From 4e66d290a6a86bd077eb31d5f2de1361793c9aca Mon Sep 17 00:00:00 2001 From: wforums Date: Fri, 15 Aug 2014 11:44:14 +0200 Subject: [PATCH] Library - step one and half Moved most of 608_helper functions to ccx_encoders_helpers, as they seem more logical. No idea yet where the last one has to go (used in both encoder/decoder 608 right now) --- src/ccextractor.c | 9 +- src/ccextractor.h | 6 - src/ccx_decoders_608.c | 4 - src/ccx_decoders_608.h | 4 +- src/ccx_encoders_common.c | 50 ++++++++ src/ccx_encoders_common.h | 8 +- src/ccx_encoders_helpers.c | 247 ++++++++++++++++++++++++++----------- src/ccx_encoders_helpers.h | 25 +++- src/params.c | 92 +------------- src/utility.c | 40 ------ src/utility.h | 6 +- 11 files changed, 257 insertions(+), 234 deletions(-) diff --git a/src/ccextractor.c b/src/ccextractor.c index 11b2f73e..09b75e2d 100644 --- a/src/ccextractor.c +++ b/src/ccextractor.c @@ -174,13 +174,6 @@ int current_file=-1; // If current_file!=1, we are processing *inputfile[current int num_input_files=0; // How many? -// Case arrays -char **spell_lower=NULL; -char **spell_correct=NULL; -int spell_words=0; -int spell_capacity=0; - - /* Hauppauge support */ unsigned hauppauge_warning_shown=0; // Did we detect a possible Hauppauge capture and told the user already? unsigned teletext_warning_shown=0; // Did we detect a possible PAL (with teletext subs) and told the user already? @@ -921,6 +914,8 @@ void init_libraries(){ // Init shared decoder settings ccx_decoders_common_settings_init(subs_delay, ccx_options.write_format); + // Init encoder helper variables + ccx_encoders_helpers_setup(ccx_options.encoding, ccx_options.nofontcolor, ccx_options.notypesetting, ccx_options.trim_subs); // Prepare 608 context context_cc608_field_1 = ccx_decoder_608_init_library( diff --git a/src/ccextractor.h b/src/ccextractor.h index 23c8a3b8..75e65065 100644 --- a/src/ccextractor.h +++ b/src/ccextractor.h @@ -375,7 +375,6 @@ extern LLONG subs_delay; extern int startcredits_displayed, end_credits_displayed; extern LLONG last_displayed_subs_ms; extern int processed_enough; -extern unsigned char usercolor_rgb[8]; extern const char *extension; extern long FILEBUFFERSIZE; // Uppercase because it used to be a define @@ -418,11 +417,6 @@ extern int num_input_files; extern char *basefilename; extern struct ccx_s_write wbout1, wbout2, *wbxdsout; -extern char **spell_lower; -extern char **spell_correct; -extern int spell_words; -extern int spell_capacity; - extern int cc608_parity_table[256]; // From myth // From ts_functions diff --git a/src/ccx_decoders_608.c b/src/ccx_decoders_608.c index 7ce2b92d..10d0ff07 100644 --- a/src/ccx_decoders_608.c +++ b/src/ccx_decoders_608.c @@ -46,10 +46,6 @@ const unsigned char pac2_attribs[][3] = // Color, font, ident unsigned char *subline; // Temp storage for .srt lines int new_sentence=1; // Capitalize next letter? -// userdefined rgb color -unsigned char usercolor_rgb[8]=""; - - static const char *command_type[] = { "Unknown", diff --git a/src/ccx_decoders_608.h b/src/ccx_decoders_608.h index 880f7645..0b6d3c36 100644 --- a/src/ccx_decoders_608.h +++ b/src/ccx_decoders_608.h @@ -1,8 +1,8 @@ -#ifndef __608_H__ - #include "ccx_decoders_common.h" #include "ccx_decoders_xds.h" +#ifndef __608_H__ + extern LLONG ts_start_of_xds; /* diff --git a/src/ccx_encoders_common.c b/src/ccx_encoders_common.c index d399aebd..47d11f9b 100644 --- a/src/ccx_encoders_common.c +++ b/src/ccx_encoders_common.c @@ -5,6 +5,7 @@ #include "608_spupng.h" #include "utility.h" #include "ocr.h" +#include "ccx_decoders_608.h" #include "ccx_decoders_xds.h" // These are the default settings for plain transcripts. No times, no CC or caption mode, and no XDS. @@ -606,3 +607,52 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub) freep(&sub->data); return wrote_something; } + +void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *context) +{ + unsigned h1, m1, s1, ms1; + unsigned h2, m2, s2, ms2; + LLONG ms_start; + int with_data = 0; + + for (int i = 0; i<15; i++) + { + if (data->row_used[i]) + with_data = 1; + } + if (!with_data) + return; + + ms_start = data->start_time; + + ms_start += subs_delay; + if (ms_start<0) // Drop screens that because of subs_delay start too early + return; + int time_reported = 0; + for (int i = 0; i<15; i++) + { + if (data->row_used[i]) + { + fprintf(stderr, "###SUBTITLE#"); + if (!time_reported) + { + LLONG ms_end = data->end_time; + mstotime(ms_start, &h1, &m1, &s1, &ms1); + mstotime(ms_end - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line. + // Note, only MM:SS here as we need to save space in the preview window + fprintf(stderr, "%02u:%02u#%02u:%02u#", + h1 * 60 + m1, s1, h2 * 60 + m2, s2); + time_reported = 1; + } + else + fprintf(stderr, "##"); + + // We don't capitalize here because whatever function that was used + // before to write to file already took care of it. + int length = get_decoder_line_encoded_for_gui(subline, i, data); + fwrite(subline, 1, length, stderr); + fwrite("\n", 1, 1, stderr); + } + } + fflush(stderr); +} diff --git a/src/ccx_encoders_common.h b/src/ccx_encoders_common.h index 21744702..a0e2faaf 100644 --- a/src/ccx_encoders_common.h +++ b/src/ccx_encoders_common.h @@ -19,15 +19,15 @@ extern ccx_encoders_transcript_format ccx_encoders_default_transcript_settings; */ struct encoder_ctx { - /** common buffer used by all encoder */ + /* common buffer used by all encoder */ unsigned char *buffer; - /** capacity of buffer */ + /* capacity of buffer */ unsigned int capacity; /* keep count of srt subtitle*/ unsigned int srt_counter; - /** output contet */ + /* output context */ struct ccx_s_write *out; - /** start time of previous sub */ + /* start time of previous sub */ LLONG prev_start; }; diff --git a/src/ccx_encoders_helpers.c b/src/ccx_encoders_helpers.c index 6d71662d..526c3cbd 100644 --- a/src/ccx_encoders_helpers.c +++ b/src/ccx_encoders_helpers.c @@ -1,31 +1,39 @@ #include "ccx_encoders_helpers.h" -// Encodes a generic string. Note that since we use the encoders for closed caption -// data, text would have to be encoded as CCs... so using special characters here -// it's a bad idea. -unsigned encode_line(unsigned char *buffer, unsigned char *text) +#ifdef _MSC_VER +#define strcasecmp stricmp +#endif + +// userdefined rgb color +unsigned char usercolor_rgb[8] = ""; + +static int spell_builtin_added = 0; // so we don't do it twice +// Case arrays +char **spell_lower = NULL; +char **spell_correct = NULL; +int spell_words = 0; +int spell_capacity = 0; + +// Some basic English words, so user-defined doesn't have to +// include the common stuff +static const char *spell_builtin[] = { - unsigned bytes = 0; - while (*text) - { - switch (ccx_options.encoding) - { - case CCX_ENC_UTF_8: - case CCX_ENC_LATIN_1: - *buffer = *text; - bytes++; - buffer++; - break; - case CCX_ENC_UNICODE: - *buffer = *text; - *(buffer + 1) = 0; - bytes += 2; - buffer += 2; - break; - } - text++; - } - return bytes; + "I", "I'd", "I've", "I'd", "I'll", + "January", "February", "March", "April", // May skipped intentionally + "June", "July", "August", "September", "October", "November", + "December", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday", "Sunday", "Halloween", "United States", + "Spain", "France", "Italy", "England", + NULL +}; + +int string_cmp2(const void *p1, const void *p2, void *arg) +{ + return strcasecmp(*(char**)p1, *(char**)p2); +} +int string_cmp(const void *p1, const void *p2) +{ + return string_cmp2(p1, p2, NULL); } void correct_case(int line_num, struct eia608_screen *data) @@ -99,6 +107,34 @@ void find_limit_characters(unsigned char *line, int *first_non_blank, int *last_ } } +// Encodes a generic string. Note that since we use the encoders for closed caption +// data, text would have to be encoded as CCs... so using special characters here +// it's a bad idea. +unsigned encode_line(unsigned char *buffer, unsigned char *text) +{ + unsigned bytes = 0; + while (*text) + { + switch (ccx_encoders_helpers_settings.encoding) + { + case CCX_ENC_UTF_8: + case CCX_ENC_LATIN_1: + *buffer = *text; + bytes++; + buffer++; + break; + case CCX_ENC_UNICODE: + *buffer = *text; + *(buffer + 1) = 0; + bytes += 2; + buffer += 2; + break; + } + text++; + } + return bytes; +} + unsigned get_decoder_line_encoded_for_gui(unsigned char *buffer, int line_num, struct eia608_screen *data) { unsigned char *line = data->characters[line_num]; @@ -140,7 +176,7 @@ unsigned char *close_tag(unsigned char *buffer, char *tagstack, char tagtype, in return buffer; } if (tagtype != 'A') // All - fatal(CCX_COMMON_EXIT_BUG_BUG, "Mismatched tags in encoding, this is a bug, please report"); + ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "Mismatched tags in encoding, this is a bug, please report"); return buffer; } @@ -155,13 +191,13 @@ unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct ei unsigned char *line = data->characters[line_num]; unsigned char *orig = buffer; // Keep for debugging int first = 0, last = 31; - if (ccx_options.trim_subs) + if (ccx_encoders_helpers_settings.trim_subs) find_limit_characters(line, &first, &last); for (int i = first; i <= last; i++) { // Handle color int its_col = data->colors[line_num][i]; - if (its_col != col && !ccx_options.nofontcolor && + if (its_col != col && !ccx_encoders_helpers_settings.no_font_color && !(col == COL_USERDEFINED && its_col == COL_WHITE)) // Don't replace user defined with white { if (changed_font) @@ -184,30 +220,30 @@ unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct ei } // Handle underlined int is_underlined = data->fonts[line_num][i] & FONT_UNDERLINED; - if (is_underlined && underlined == 0 && !ccx_options.notypesetting) // Open underline + if (is_underlined && underlined == 0 && !ccx_encoders_helpers_settings.no_type_setting) // Open underline { buffer += encode_line(buffer, (unsigned char *) ""); strcat(tagstack, "U"); underlined++; } - if (is_underlined == 0 && underlined && !ccx_options.notypesetting) // Close underline + if (is_underlined == 0 && underlined && !ccx_encoders_helpers_settings.no_type_setting) // Close underline { buffer = close_tag(buffer, tagstack, 'U', &underlined, &italics, &changed_font); } // Handle italics int has_ita = data->fonts[line_num][i] & FONT_ITALICS; - if (has_ita && italics == 0 && !ccx_options.notypesetting) // Open italics + if (has_ita && italics == 0 && !ccx_encoders_helpers_settings.no_type_setting) // Open italics { buffer += encode_line(buffer, (unsigned char *) ""); strcat(tagstack, "I"); italics++; } - if (has_ita == 0 && italics && !ccx_options.notypesetting) // Close italics + if (has_ita == 0 && italics && !ccx_encoders_helpers_settings.no_type_setting) // Close italics { buffer = close_tag(buffer, tagstack, 'I', &underlined, &italics, &changed_font); } int bytes = 0; - switch (ccx_options.encoding) + switch (ccx_encoders_helpers_settings.encoding) { case CCX_ENC_UTF_8: bytes = get_char_in_utf_8(buffer, line[i]); @@ -225,12 +261,11 @@ unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct ei } buffer = close_tag(buffer, tagstack, 'A', &underlined, &italics, &changed_font); if (underlined || italics || changed_font) - fatal(CCX_COMMON_EXIT_BUG_BUG, "Not all tags closed in encoding, this is a bug, please report.\n"); + ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "Not all tags closed in encoding, this is a bug, please report.\n"); *buffer = 0; return (unsigned)(buffer - orig); // Return length } - /*void delete_all_lines_but_current(ccx_decoder_608_context *context, struct eia608_screen *data, int row) { for (int i=0;i<15;i++) @@ -254,51 +289,115 @@ used=encode_line (ctx->buffer,(unsigned char *) string); fwrite (ctx->buffer,used,1,fh); }*/ -void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *context) +int add_word(const char *word) { - unsigned h1, m1, s1, ms1; - unsigned h2, m2, s2, ms2; - LLONG ms_start; - int with_data = 0; - - for (int i = 0; i<15; i++) + char *new_lower; + char *new_correct; + char **ptr_lower; + char **ptr_correct; + int i; + if (spell_words == spell_capacity) { - if (data->row_used[i]) - with_data = 1; + // Time to grow + spell_capacity += 50; + ptr_lower = (char **)realloc(spell_lower, sizeof (char *)* + spell_capacity); + ptr_correct = (char **)realloc(spell_correct, sizeof (char *)* + spell_capacity); } - if (!with_data) - return; - - ms_start = data->start_time; - - ms_start += subs_delay; - if (ms_start<0) // Drop screens that because of subs_delay start too early - return; - int time_reported = 0; - for (int i = 0; i<15; i++) + size_t len = strlen(word); + new_lower = (char *)malloc(len + 1); + new_correct = (char *)malloc(len + 1); + if (ptr_lower == NULL || ptr_correct == NULL || + new_lower == NULL || new_correct == NULL) { - if (data->row_used[i]) + spell_capacity = 0; + for (i = 0; i < spell_words; i++) { - fprintf(stderr, "###SUBTITLE#"); - if (!time_reported) - { - LLONG ms_end = data->end_time; - mstotime(ms_start, &h1, &m1, &s1, &ms1); - mstotime(ms_end - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line. - // Note, only MM:SS here as we need to save space in the preview window - fprintf(stderr, "%02u:%02u#%02u:%02u#", - h1 * 60 + m1, s1, h2 * 60 + m2, s2); - time_reported = 1; - } - else - fprintf(stderr, "##"); + freep(&spell_lower[spell_words]); + freep(&spell_correct[spell_words]); + } + freep(&spell_lower); + freep(&spell_correct); + freep(&ptr_lower); + freep(&ptr_correct); + freep(&new_lower); + freep(&new_correct); + spell_words = 0; + return -1; + } + else + { + spell_lower = ptr_lower; + spell_correct = ptr_correct; + } + strcpy(new_correct, word); + for (size_t i = 0; i 0; gap = gap / 2) + { + int p, j; + for (p = gap; p < nb; p++) + { + memcpy(tmp, lbase + (p *size), size); + for (j = p; j >= gap && (compar(tmp, lbase + ((j - gap) * size), arg) < 0); j -= gap) + { + memcpy(lbase + (j*size), lbase + ((j - gap) * size), size); + } + memcpy(lbase + (j *size), tmp, size); } } - fflush(stderr); + free(tmp); +} + +void ccx_encoders_helpers_perform_shellsort_words(){ + shell_sort(spell_lower, spell_words, sizeof(*spell_lower), string_cmp2, NULL); + shell_sort(spell_correct, spell_words, sizeof(*spell_correct), string_cmp2, NULL); +} + +void ccx_encoders_helpers_setup(enum ccx_encoding_type encoding,int no_font_color,int no_type_setting,int trim_subs){ + ccx_encoders_helpers_settings.encoding = encoding; + ccx_encoders_helpers_settings.no_font_color = no_font_color; + ccx_encoders_helpers_settings.no_type_setting = no_type_setting; + ccx_encoders_helpers_settings.trim_subs = trim_subs; } diff --git a/src/ccx_encoders_helpers.h b/src/ccx_encoders_helpers.h index 57a2e00a..0920e210 100644 --- a/src/ccx_encoders_helpers.h +++ b/src/ccx_encoders_helpers.h @@ -1,10 +1,24 @@ #ifndef _CCX_ENCODERS_HELPERS_H #define _CCX_ENCODERS_HELPERS_H -#include "ccx_common_constants.h" +#include "ccx_common_common.h" #include "ccx_decoders_structs.h" #include "ccx_decoders_608.h" +extern char **spell_lower; +extern char **spell_correct; +extern int spell_words; +extern int spell_capacity; + +extern unsigned char usercolor_rgb[8]; + +struct ccx_encoders_helpers_settings_t { + int trim_subs; + int no_font_color; + int no_type_setting; + enum ccx_encoding_type encoding; +} ccx_encoders_helpers_settings; + // Helper functions void correct_case(int line_num, struct eia608_screen *data); void capitalize(int line_num, struct eia608_screen *data); @@ -12,4 +26,13 @@ void find_limit_characters(unsigned char *line, int *first_non_blank, int *last_ unsigned get_decoder_line_encoded_for_gui(unsigned char *buffer, int line_num, struct eia608_screen *data); unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct eia608_screen *data); +int string_cmp(const void *p1, const void *p2); +int string_cmp2(const void *p1, const void *p2, void *arg); +int add_built_in_words(); +int add_word(const char *word); + +void shell_sort(void *base, int nb, size_t size, int(*compar)(const void*p1, const void *p2, void*arg), void *arg); + +void ccx_encoders_helpers_perform_shellsort_words(); +void ccx_encoders_helpers_setup(enum ccx_encoding_type encoding, int no_font_color, int no_type_setting, int trim_subs); #endif \ No newline at end of file diff --git a/src/params.c b/src/params.c index 2d977e69..2da0558a 100644 --- a/src/params.c +++ b/src/params.c @@ -2,7 +2,6 @@ #include "utility.h" static int inputfile_capacity=0; -static int spell_builtin_added=0; // so we don't do it twice static const char *DEF_VAL_STARTCREDITSNOTBEFORE="0"; static const char *DEF_VAL_STARTCREDITSNOTAFTER="5:00"; // To catch the theme after the teaser in TV shows @@ -11,19 +10,6 @@ static const char *DEF_VAL_STARTCREDITSFORATMOST="5"; static const char *DEF_VAL_ENDCREDITSFORATLEAST="2"; static const char *DEF_VAL_ENDCREDITSFORATMOST="5"; -// Some basic English words, so user-defined doesn't have to -// include the common stuff -static const char *spell_builtin[]= -{ - "I", "I'd", "I've", "I'd", "I'll", - "January","February","March","April", // May skipped intentionally - "June","July","August","September","October","November", - "December","Monday","Tuesday","Wednesday","Thursday", - "Friday","Saturday","Sunday","Halloween","United States", - "Spain","France","Italy","England", - NULL -}; - int stringztoms (const char *s, struct ccx_boundary_time *bt) { unsigned ss=0, mm=0, hh=0; @@ -69,81 +55,6 @@ int stringztoms (const char *s, struct ccx_boundary_time *bt) return 0; } - -int add_word (const char *word) -{ - char *new_lower; - char *new_correct; - char **ptr_lower; - char **ptr_correct; - int i; - if (spell_words==spell_capacity) - { - // Time to grow - spell_capacity+=50; - ptr_lower=(char **) realloc (spell_lower, sizeof (char *) * - spell_capacity); - ptr_correct=(char **) realloc (spell_correct, sizeof (char *) * - spell_capacity); - } - size_t len=strlen (word); - new_lower = (char *) malloc (len+1); - new_correct = (char *) malloc (len+1); - if (ptr_lower==NULL || ptr_correct==NULL || - new_lower==NULL || new_correct==NULL) - { - spell_capacity = 0; - for ( i = 0; i < spell_words ; i++) - { - freep(&spell_lower[spell_words]); - freep(&spell_correct[spell_words]); - } - freep(&spell_lower); - freep(&spell_correct); - freep(&ptr_lower); - freep(&ptr_correct); - freep(&new_lower); - freep(&new_correct); - spell_words = 0; - return -1; - } - else - { - spell_lower = ptr_lower; - spell_correct = ptr_correct; - } - strcpy (new_correct, word); - for (size_t i=0; isentence_cap_file && process_cap_file (option->sentence_cap_file)) fatal (EXIT_ERROR_IN_CAPITALIZATION_FILE, "There was an error processing the capitalization file.\n"); - shell_sort(spell_lower,spell_words,sizeof(*spell_lower),string_cmp2,NULL); - shell_sort(spell_correct,spell_words,sizeof(*spell_correct),string_cmp2,NULL); + ccx_encoders_helpers_perform_shellsort_words(); } if(option->ts_forced_program != -1) option->ts_forced_program_selected = 1; diff --git a/src/utility.c b/src/utility.c index 91a51882..e5934d56 100644 --- a/src/utility.c +++ b/src/utility.c @@ -1,9 +1,5 @@ #include "ccextractor.h" -#ifdef _MSC_VER -#define strcasecmp stricmp -#endif - static char *text; static int text_size=0; @@ -248,39 +244,3 @@ int hex2int (char high, char low) return -1; return h*16+l; } -/** - * @param base points to the start of the array - * @param nb number of element in array - * @param size size of each element - * @param compar Comparison function, which is called with three argument - * that point to the objects being compared and arg. - * @param arg argument passed as it is to compare function - */ -void shell_sort(void *base, int nb,size_t size,int (*compar)(const void*p1,const void *p2,void*arg),void *arg) -{ - unsigned char *lbase = (unsigned char*)base; - unsigned char *tmp = (unsigned char*)malloc(size); - for (int gap = nb / 2; gap > 0; gap = gap / 2) - { - int p, j; - for (p = gap; p < nb; p++) - { - memcpy(tmp, lbase + (p *size), size); - for (j = p; j >= gap && ( compar(tmp,lbase + ( (j - gap) * size),arg) < 0); j -= gap) - { - memcpy(lbase + (j*size),lbase + ( (j - gap) * size),size); - } - memcpy(lbase + (j *size),tmp, size); - } - } - free(tmp); -} - -int string_cmp2(const void *p1,const void *p2,void *arg) -{ - return strcasecmp(*(char**)p1,*(char**)p2); -} -int string_cmp(const void *p1,const void *p2) -{ - return string_cmp2(p1, p2, NULL); -} \ No newline at end of file diff --git a/src/utility.h b/src/utility.h index 9d32ee1d..aa4bc8ef 100644 --- a/src/utility.h +++ b/src/utility.h @@ -10,8 +10,4 @@ #define RL16(x) (*(unsigned short int*)(x)) #define RB16(x) (ntohs(*(unsigned short int*)(x))) -void shell_sort(void *base, int nb,size_t size,int (*compar)(const void*p1,const void *p2,void*arg),void *arg); -int string_cmp(const void *p1,const void *p2); -int string_cmp2(const void *p1,const void *p2,void *arg); - -#endif +#endif \ No newline at end of file