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
}
Esempio n. 4
0
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
}