unsigned get_decoder_line_encoded_for_gui(unsigned char *buffer, int line_num, struct eia608_screen *data) { unsigned char *line = data->characters[line_num]; unsigned char *orig = buffer; // Keep for debugging int first = 0, last = 31; find_limit_characters(line, &first, &last); for (int i = first; i <= last; i++) { get_char_in_latin_1(buffer, line[i]); buffer++; } *buffer = 0; return (unsigned)(buffer - orig); // Return length }
int get_str_basic(unsigned char *out_buffer, unsigned char *in_buffer, int trim_subs, enum ccx_encoding_type in_enc, enum ccx_encoding_type out_enc, int max_len) { int last_non_blank = -1; int first_non_blank = -1; int len = 0; find_limit_characters(in_buffer, &first_non_blank, &last_non_blank, max_len); if (!trim_subs) first_non_blank = 0; if (first_non_blank == -1) { *out_buffer = 0; return 0; } // change encoding only when required switch (in_enc) { case CCX_ENC_UTF_8: len = change_utf8_encoding(out_buffer, in_buffer + first_non_blank, last_non_blank-first_non_blank+1, out_enc); break; case CCX_ENC_LATIN_1: len = change_latin1_encoding(out_buffer, in_buffer + first_non_blank, last_non_blank-first_non_blank+1, out_enc); break; case CCX_ENC_UNICODE: len = change_unicode_encoding(out_buffer, in_buffer + first_non_blank, last_non_blank-first_non_blank+1, out_enc); break; case CCX_ENC_ASCII: len = change_ascii_encoding(out_buffer, in_buffer + first_non_blank, last_non_blank-first_non_blank+1, out_enc); break; } if (len < 0) mprint("WARNING: Could not encode in specified format\n"); else if (len == CCX_ENOSUPP) // we only support ASCII to other encoding std mprint("WARNING: Encoding is not yet supported\n"); else return (unsigned)len; // Return length return 0; // Return length }
unsigned get_decoder_line_basic(unsigned char *buffer, int line_num, struct eia608_screen *data, int trim_subs, enum ccx_encoding_type encoding) { unsigned char *line = data->characters[line_num]; int last_non_blank = -1; int first_non_blank = -1; unsigned char *orig = buffer; // Keep for debugging find_limit_characters(line, &first_non_blank, &last_non_blank); if (!trim_subs) first_non_blank = 0; if (first_non_blank == -1) { *buffer = 0; return 0; } int bytes = 0; for (int i = first_non_blank; i <= last_non_blank; i++) { char c = line[i]; switch (encoding) { case CCX_ENC_UTF_8: bytes = get_char_in_utf_8(buffer, c); break; case CCX_ENC_LATIN_1: get_char_in_latin_1(buffer, c); bytes = 1; break; case CCX_ENC_UNICODE: get_char_in_unicode(buffer, c); bytes = 2; break; } buffer += bytes; } *buffer = 0; return (unsigned)(buffer - orig); // Return length }
int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *context) { int used; unsigned h1,m1,s1,ms1; unsigned h2,m2,s2,ms2; LLONG ms_start, ms_end; int wrote_something = 0; ms_start = data->start_time; int prev_line_start=-1, prev_line_end=-1; // Column in which the previous line started and ended, for autodash int prev_line_center1=-1, prev_line_center2=-1; // Center column of previous line text int empty_buf=1; for (int i=0;i<15;i++) { if (data->row_used[i]) { empty_buf=0; break; } } if (empty_buf) // Prevent writing empty screens. Not needed in .srt return 0; ms_start+=context->subs_delay; if (ms_start<0) // Drop screens that because of subs_delay start too early return 0; 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. char timeline[128]; context->srt_counter++; sprintf(timeline, "%u%s", context->srt_counter, context->encoded_crlf); used = encode_line(context, context->buffer,(unsigned char *) timeline); write(context->out->fh, context->buffer, used); sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u%s", h1, m1, s1, ms1, h2, m2, s2, ms2, context->encoded_crlf); used = encode_line(context, context->buffer,(unsigned char *) timeline); dbg_print(CCX_DMT_DECODER_608, "\n- - - SRT caption ( %d) - - -\n", context->srt_counter); dbg_print(CCX_DMT_DECODER_608, "%s",timeline); write (context->out->fh, context->buffer, used); for (int i=0;i<15;i++) { if (data->row_used[i]) { if (context->sentence_cap) { capitalize (i,data); correct_case(i,data); } if (context->autodash && context->trim_subs) { int first=0, last=31, center1=-1, center2=-1; unsigned char *line = data->characters[i]; int do_dash=1, colon_pos=-1; find_limit_characters(line,&first,&last); if (first==-1 || last==-1) // Probably a bug somewhere though break; // Is there a speaker named, for example: TOM: What are you doing? for (int j=first;j<=last;j++) { if (line[j]==':') { colon_pos=j; break; } if (!isupper (line[j])) break; } if (prev_line_start==-1) do_dash=0; if (first==prev_line_start) // Case of left alignment do_dash=0; if (last==prev_line_end) // Right align do_dash=0; if (first>prev_line_start && last<prev_line_end) // Fully contained do_dash=0; if ((first>prev_line_start && first<prev_line_end) || // Overlap (last>prev_line_start && last<prev_line_end)) do_dash=0; center1=(first+last)/2; if (colon_pos!=-1) { while (colon_pos<CCX_DECODER_608_SCREEN_WIDTH && (line[colon_pos]==':' || line[colon_pos]==' ' || line[colon_pos]==0x89)) colon_pos++; // Find actual text center2=(colon_pos+last)/2; } else center2=center1; if (center1>=prev_line_center1-1 && center1<=prev_line_center1+1 && center1!=-1) // Center align do_dash=0; if (center2>=prev_line_center2-2 && center1<=prev_line_center2+2 && center1!=-1) // Center align do_dash=0; if (do_dash) write(context->out->fh, "- ", 2); prev_line_start=first; prev_line_end=last; prev_line_center1=center1; prev_line_center2=center2; } int length = get_decoder_line_encoded (context, context->subline, i, data); if (context->encoding!=CCX_ENC_UNICODE) { dbg_print(CCX_DMT_DECODER_608, "\r"); dbg_print(CCX_DMT_DECODER_608, "%s\n",context->subline); } write(context->out->fh, context->subline, length); write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length); wrote_something=1; // fprintf (wb->fh,context->encoded_crlf); } } dbg_print(CCX_DMT_DECODER_608, "- - - - - - - - - - - -\r\n"); // fprintf (wb->fh, context->encoded_crlf); write (context->out->fh, context->encoded_crlf, context->encoded_crlf_length); return wrote_something; }
unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num, struct eia608_screen *data) { int col = COL_WHITE; int underlined = 0; int italics = 0; int changed_font = 0; char tagstack[128] = ""; // Keep track of opening/closing tags unsigned char *line = data->characters[line_num]; unsigned char *orig = buffer; // Keep for debugging int first = 0, last = 31; 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_encoders_helpers_settings.no_font_color && !(col == COL_USERDEFINED && its_col == COL_WHITE)) // Don't replace user defined with white { if (changed_font) buffer = close_tag(buffer, tagstack, 'F', &underlined, &italics, &changed_font); // Add new font tag buffer += encode_line(buffer, (unsigned char*)color_text[its_col][1]); if (its_col == COL_USERDEFINED) { // The previous sentence doesn't copy the whole // <font> tag, just up to the quote before the color buffer += encode_line(buffer, (unsigned char*)usercolor_rgb); buffer += encode_line(buffer, (unsigned char*) "\">"); } if (color_text[its_col][1][0]) // That means a <font> was added to the buffer { strcat(tagstack, "F"); changed_font++; } col = its_col; } // Handle underlined int is_underlined = data->fonts[line_num][i] & FONT_UNDERLINED; if (is_underlined && underlined == 0 && !ccx_encoders_helpers_settings.no_type_setting) // Open underline { buffer += encode_line(buffer, (unsigned char *) "<u>"); strcat(tagstack, "U"); underlined++; } 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_encoders_helpers_settings.no_type_setting) // Open italics { buffer += encode_line(buffer, (unsigned char *) "<i>"); strcat(tagstack, "I"); 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_encoders_helpers_settings.encoding) { case CCX_ENC_UTF_8: bytes = get_char_in_utf_8(buffer, line[i]); break; case CCX_ENC_LATIN_1: get_char_in_latin_1(buffer, line[i]); bytes = 1; break; case CCX_ENC_UNICODE: get_char_in_unicode(buffer, line[i]); bytes = 2; break; } buffer += bytes; } buffer = close_tag(buffer, tagstack, 'A', &underlined, &italics, &changed_font); if (underlined || italics || changed_font) 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 }