Skip to content

Commit

Permalink
[IMPROVEMENT] Implement subtitle modifications for each encoder (#1214)
Browse files Browse the repository at this point in the history
* Implement subtitle modification for all 608 encoders

This is done by modifying the subtitles in `ccx_encoders_common.c`
rather than per encoder.

* Use `char *` instead of subtitle data to capitalize

* Implement subtitle modification for OCR encoders

* Remove signness warnings

* Remove two-word profanity

They do not work for the moment

* Deal with different encoding

* Mention in changelog
  • Loading branch information
NilsIrl authored and cfsmp3 committed Jan 24, 2020
1 parent 7b038ab commit 8db3398
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 52 deletions.
1 change: 1 addition & 0 deletions docs/CHANGES.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- New: Added more fatals on no arguments errors.
- New: Updated ccextractor.cnf.sample.
- New: Add support for censoring words ("Kid Friendly") (#1139)
- New: Extend support of capitalization for all BITMAP and 608 subtitles (#1214)
- Fix: ccx_demuxer_mxf.c: Parse framerate from MXF captions to fix caption timings.
- Fix: hardsubx_decoder.c: Fix memory leaks using Leptonica API.
- Fix: linux/Makefile.am: added some sources to enable rpms to be created.
Expand Down
27 changes: 23 additions & 4 deletions src/lib_ccx/ccx_encoders_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,6 @@ void write_cc_line_as_simplexml(struct eia608_screen *data, struct encoder_ctx *
char *cap = "<caption>";
char *cap1 = "</caption>";

correct_spelling_and_censor_words_608(context, line_number, data);

length = get_str_basic(context->subline, data->characters[line_number],
context->trim_subs, CCX_ENC_ASCII, context->encoding, CCX_DECODER_608_SCREEN_WIDTH);

Expand Down Expand Up @@ -1155,6 +1153,9 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
data->end_time += utc_refvalue * 1000;
}

for (int i = 0; i < CCX_DECODER_608_SCREEN_ROWS; ++i)
correct_spelling_and_censor_words(context, (char *) data->characters[i], CCX_DECODER_608_SCREEN_WIDTH);

#ifdef PYTHON_API
pass_cc_buffer_to_python(data, context);
#else
Expand Down Expand Up @@ -1228,7 +1229,26 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
}
freep(&sub->data);
break;
case CC_BITMAP:
case CC_BITMAP:;

#ifdef ENABLE_OCR
struct cc_bitmap *rect;
int i;
for (i = 0, rect = sub->data; i < sub->nb_data; ++i, ++rect)
{
if (rect->ocr_text)
{
int len = strlen(rect->ocr_text);
correct_spelling_and_censor_words(context, rect->ocr_text, len);
for (int i = 0; i < len; ++i)
{
if ((unsigned char)rect->ocr_text[i] == 0x98) // asterisk in 608 encoding
rect->ocr_text[i] = '*';
}
}
}
#endif

switch (context->write_format)
{
case CCX_OF_CCD:
Expand Down Expand Up @@ -1281,7 +1301,6 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
default:
break;
}

break;
case CC_RAW:
if (context->send_to_srv)
Expand Down
44 changes: 17 additions & 27 deletions src/lib_ccx/ccx_encoders_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const char *profane_builtin[] =
"goddamn",
"godsdamn",
"hell",
"holy shit",
"holy",
"horseshit",
"motherfucker",
"nigga",
Expand All @@ -84,17 +84,17 @@ int string_cmp(const void *p1, const void *p2)
return string_cmp_function(p1, p2, NULL);
}

void capitalize_word(size_t index, unsigned char *word)
void capitalize_word(size_t index, char *word)
{
memcpy(word, capitalization_list.words[index], strlen(capitalization_list.words[index]));
}

void censor_word(size_t index, unsigned char *word)
void censor_word(size_t index, char *word)
{
memset(word, 0x98, strlen(profane.words[index])); // 0x98 is the asterisk in EIA-608
}

void call_function_if_match(int line_num, struct eia608_screen *data, struct word_list *list, void (*modification)(size_t, unsigned char *))
void call_function_if_match(char *line, struct word_list *list, void (*modification)(size_t, char *))
{
char delim[64] = {
' ', '\n', '\r', 0x89, 0x99,
Expand All @@ -105,8 +105,8 @@ void call_function_if_match(int line_num, struct eia608_screen *data, struct wor
'.', '/', ':', '^', '_',
'{', '|', '}', '~', '\0' };

char *line = strdup(data->characters[line_num]);
char *c = strtok(line, delim);
char *line_token = strdup(line);
char *c = strtok(line_token, delim);

if (c != NULL)
{
Expand All @@ -116,21 +116,11 @@ void call_function_if_match(int line_num, struct eia608_screen *data, struct wor

if (index)
{
modification(index - list->words, data->characters[line_num] + (c - line));
modification(index - list->words, line + (c - line_token));
}
} while ((c = strtok(NULL, delim)) != NULL);
}
free(line);
}

void correct_case_with_dictionary(int line_num, struct eia608_screen *data)
{
call_function_if_match(line_num, data, &capitalization_list, capitalize_word);
}

void censor_word_with_dictionary(int line_num, struct eia608_screen *data)
{
call_function_if_match(line_num, data, &profane, censor_word);
free(line_token);
}

void telx_correct_case(char *sub_line)
Expand Down Expand Up @@ -180,17 +170,17 @@ int is_all_caps(struct encoder_ctx *context, int line_num, struct eia608_screen
return (saw_upper && !saw_lower); // 1 if we've seen upper and not lower, 0 otherwise
}

int clever_capitalize(struct encoder_ctx *context, int line_num, struct eia608_screen *data)
int clever_capitalize(struct encoder_ctx *context, char *line, unsigned int length)
{
// CFS: Tried doing to clever (see below) but some channels do all uppercase except for
// notes for deaf people (such as "(narrator)" which messes things up.
// First find out if we actually need to do it, don't mess with lines that come OK
//int doit = is_all_caps(context, line_num, data);
int doit = 1;

for (int i = 0; i < CCX_DECODER_608_SCREEN_WIDTH; i++)
for (int i = 0; i < length; i++)
{
switch (data->characters[line_num][i])
switch (line[i])
{
case ' ':
case 0x89: // This is a transparent space
Expand All @@ -206,9 +196,9 @@ int clever_capitalize(struct encoder_ctx *context, int line_num, struct eia608_s
if (doit)
{
if (context->new_sentence)
data->characters[line_num][i] = cctoupper(data->characters[line_num][i]);
line[i] = cctoupper(line[i]);
else
data->characters[line_num][i] = cctolower(data->characters[line_num][i]);
line[i] = cctolower(line[i]);
}
context->new_sentence = 0;
break;
Expand Down Expand Up @@ -455,17 +445,17 @@ int add_builtin_words(const char *builtin[], struct word_list *list)
return 0;
}

void correct_spelling_and_censor_words_608(struct encoder_ctx *context, int line_number, struct eia608_screen *data)
void correct_spelling_and_censor_words(struct encoder_ctx *context, char *line, unsigned int length)
{
if (context->sentence_cap)
{
if (clever_capitalize(context, line_number, data))
correct_case_with_dictionary(line_number, data);
if (clever_capitalize(context, line, length))
call_function_if_match(line, &capitalization_list, capitalize_word);
}

if (context->filter_profanity)
{
censor_word_with_dictionary(line_number, data);
call_function_if_match(line, &profane, censor_word);
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/lib_ccx/ccx_encoders_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ struct ccx_encoders_helpers_settings_t {
};

// Helper functions
void correct_case_with_dictionary(int line_num, struct eia608_screen *data);
int is_all_caps(struct encoder_ctx *context, int line_num, struct eia608_screen *data);
int clever_capitalize(struct encoder_ctx *context, int line_num, struct eia608_screen *data);
void telx_correct_case(char *sub_line);
unsigned get_decoder_line_encoded_for_gui(unsigned char *buffer, int line_num, struct eia608_screen *data);
unsigned get_decoder_line_encoded(struct encoder_ctx *ctx, unsigned char *buffer, int line_num, struct eia608_screen *data);
Expand All @@ -36,7 +34,7 @@ int string_cmp_function(const void *p1, const void *p2, void *arg);
int add_word(struct word_list *list, const char *word);

int add_builtin_words(const char *builtin[], struct word_list *list);
void correct_spelling_and_censor_words_608(struct encoder_ctx *context, int line_number, struct eia608_screen *data);
void correct_spelling_and_censor_words(struct encoder_ctx *context, char *line, unsigned int length);

unsigned encode_line (struct encoder_ctx *ctx, unsigned char *buffer, unsigned char *text);

Expand Down
2 changes: 0 additions & 2 deletions src/lib_ccx/ccx_encoders_smptett.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,6 @@ int write_cc_buffer_as_smptett(struct eia608_screen *data, struct encoder_ctx *c
{
if (data->row_used[row])
{
correct_spelling_and_censor_words_608(context, row, data);

float row1=0;
float col1=0;
int firstcol=-1;
Expand Down
2 changes: 1 addition & 1 deletion src/lib_ccx/ccx_encoders_splitbysentence.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ struct cc_subtitle * reformat_cc_bitmap_through_sentence_buffer(struct cc_subtit
if (sub->flags & SUB_EOD_MARKER)
context->prev_start = sub->start_time;

str = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
str = paraof_ocrtext(sub, context);

if (str)
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib_ccx/ccx_encoders_spupng.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ int write_cc_bitmap_as_spupng(struct cc_subtitle *sub, struct encoder_ctx *conte
if (!context->nospupngocr)
{
char *str;
str = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
str = paraof_ocrtext(sub, context);
if (str)
{
write_spucomment(sp, str);
Expand Down
4 changes: 1 addition & 3 deletions src/lib_ccx/ccx_encoders_srt.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
if(sub->flags & SUB_EOD_MARKER)
context->prev_start = sub->start_time;

str = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
str = paraof_ocrtext(sub, context);
if (str)
{
if(context->is_mkv == 1) {
Expand Down Expand Up @@ -210,8 +210,6 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *conte
{
if (data->row_used[i])
{
correct_spelling_and_censor_words_608(context, i, data);

if (context->autodash && context->trim_subs)
{
int first=0, last=31, center1=-1, center2=-1;
Expand Down
4 changes: 1 addition & 3 deletions src/lib_ccx/ccx_encoders_ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ int write_cc_bitmap_as_ssa(struct cc_subtitle *sub, struct encoder_ctx *context)
if(sub->flags & SUB_EOD_MARKER)
context->prev_start = sub->start_time;

str = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
str = paraof_ocrtext(sub, context);
if (str)
{
// SSA format - change "\r\n" to "\N"
Expand Down Expand Up @@ -194,8 +194,6 @@ int write_cc_buffer_as_ssa(struct eia608_screen *data, struct encoder_ctx *conte
{
if (data->row_used[i])
{
correct_spelling_and_censor_words_608(context, i, data);

if (context->autodash && context->trim_subs)
{
int first=0, last=31, center1=-1, center2=-1;
Expand Down
5 changes: 1 addition & 4 deletions src/lib_ccx/ccx_encoders_transcript.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ int write_cc_bitmap_as_transcript(struct cc_subtitle *sub, struct encoder_ctx *c
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
{
char *token = NULL;
token = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
token = paraof_ocrtext(sub, context);
if (context->transcript_settings->showStartTime)
{
char buf1[80];
Expand Down Expand Up @@ -239,9 +239,6 @@ int write_cc_subtitle_as_transcript(struct cc_subtitle *sub, struct encoder_ctx
void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number)
{
int ret = 0;

correct_spelling_and_censor_words_608(context, line_number, data);

int length = get_str_basic(context->subline, data->characters[line_number],
context->trim_subs, CCX_ENC_ASCII, context->encoding, CCX_DECODER_608_SCREEN_WIDTH);

Expand Down
2 changes: 1 addition & 1 deletion src/lib_ccx/ccx_encoders_webvtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ int write_cc_bitmap_as_webvtt(struct cc_subtitle *sub, struct encoder_ctx *conte
if (sub->flags & SUB_EOD_MARKER)
context->prev_start = sub->start_time;

str = paraof_ocrtext(sub, context->encoded_crlf, context->encoded_crlf_length);
str = paraof_ocrtext(sub, context);
if (str)
{
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
Expand Down
4 changes: 2 additions & 2 deletions src/lib_ccx/ocr.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ void add_ocrtext2str(char *dest, char *src, const unsigned char *crlf, unsigned
* for all text detected from rectangles
*/

char *paraof_ocrtext(struct cc_subtitle *sub, const unsigned char *crlf, unsigned crlf_length)
char *paraof_ocrtext(struct cc_subtitle *sub, struct encoder_ctx *context)
{
int i;
int len = 0;
Expand All @@ -1002,7 +1002,7 @@ char *paraof_ocrtext(struct cc_subtitle *sub, const unsigned char *crlf, unsigne
for(i = 0, rect = sub->data; i < sub->nb_data; i++, rect++)
{
if (!rect->ocr_text) continue;
add_ocrtext2str(str, rect->ocr_text, crlf, crlf_length);
add_ocrtext2str(str, rect->ocr_text, context->encoded_crlf, context->encoded_crlf_length);
free(rect->ocr_text);
}
return str;
Expand Down
2 changes: 1 addition & 1 deletion src/lib_ccx/ocr.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ void delete_ocr (void** arg);
void* init_ocr(int lang_index);
char* ocr_bitmap(void* arg, png_color *palette,png_byte *alpha, unsigned char* indata,int w, int h, struct image_copy *copy);
int ocr_rect(void* arg, struct cc_bitmap *rect, char **str, int bgcolor, int ocr_quantmode);
char *paraof_ocrtext(struct cc_subtitle *sub, const unsigned char *crlf, unsigned crlf_length);
char *paraof_ocrtext(struct cc_subtitle *sub, struct encoder_ctx *context);

#endif

0 comments on commit 8db3398

Please sign in to comment.