diff options
Diffstat (limited to 'src/odr-padenc.cpp')
-rw-r--r-- | src/odr-padenc.cpp | 163 |
1 files changed, 138 insertions, 25 deletions
diff --git a/src/odr-padenc.cpp b/src/odr-padenc.cpp index 93aaeb6..1f15143 100644 --- a/src/odr-padenc.cpp +++ b/src/odr-padenc.cpp @@ -221,7 +221,8 @@ int encodeFile(int output_fd, const std::string& fname, int fidx, bool raw_slide uint8_vector_t createMotHeader( size_t blobsize, int fidx, - bool jfif_not_png); + bool jfif_not_png, + const std::string ¶ms_fname); void createMscDG(MSCDG* msc, unsigned short int dgtype, int *cindex, unsigned short int segnum, unsigned short int lastseg, unsigned short int tid, unsigned char* data, @@ -297,6 +298,8 @@ struct DATA_GROUP { static int cindex_header = 0; static int cindex_body = 0; +const std::string SLS_PARAMS_SUFFIX = ".sls_params"; + class MOTHeader { private: @@ -730,6 +733,20 @@ pad_t* PADPacketizer::FlushPAD() { static PADPacketizer *pad_packetizer; +std::vector<std::string> split_string(const std::string &s, const char delimiter) { + std::vector<std::string> result; + std::stringstream ss(s); + std::string part; + + while (std::getline(ss, part, delimiter)) + result.push_back(part); + return result; +} + + + + + @@ -956,18 +973,28 @@ int main(int argc, char *argv[]) // Add new slides to transmit to list while ((pDirent = readdir(pDir)) != NULL) { - if (pDirent->d_name[0] != '.') { - char imagepath[256]; - sprintf(imagepath, "%s/%s", sls_dir, pDirent->d_name); + std::string slide = pDirent->d_name; - slide_metadata_t md; - md.filepath = imagepath; - md.fidx = slides_history.get_fidx(imagepath); - slides_to_transmit.push_back(md); + // skip dirs beginning with '.' + if(slide[0] == '.') + continue; - if (verbose) { - fprintf(stderr, "ODR-PadEnc found slide '%s', fidx %d\n", imagepath, md.fidx); - } + // skip slide params files + if(slide.length() >= SLS_PARAMS_SUFFIX.length() && + slide.compare(slide.length() - SLS_PARAMS_SUFFIX.length(), SLS_PARAMS_SUFFIX.length(), SLS_PARAMS_SUFFIX) == 0) + continue; + + // add slide + char imagepath[256]; + sprintf(imagepath, "%s/%s", sls_dir, slide.c_str()); + + slide_metadata_t md; + md.filepath = imagepath; + md.fidx = slides_history.get_fidx(imagepath); + slides_to_transmit.push_back(md); + + if (verbose) { + fprintf(stderr, "ODR-PadEnc found slide '%s', fidx %d\n", imagepath, md.fidx); } } @@ -1323,7 +1350,7 @@ int encodeFile(int output_fd, const std::string& fname, int fidx, bool raw_slide nseg++; } - uint8_vector_t mothdr = createMotHeader(blobsize, fidx, jfif_not_png); + uint8_vector_t mothdr = createMotHeader(blobsize, fidx, jfif_not_png, fname + SLS_PARAMS_SUFFIX); // Create the MSC Data Group C-Structure createMscDG(&msc, 3, &cindex_header, 0, 1, fidx, &mothdr[0], mothdr.size()); // Generate the MSC DG frame (Figure 9 en 300 401) @@ -1371,14 +1398,104 @@ encodefile_out: } -uint8_vector_t createMotHeader(size_t blobsize, int fidx, bool jfif_not_png) +bool parse_sls_param_id(const std::string &key, const std::string &value, uint8_t &target) { + int value_int = atoi(value.c_str()); + if (value_int >= 0x00 && value_int <= 0xFF) { + target = value_int; + return true; + } + fprintf(stderr, "ODR-PadEnc Warning: SLS parameter '%s' %d out of range - ignored\n", key.c_str(), value_int); + return false; +} + + +bool check_sls_param_len(const std::string &key, size_t len, size_t len_max) { + if (len <= len_max) + return true; + fprintf(stderr, "ODR-PadEnc Warning: SLS parameter '%s' exceeds its maximum length (%zu > %zu) - ignored\n", key.c_str(), len, len_max); + return false; +} + + +void process_mot_params_file(MOTHeader& header, const std::string ¶ms_fname) { + std::ifstream params_fstream(params_fname); + if (!params_fstream.is_open()) + return; + + std::string line; + while (std::getline(params_fstream, line)) { + // ignore empty lines and comments + if (line.empty() || line[0] == '#') + continue; + + // parse key/value pair + size_t separator_pos = line.find('='); + if (separator_pos == std::string::npos) { + fprintf(stderr, "ODR-PadEnc Warning: SLS parameter line '%s' without separator - ignored\n", line.c_str()); + continue; + } + std::string key = line.substr(0, separator_pos); + std::string value = line.substr(separator_pos + 1); +#if DEBUG + fprintf(stderr, "process_mot_params_file: key: '%s', value: '%s'\n", key.c_str(), value.c_str()); +#endif + + if (key == "CategoryID/SlideID") { + // split value + std::vector<std::string> params = split_string(value, ' '); + if (params.size() != 2) { + fprintf(stderr, "ODR-PadEnc Warning: SLS parameter CategoryID/SlideID value '%s' does not have two parts - ignored\n", value.c_str()); + continue; + } + + uint8_t id_param[2]; + if (parse_sls_param_id("CategoryID", params[0], id_param[0]) & + parse_sls_param_id("SlideID", params[1], id_param[1])) { + header.AddExtensionVarSize(0x25, id_param, sizeof(id_param)); + if (verbose) + fprintf(stderr, "ODR-PadEnc SLS parameter: CategoryID = %d / SlideID = %d\n", id_param[0], id_param[1]); + } + continue; + } + if (key == "CategoryTitle") { + if(!check_sls_param_len("CategoryTitle", value.length(), 128)) + continue; + + header.AddExtensionVarSize(0x26, (uint8_t*) value.c_str(), value.length()); + if (verbose) + fprintf(stderr, "ODR-PadEnc SLS parameter: CategoryTitle = '%s'\n", value.c_str()); + continue; + } + if (key == "ClickThroughURL") { + if(!check_sls_param_len("ClickThroughURL", value.length(), 512)) + continue; + + header.AddExtensionVarSize(0x27, (uint8_t*) value.c_str(), value.length()); + if (verbose) + fprintf(stderr, "ODR-PadEnc SLS parameter: ClickThroughURL = '%s'\n", value.c_str()); + continue; + } + if (key == "AlternativeLocationURL") { + if(!check_sls_param_len("AlternativeLocationURL", value.length(), 512)) + continue; + + header.AddExtensionVarSize(0x28, (uint8_t*) value.c_str(), value.length()); + if (verbose) + fprintf(stderr, "ODR-PadEnc SLS parameter: AlternativeLocationURL = '%s'\n", value.c_str()); + continue; + } + + fprintf(stderr, "ODR-PadEnc Warning: SLS parameter '%s' unknown - ignored\n", key.c_str()); + } +} + + +uint8_vector_t createMotHeader(size_t blobsize, int fidx, bool jfif_not_png, const std::string ¶ms_fname) { // prepare ContentName uint8_t cntemp[10]; // = 1 + 8 + 1 = charset + name + terminator cntemp[0] = 0x0 << 4; // charset: 0 (Complete EBU Latin based) - doesn't really matter here snprintf((char*) (cntemp + 1), sizeof(cntemp) - 1, "%04d.%s", fidx, jfif_not_png ? "jpg" : "png"); - if (verbose) - fprintf(stderr, "ODR-PadEnc writing image as '%s'\n", cntemp + 1); // MOT header - content type: image, content subtype: JFIF / PNG MOTHeader header(blobsize, 0x02, jfif_not_png ? 0x001 : 0x003); @@ -1389,6 +1506,12 @@ uint8_vector_t createMotHeader(size_t blobsize, int fidx, bool jfif_not_png) // ContentName: XXXX.jpg / XXXX.png header.AddExtensionVarSize(0x0C, cntemp, sizeof(cntemp) - 1); // omit terminator + // process params file if present + process_mot_params_file(header, params_fname); + + if (verbose) + fprintf(stderr, "ODR-PadEnc writing image as '%s'\n", cntemp + 1); + return header.GetData(); } @@ -1509,16 +1632,6 @@ DATA_GROUP* createDynamicLabelPlus(const DL_STATE& dl_state) { } -std::vector<std::string> split_string(const std::string &s, const char delimiter) { - std::vector<std::string> result; - std::stringstream ss(s); - std::string part; - - while (std::getline(ss, part, delimiter)) - result.push_back(part); - return result; -} - bool parse_dl_param_bool(const std::string &key, const std::string &value, bool &target) { if (value == "0") { target = 0; |