summaryrefslogtreecommitdiffstats
path: root/libhb/deccc608sub.c
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2014-04-13 16:22:16 +0000
committerjstebbins <[email protected]>2014-04-13 16:22:16 +0000
commit6db1a1e531ad62ba977f4587fb9011b0fd0b3416 (patch)
tree2c6882e9344b8181a11238835ae163d52e98e49e /libhb/deccc608sub.c
parente6ca45c979ec69bd1736bc943063083b08ce1914 (diff)
Convert all text subtitles to ASS subs
Add support for font color to tx3g. Allow more than one style flag at time in tx3g. Add positioning support to CC subs git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6163 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/deccc608sub.c')
-rw-r--r--libhb/deccc608sub.c1562
1 files changed, 492 insertions, 1070 deletions
diff --git a/libhb/deccc608sub.c b/libhb/deccc608sub.c
index 85b43efab..5f4066b67 100644
--- a/libhb/deccc608sub.c
+++ b/libhb/deccc608sub.c
@@ -7,15 +7,12 @@
#include "hb.h"
#include "deccc608sub.h"
+#define SSA_PREAMBLE_LEN 24
/*
* ccextractor static configuration variables.
*/
static int debug_608 = 0;
-static int trim_subs = 1;
-static int nofontcolor = 0;
-static enum encoding_type encoding = ENC_UTF_8;
static int cc_channel = 1;
-static int sentence_cap = 0;
static int subs_delay = 0;
static int norollup = 0;
static int direct_rollup = 0;
@@ -23,28 +20,21 @@ static int direct_rollup = 0;
/*
* Get the time of the last buffer that we have received.
*/
-static int64_t get_fts(struct s_write *wb)
+static int64_t get_last_pts(struct s_write *wb)
{
return wb->last_pts;
}
#define fatal(N, ...) // N
-int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10};
+int rowdata[] = {11,-1,1,2,3,4,12,13,14,15,5,6,7,8,9,10};
// Relationship between the first PAC byte and the row number
// The following enc_buffer is not used at the moment, if it does get used
// we need to bring it into the swrite struct. Same for "str".
#define INITIAL_ENC_BUFFER_CAPACITY 2048
-unsigned char str[2048]; // Another generic general purpose buffer
-
-#define GUARANTEE(wb, length) if (length>wb->enc_buffer_capacity) \
-{wb->enc_buffer_capacity*=2; wb->enc_buffer=(unsigned char*) realloc (wb->enc_buffer, wb->enc_buffer_capacity); \
- if (wb->enc_buffer==NULL) { fatal (EXIT_NOT_ENOUGH_MEMORY, "Not enough memory, bailing out\n"); } \
-}
-
-const unsigned char pac2_attribs[][3]= // Color, font, ident
+static const unsigned char pac2_attribs[][3]= // Color, font, ident
{
{COL_WHITE, FONT_REGULAR, 0}, // 0x40 || 0x60
{COL_WHITE, FONT_UNDERLINED, 0}, // 0x41 || 0x61
@@ -80,17 +70,10 @@ const unsigned char pac2_attribs[][3]= // Color, font, ident
{COL_WHITE, FONT_UNDERLINED, 28} // 0x5f || 0x7f
};
-// Preencoded strings
-unsigned char encoded_crlf[16];
-unsigned int encoded_crlf_length;
-unsigned char encoded_br[16];
-unsigned int encoded_br_length;
-
// Default color
-unsigned char usercolor_rgb[8]="";
-enum color_code default_color=COL_WHITE;
+static enum color_code default_color=COL_WHITE;
-const char *command_type[] =
+static const char *command_type[] =
{
"Unknown",
"EDM - EraseDisplayedMemory",
@@ -108,7 +91,7 @@ const char *command_type[] =
"RTD - Resume Text Display"
};
-const char *font_text[]=
+static const char *font_text[]=
{
"regular",
"italics",
@@ -116,24 +99,19 @@ const char *font_text[]=
"underlined italics"
};
-const char *cc_modes_text[]=
-{
- "Pop-Up captions"
-};
-
-const char *color_text[][2]=
+static const char *color_text[][2]=
{
- {"white",""},
- {"green","<font color=\"#00ff00\">"},
- {"blue","<font color=\"#0000ff\">"},
- {"cyan","<font color=\"#00ffff\">"},
- {"red","<font color=\"#ff0000\">"},
- {"yellow","<font color=\"#ffff00\">"},
- {"magenta","<font color=\"#ff00ff\">"},
- {"userdefined","<font color=\""}
+ {"white", "&HFFFFFF&"},
+ {"green", "&H00FF00&"},
+ {"blue", "&HFF0000&"},
+ {"cyan", "&HFFFF00&"},
+ {"red", "&H0000FF&"},
+ {"yellow", "&H00FFFF&"},
+ {"magenta", "&HFF00FF&"},
+ {"userdefined", "&HFFFFFF&"}
};
-int general_608_init (struct s_write *wb)
+static int general_608_init (struct s_write *wb)
{
if( !wb->enc_buffer )
{
@@ -167,7 +145,7 @@ int general_608_init (struct s_write *wb)
* parallel encodes to fail - to be honest they will be stuffed anyway since
* the CC's may be overwriting the buffers.
*/
-void general_608_close (struct s_write *wb)
+static void general_608_close (struct s_write *wb)
{
if( wb->enc_buffer ) {
free(wb->enc_buffer);
@@ -186,1076 +164,501 @@ void general_608_close (struct s_write *wb)
#include <ctype.h>
-void get_char_in_latin_1 (unsigned char *buffer, unsigned char c)
+// Returns number of bytes used
+static int get_char_in_utf8(unsigned char *buffer, unsigned char c)
{
- unsigned char c1='?';
- if (c<0x80)
- {
- // Regular line-21 character set, mostly ASCII except these exceptions
- switch (c)
- {
- case 0x2a: // lowercase a, acute accent
- c1=0xe1;
- break;
- case 0x5c: // lowercase e, acute accent
- c1=0xe9;
- break;
- case 0x5e: // lowercase i, acute accent
- c1=0xed;
- break;
- case 0x5f: // lowercase o, acute accent
- c1=0xf3;
- break;
- case 0x60: // lowercase u, acute accent
- c1=0xfa;
- break;
- case 0x7b: // lowercase c with cedilla
- c1=0xe7;
- break;
- case 0x7c: // division symbol
- c1=0xf7;
- break;
- case 0x7d: // uppercase N tilde
- c1=0xd1;
- break;
- case 0x7e: // lowercase n tilde
- c1=0xf1;
- break;
- default:
- c1=c;
- break;
- }
- *buffer=c1;
- return;
- }
- switch (c)
- {
- // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
- case 0x80: // Registered symbol (R)
- c1=0xae;
- break;
- case 0x81: // degree sign
- c1=0xb0;
- break;
- case 0x82: // 1/2 symbol
- c1=0xbd;
- break;
- case 0x83: // Inverted (open) question mark
- c1=0xbf;
- break;
- case 0x84: // Trademark symbol (TM) - Does not exist in Latin 1
- break;
- case 0x85: // Cents symbol
- c1=0xa2;
- break;
- case 0x86: // Pounds sterling
- c1=0xa3;
- break;
- case 0x87: // Music note - Not in latin 1, so we use 'pilcrow'
- c1=0xb6;
- break;
- case 0x88: // lowercase a, grave accent
- c1=0xe0;
- break;
- case 0x89: // transparent space, we make it regular
- c1=0x20;
- break;
- case 0x8a: // lowercase e, grave accent
- c1=0xe8;
- break;
- case 0x8b: // lowercase a, circumflex accent
- c1=0xe2;
- break;
- case 0x8c: // lowercase e, circumflex accent
- c1=0xea;
- break;
- case 0x8d: // lowercase i, circumflex accent
- c1=0xee;
- break;
- case 0x8e: // lowercase o, circumflex accent
- c1=0xf4;
- break;
- case 0x8f: // lowercase u, circumflex accent
- c1=0xfb;
- break;
- // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
- case 0x90: // capital letter A with acute
- c1=0xc1;
- break;
- case 0x91: // capital letter E with acute
- c1=0xc9;
- break;
- case 0x92: // capital letter O with acute
- c1=0xd3;
- break;
- case 0x93: // capital letter U with acute
- c1=0xda;
- break;
- case 0x94: // capital letter U with diaresis
- c1=0xdc;
- break;
- case 0x95: // lowercase letter U with diaeresis
- c1=0xfc;
- break;
- case 0x96: // apostrophe
- c1=0x27;
- break;
- case 0x97: // inverted exclamation mark
- c1=0xa1;
- break;
- case 0x98: // asterisk
- c1=0x2a;
- break;
- case 0x99: // apostrophe (yes, duped). See CCADI source code.
- c1=0x27;
- break;
- case 0x9a: // hyphen-minus
- c1=0x2d;
- break;
- case 0x9b: // copyright sign
- c1=0xa9;
- break;
- case 0x9c: // Service Mark - not available in latin 1
- break;
- case 0x9d: // Full stop (.)
- c1=0x2e;
- break;
- case 0x9e: // Quoatation mark
- c1=0x22;
- break;
- case 0x9f: // Quoatation mark
- c1=0x22;
- break;
- case 0xa0: // uppercase A, grave accent
- c1=0xc0;
- break;
- case 0xa1: // uppercase A, circumflex
- c1=0xc2;
- break;
- case 0xa2: // uppercase C with cedilla
- c1=0xc7;
- break;
- case 0xa3: // uppercase E, grave accent
- c1=0xc8;
- break;
- case 0xa4: // uppercase E, circumflex
- c1=0xca;
- break;
- case 0xa5: // capital letter E with diaresis
- c1=0xcb;
- break;
- case 0xa6: // lowercase letter e with diaresis
- c1=0xeb;
- break;
- case 0xa7: // uppercase I, circumflex
- c1=0xce;
- break;
- case 0xa8: // uppercase I, with diaresis
- c1=0xcf;
- break;
- case 0xa9: // lowercase i, with diaresis
- c1=0xef;
- break;
- case 0xaa: // uppercase O, circumflex
- c1=0xd4;
- break;
- case 0xab: // uppercase U, grave accent
- c1=0xd9;
- break;
- case 0xac: // lowercase u, grave accent
- c1=0xf9;
- break;
- case 0xad: // uppercase U, circumflex
- c1=0xdb;
- break;
- case 0xae: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
- c1=0xab;
- break;
- case 0xaf: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
- c1=0xbb;
- break;
- // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
- case 0xb0: // Uppercase A, tilde
- c1=0xc3;
- break;
- case 0xb1: // Lowercase a, tilde
- c1=0xe3;
- break;
- case 0xb2: // Uppercase I, acute accent
- c1=0xcd;
- break;
- case 0xb3: // Uppercase I, grave accent
- c1=0xcc;
- break;
- case 0xb4: // Lowercase i, grave accent
- c1=0xec;
- break;
- case 0xb5: // Uppercase O, grave accent
- c1=0xd2;
- break;
- case 0xb6: // Lowercase o, grave accent
- c1=0xf2;
- break;
- case 0xb7: // Uppercase O, tilde
- c1=0xd5;
- break;
- case 0xb8: // Lowercase o, tilde
- c1=0xf5;
- break;
- case 0xb9: // Open curly brace
- c1=0x7b;
- break;
- case 0xba: // Closing curly brace
- c1=0x7d;
- break;
- case 0xbb: // Backslash
- c1=0x5c;
- break;
- case 0xbc: // Caret
- c1=0x5e;
- break;
- case 0xbd: // Underscore
- c1=0x5f;
- break;
- case 0xbe: // Pipe (broken bar)
- c1=0xa6;
- break;
- case 0xbf: // Tilde
- c1=0x7e;
- break;
- case 0xc0: // Uppercase A, umlaut
- c1=0xc4;
- break;
- case 0xc1: // Lowercase A, umlaut
- c1=0xe3;
- break;
- case 0xc2: // Uppercase O, umlaut
- c1=0xd6;
- break;
- case 0xc3: // Lowercase o, umlaut
- c1=0xf6;
- break;
- case 0xc4: // Esszett (sharp S)
- c1=0xdf;
- break;
- case 0xc5: // Yen symbol
- c1=0xa5;
- break;
- case 0xc6: // Currency symbol
- c1=0xa4;
- break;
- case 0xc7: // Vertical bar
- c1=0x7c;
- break;
- case 0xc8: // Uppercase A, ring
- c1=0xc5;
- break;
- case 0xc9: // Lowercase A, ring
- c1=0xe5;
- break;
- case 0xca: // Uppercase O, slash
- c1=0xd8;
- break;
- case 0xcb: // Lowercase o, slash
- c1=0xf8;
- break;
- case 0xcc: // Upper left corner
- case 0xcd: // Upper right corner
- case 0xce: // Lower left corner
- case 0xcf: // Lower right corner
- default: // For those that don't have representation
- *buffer='?'; // I'll do it eventually, I promise
- break; // This are weird chars anyway
- }
- *buffer=c1;
-}
-
-void get_char_in_unicode (unsigned char *buffer, unsigned char c)
-{
- unsigned char c1,c2;
- switch (c)
- {
- case 0x84: // Trademark symbol (TM)
- c2=0x21;
- c1=0x22;
- break;
- case 0x87: // Music note
- c2=0x26;
- c1=0x6a;
- break;
- case 0x9c: // Service Mark
- c2=0x21;
- c1=0x20;
- break;
- case 0xcc: // Upper left corner
- c2=0x23;
- c1=0x1c;
- break;
- case 0xcd: // Upper right corner
- c2=0x23;
- c1=0x1d;
- break;
- case 0xce: // Lower left corner
- c2=0x23;
- c1=0x1e;
- break;
- case 0xcf: // Lower right corner
- c2=0x23;
- c1=0x1f;
- break;
- default: // Everything else, same as latin-1 followed by 00
- get_char_in_latin_1 (&c1,c);
- c2=0;
- break;
- }
- *buffer=c1;
- *(buffer+1)=c2;
-}
-
-int get_char_in_utf_8 (unsigned char *buffer, unsigned char c) // Returns number of bytes used
-{
- if (c==0x00)
+ if (c == 0x00)
return 0;
- if (c<0x80) // Regular line-21 character set, mostly ASCII except these exceptions
+
+ // Regular line-21 character set, mostly ASCII except these exceptions
+ if (c < 0x80)
{
switch (c)
{
case 0x2a: // lowercase a, acute accent
- *buffer=0xc3;
- *(buffer+1)=0xa1;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa1;
return 2;
case 0x5c: // lowercase e, acute accent
- *buffer=0xc3;
- *(buffer+1)=0xa9;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa9;
return 2;
case 0x5e: // lowercase i, acute accent
- *buffer=0xc3;
- *(buffer+1)=0xad;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xad;
return 2;
case 0x5f: // lowercase o, acute accent
- *buffer=0xc3;
- *(buffer+1)=0xb3;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb3;
return 2;
case 0x60: // lowercase u, acute accent
- *buffer=0xc3;
- *(buffer+1)=0xba;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xba;
return 2;
case 0x7b: // lowercase c with cedilla
- *buffer=0xc3;
- *(buffer+1)=0xa7;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa7;
return 2;
case 0x7c: // division symbol
- *buffer=0xc3;
- *(buffer+1)=0xb7;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb7;
return 2;
case 0x7d: // uppercase N tilde
- *buffer=0xc3;
- *(buffer+1)=0x91;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x91;
return 2;
case 0x7e: // lowercase n tilde
- *buffer=0xc3;
- *(buffer+1)=0xb1;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb1;
return 2;
default:
- *buffer=c;
+ *buffer = c;
return 1;
}
}
switch (c)
{
// THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
+ // THAT COME FROM HI BYTE = 0x11 AND LOW BETWEEN 0x30 AND 0x3F
case 0x80: // Registered symbol (R)
- *buffer=0xc2;
- *(buffer+1)=0xae;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xae;
return 2;
case 0x81: // degree sign
- *buffer=0xc2;
- *(buffer+1)=0xb0;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xb0;
return 2;
case 0x82: // 1/2 symbol
- *buffer=0xc2;
- *(buffer+1)=0xbd;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xbd;
return 2;
case 0x83: // Inverted (open) question mark
- *buffer=0xc2;
- *(buffer+1)=0xbf;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xbf;
return 2;
case 0x84: // Trademark symbol (TM)
- *buffer=0xe2;
- *(buffer+1)=0x84;
- *(buffer+2)=0xa2;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x84;
+ *(buffer+2) = 0xa2;
return 3;
case 0x85: // Cents symbol
- *buffer=0xc2;
- *(buffer+1)=0xa2;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa2;
return 2;
case 0x86: // Pounds sterling
- *buffer=0xc2;
- *(buffer+1)=0xa3;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa3;
return 2;
case 0x87: // Music note
- *buffer=0xe2;
- *(buffer+1)=0x99;
- *(buffer+2)=0xaa;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x99;
+ *(buffer+2) = 0xaa;
return 3;
case 0x88: // lowercase a, grave accent
- *buffer=0xc3;
- *(buffer+1)=0xa0;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa0;
return 2;
case 0x89: // transparent space, we make it regular
- *buffer=0x20;
+ *buffer = 0x20;
return 1;
case 0x8a: // lowercase e, grave accent
- *buffer=0xc3;
- *(buffer+1)=0xa8;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa8;
return 2;
case 0x8b: // lowercase a, circumflex accent
- *buffer=0xc3;
- *(buffer+1)=0xa2;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa2;
return 2;
case 0x8c: // lowercase e, circumflex accent
- *buffer=0xc3;
- *(buffer+1)=0xaa;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xaa;
return 2;
case 0x8d: // lowercase i, circumflex accent
- *buffer=0xc3;
- *(buffer+1)=0xae;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xae;
return 2;
case 0x8e: // lowercase o, circumflex accent
- *buffer=0xc3;
- *(buffer+1)=0xb4;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb4;
return 2;
case 0x8f: // lowercase u, circumflex accent
- *buffer=0xc3;
- *(buffer+1)=0xbb;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xbb;
return 2;
// THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
+ // THAT COME FROM HI BYTE = 0x12 AND LOW BETWEEN 0x20 AND 0x3F
case 0x90: // capital letter A with acute
- *buffer=0xc3;
- *(buffer+1)=0x81;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x81;
return 2;
case 0x91: // capital letter E with acute
- *buffer=0xc3;
- *(buffer+1)=0x89;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x89;
return 2;
case 0x92: // capital letter O with acute
- *buffer=0xc3;
- *(buffer+1)=0x93;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x93;
return 2;
case 0x93: // capital letter U with acute
- *buffer=0xc3;
- *(buffer+1)=0x9a;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x9a;
return 2;
case 0x94: // capital letter U with diaresis
- *buffer=0xc3;
- *(buffer+1)=0x9c;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x9c;
return 2;
case 0x95: // lowercase letter U with diaeresis
- *buffer=0xc3;
- *(buffer+1)=0xbc;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xbc;
return 2;
case 0x96: // apostrophe
- *buffer=0x27;
+ *buffer = 0x27;
return 1;
case 0x97: // inverted exclamation mark
- *buffer=0xc2;
- *(buffer+1)=0xa1;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa1;
return 2;
case 0x98: // asterisk
- *buffer=0x2a;
+ *buffer = 0x2a;
return 1;
case 0x99: // apostrophe (yes, duped). See CCADI source code.
- *buffer=0x27;
+ *buffer = 0x27;
return 1;
case 0x9a: // hyphen-minus
- *buffer=0x2d;
+ *buffer = 0x2d;
return 1;
case 0x9b: // copyright sign
- *buffer=0xc2;
- *(buffer+1)=0xa9;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa9;
return 2;
case 0x9c: // Service mark
- *buffer=0xe2;
- *(buffer+1)=0x84;
- *(buffer+2)=0xa0;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x84;
+ *(buffer+2) = 0xa0;
return 3;
case 0x9d: // Full stop (.)
- *buffer=0x2e;
+ *buffer = 0x2e;
return 1;
case 0x9e: // Quoatation mark
- *buffer=0x22;
+ *buffer = 0x22;
return 1;
case 0x9f: // Quoatation mark
- *buffer=0x22;
+ *buffer = 0x22;
return 1;
case 0xa0: // uppercase A, grave accent
- *buffer=0xc3;
- *(buffer+1)=0x80;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x80;
return 2;
case 0xa1: // uppercase A, circumflex
- *buffer=0xc3;
- *(buffer+1)=0x82;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x82;
return 2;
case 0xa2: // uppercase C with cedilla
- *buffer=0xc3;
- *(buffer+1)=0x87;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x87;
return 2;
case 0xa3: // uppercase E, grave accent
- *buffer=0xc3;
- *(buffer+1)=0x88;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x88;
return 2;
case 0xa4: // uppercase E, circumflex
- *buffer=0xc3;
- *(buffer+1)=0x8a;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8a;
return 2;
case 0xa5: // capital letter E with diaresis
- *buffer=0xc3;
- *(buffer+1)=0x8b;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8b;
return 2;
case 0xa6: // lowercase letter e with diaresis
- *buffer=0xc3;
- *(buffer+1)=0xab;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xab;
return 2;
case 0xa7: // uppercase I, circumflex
- *buffer=0xc3;
- *(buffer+1)=0x8e;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8e;
return 2;
case 0xa8: // uppercase I, with diaresis
- *buffer=0xc3;
- *(buffer+1)=0x8f;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8f;
return 2;
case 0xa9: // lowercase i, with diaresis
- *buffer=0xc3;
- *(buffer+1)=0xaf;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xaf;
return 2;
case 0xaa: // uppercase O, circumflex
- *buffer=0xc3;
- *(buffer+1)=0x94;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x94;
return 2;
case 0xab: // uppercase U, grave accent
- *buffer=0xc3;
- *(buffer+1)=0x99;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x99;
return 2;
case 0xac: // lowercase u, grave accent
- *buffer=0xc3;
- *(buffer+1)=0xb9;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb9;
return 2;
case 0xad: // uppercase U, circumflex
- *buffer=0xc3;
- *(buffer+1)=0x9b;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x9b;
return 2;
case 0xae: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
- *buffer=0xc2;
- *(buffer+1)=0xab;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xab;
return 2;
case 0xaf: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
- *buffer=0xc2;
- *(buffer+1)=0xbb;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xbb;
return 2;
// THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
- // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
+ // THAT COME FROM HI BYTE = 0x13 AND LOW BETWEEN 0x20 AND 0x3F
case 0xb0: // Uppercase A, tilde
- *buffer=0xc3;
- *(buffer+1)=0x83;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x83;
return 2;
case 0xb1: // Lowercase a, tilde
- *buffer=0xc3;
- *(buffer+1)=0xa3;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa3;
return 2;
case 0xb2: // Uppercase I, acute accent
- *buffer=0xc3;
- *(buffer+1)=0x8d;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8d;
return 2;
case 0xb3: // Uppercase I, grave accent
- *buffer=0xc3;
- *(buffer+1)=0x8c;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x8c;
return 2;
case 0xb4: // Lowercase i, grave accent
- *buffer=0xc3;
- *(buffer+1)=0xac;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xac;
return 2;
case 0xb5: // Uppercase O, grave accent
- *buffer=0xc3;
- *(buffer+1)=0x92;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x92;
return 2;
case 0xb6: // Lowercase o, grave accent
- *buffer=0xc3;
- *(buffer+1)=0xb2;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb2;
return 2;
case 0xb7: // Uppercase O, tilde
- *buffer=0xc3;
- *(buffer+1)=0x95;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x95;
return 2;
case 0xb8: // Lowercase o, tilde
- *buffer=0xc3;
- *(buffer+1)=0xb5;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb5;
return 2;
case 0xb9: // Open curly brace
- *buffer=0x7b;
+ *buffer = 0x7b;
return 1;
case 0xba: // Closing curly brace
- *buffer=0x7d;
+ *buffer = 0x7d;
return 1;
case 0xbb: // Backslash
- *buffer=0x5c;
+ *buffer = 0x5c;
return 1;
case 0xbc: // Caret
- *buffer=0x5e;
+ *buffer = 0x5e;
return 1;
case 0xbd: // Underscore
- *buffer=0x5f;
+ *buffer = 0x5f;
return 1;
case 0xbe: // Pipe (broken bar)
- *buffer=0xc2;
- *(buffer+1)=0xa6;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa6;
return 1;
case 0xbf: // Tilde
- *buffer=0x7e; // Not sure
+ *buffer = 0x7e; // Not sure
return 1;
case 0xc0: // Uppercase A, umlaut
- *buffer=0xc3;
- *(buffer+1)=0x84;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x84;
return 2;
case 0xc1: // Lowercase A, umlaut
- *buffer=0xc3;
- *(buffer+1)=0xa4;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa4;
return 2;
case 0xc2: // Uppercase O, umlaut
- *buffer=0xc3;
- *(buffer+1)=0x96;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x96;
return 2;
case 0xc3: // Lowercase o, umlaut
- *buffer=0xc3;
- *(buffer+1)=0xb6;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb6;
return 2;
case 0xc4: // Esszett (sharp S)
- *buffer=0xc3;
- *(buffer+1)=0x9f;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x9f;
return 2;
case 0xc5: // Yen symbol
- *buffer=0xc2;
- *(buffer+1)=0xa5;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa5;
return 2;
case 0xc6: // Currency symbol
- *buffer=0xc2;
- *(buffer+1)=0xa4;
+ *buffer = 0xc2;
+ *(buffer+1) = 0xa4;
return 2;
case 0xc7: // Vertical bar
- *buffer=0x7c;
+ *buffer = 0x7c;
return 1;
case 0xc8: // Uppercase A, ring
- *buffer=0xc3;
- *(buffer+1)=0x85;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x85;
return 2;
case 0xc9: // Lowercase A, ring
- *buffer=0xc3;
- *(buffer+1)=0xa5;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xa5;
return 2;
case 0xca: // Uppercase O, slash
- *buffer=0xc3;
- *(buffer+1)=0x98;
+ *buffer = 0xc3;
+ *(buffer+1) = 0x98;
return 2;
case 0xcb: // Lowercase o, slash
- *buffer=0xc3;
- *(buffer+1)=0xb8;
+ *buffer = 0xc3;
+ *(buffer+1) = 0xb8;
return 2;
case 0xcc: // Upper left corner
- *buffer=0xe2;
- *(buffer+1)=0x8c;
- *(buffer+2)=0x9c;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x8c;
+ *(buffer+2) = 0x9c;
return 3;
case 0xcd: // Upper right corner
- *buffer=0xe2;
- *(buffer+1)=0x8c;
- *(buffer+2)=0x9d;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x8c;
+ *(buffer+2) = 0x9d;
return 3;
case 0xce: // Lower left corner
- *buffer=0xe2;
- *(buffer+1)=0x8c;
- *(buffer+2)=0x9e;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x8c;
+ *(buffer+2) = 0x9e;
return 3;
case 0xcf: // Lower right corner
- *buffer=0xe2;
- *(buffer+1)=0x8c;
- *(buffer+2)=0x9f;
+ *buffer = 0xe2;
+ *(buffer+1) = 0x8c;
+ *(buffer+2) = 0x9f;
return 3;
default: //
- *buffer='?'; // I'll do it eventually, I promise
+ *buffer = '?'; // I'll do it eventually, I promise
return 1; // This are weird chars anyway
}
}
-unsigned char cctolower (unsigned char c)
+// 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.
+static unsigned encode_line(unsigned char *buffer, unsigned char *text)
{
- if (c>='A' && c<='Z')
- return tolower(c);
- switch (c)
- {
- case 0x7d: // uppercase N tilde
- return 0x7e;
- case 0x90: // capital letter A with acute
- return 0x2a;
- case 0x91: // capital letter E with acute
- return 0x5c;
- case 0x92: // capital letter O with acute
- return 0x5f;
- case 0x93: // capital letter U with acute
- return 0x60;
- case 0xa2: // uppercase C with cedilla
- return 0x7b;
- case 0xa0: // uppercase A, grave accent
- return 0x88;
- case 0xa3: // uppercase E, grave accent
- return 0x8a;
- case 0xa1: // uppercase A, circumflex
- return 0x8b;
- case 0xa4: // uppercase E, circumflex
- return 0x8c;
- case 0xa7: // uppercase I, circumflex
- return 0x8d;
- case 0xaa: // uppercase O, circumflex
- return 0x8e;
- case 0xad: // uppercase U, circumflex
- return 0x8f;
- case 0x94: // capital letter U with diaresis
- return 0x95;
- case 0xa5: // capital letter E with diaresis
- return 0xa6;
- case 0xa8: // uppercase I, with diaresis
- return 0xa9;
- case 0xab: // uppercase U, grave accent
- return 0xac;
- case 0xb0: // Uppercase A, tilde
- return 0xb1;
- case 0xb2: // Uppercase I, acute accent
- return 0x5e;
- case 0xb3: // Uppercase I, grave accent
- return 0xb4;
- case 0xb5: // Uppercase O, grave accent
- return 0xb6;
- case 0xb7: // Uppercase O, tilde
- return 0xb8;
- case 0xc0: // Uppercase A, umlaut
- return 0xc1;
- case 0xc2: // Uppercase O, umlaut
- return 0xc3;
- case 0xc8: // Uppercase A, ring
- return 0xc9;
- case 0xca: // Uppercase O, slash
- return 0xcb;
- }
- return c;
-}
-
-unsigned char cctoupper (unsigned char c)
-{
- if (c>='a' && c<='z')
- return toupper(c);
- switch (c)
- {
- case 0x7e: // lowercase n tilde
- return 0x7d;
- case 0x2a: // lowercase a, acute accent
- return 0x90;
- case 0x5c: // lowercase e, acute accent
- return 0x91;
- case 0x5e: // lowercase i, acute accent
- return 0xb2;
- case 0x5f: // lowercase o, acute accent
- return 0x92;
- case 0x60: // lowercase u, acute accent
- return 0x93;
- case 0x7b: // lowercase c with cedilla
- return 0xa2;
- case 0x88: // lowercase a, grave accent
- return 0xa0;
- case 0x8a: // lowercase e, grave accent
- return 0xa3;
- case 0x8b: // lowercase a, circumflex accent
- return 0xa1;
- case 0x8c: // lowercase e, circumflex accent
- return 0xa4;
- case 0x8d: // lowercase i, circumflex accent
- return 0xa7;
- case 0x8e: // lowercase o, circumflex accent
- return 0xaa;
- case 0x8f: // lowercase u, circumflex accent
- return 0xad;
- case 0x95: // lowercase letter U with diaeresis
- return 0x94;
- case 0xa6: // lowercase letter e with diaresis
- return 0xa5;
- case 0xa9: // lowercase i, with diaresis
- return 0xa8;
- case 0xac: // lowercase u, grave accent
- return 0xab;
- case 0xb1: // Lowercase a, tilde
- return 0xb0;
- case 0xb4: // Lowercase i, grave accent
- return 0xb3;
- case 0xb6: // Lowercase o, grave accent
- return 0xb5;
- case 0xb8: // Lowercase o, tilde
- return 0xb7;
- case 0xc1: // Lowercase A, umlaut
- return 0xc0;
- case 0xc3: // Lowercase o, umlaut
- return 0xc2;
- case 0xc9: // Lowercase A, ring
- return 0xc8;
- case 0xcb: // Lowercase o, slash
- return 0xca;
- }
- return c;
-}
-
-
-// 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;
+ unsigned bytes = 0;
while (*text)
{
- switch (encoding)
- {
- case ENC_UTF_8:
- case ENC_LATIN_1:
- *buffer=*text;
- bytes++;
- buffer++;
- break;
- case ENC_UNICODE:
- *buffer=*text;
- *(buffer+1)=0;
- bytes+=2;
- buffer+=2;
- break;
- }
- text++;
+ *buffer++ = *text++;
+ bytes++;
}
return bytes;
}
-#define ISSEPARATOR(c) (c==' ' || c==0x89 || ispunct(c) \
- || c==0x99) // This is the apostrofe. We get it here in CC encoding, not ASCII
-
-
-void correct_case (int line_num, struct eia608_screen *data)
-{
-/* int i=0; */
-/* while (i<spell_words) */
-/* { */
-/* char *c=(char *) data->characters[line_num]; */
-/* size_t len=strlen (spell_correct[i]); */
-/* while ((c=strstr (c,spell_lower[i]))!=NULL) */
-/* { */
-/* // Make sure it's a whole word (start of line or */
-/* // preceded by space, and end of line or followed by */
-/* // space) */
-/* unsigned char prev; */
-/* if (c==(char *) data->characters[line_num]) // Beginning of line... */
-/* prev=' '; // ...Pretend we had a blank before */
-/* else */
-/* prev=*(c-1); */
-/* unsigned char next; */
-/* if (c-(char *) data->characters[line_num]+len==CC608_SCREEN_WIDTH) // End of line... */
-/* next=' '; // ... pretend we have a blank later */
-/* else */
-/* next=*(c+len); */
-/* if ( ISSEPARATOR(prev) && ISSEPARATOR(next)) */
-/* { */
-/* memcpy (c,spell_correct[i],len); */
-/* } */
-/* c++; */
-/* } */
-/* i++; */
-/* } */
-}
-
-void capitalize (int line_num, struct eia608_screen *data, int *new_sentence)
+static void find_limit_characters(unsigned char *line, int *first_non_blank,
+ int *last_non_blank)
{
int i;
- for (i=0;i<CC608_SCREEN_WIDTH;i++)
+ *last_non_blank = -1;
+ *first_non_blank = -1;
+ for (i = 0; i < CC608_SCREEN_WIDTH; i++)
{
- switch (data->characters[line_num][i])
+ unsigned char c = line[i];
+ if (c != ' ' && c != 0x89)
{
- case ' ':
- case 0x89: // This is a transparent space
- case '-':
- break;
- case '.': // Fallthrough
- case '?': // Fallthrough
- case '!':
- case ':':
- *new_sentence=1;
- break;
- default:
- if (*new_sentence)
- data->characters[line_num][i]=cctoupper (data->characters[line_num][i]);
- else
- data->characters[line_num][i]=cctolower (data->characters[line_num][i]);
- *new_sentence=0;
- break;
+ if (*first_non_blank == -1)
+ *first_non_blank = i;
+ *last_non_blank = i;
}
}
}
-void find_limit_characters (unsigned char *line, int *first_non_blank, int *last_non_blank)
+static unsigned get_decoder_line_encoded(unsigned char *buffer, int line_num,
+ struct eia608_screen *data)
{
+ uint8_t font_style;
+ uint8_t prev_font_style = FONT_REGULAR;
+ uint8_t font_color;
+ uint8_t prev_font_color = COL_WHITE;
int i;
- *last_non_blank=-1;
- *first_non_blank=-1;
- for (i=0;i<CC608_SCREEN_WIDTH;i++)
- {
- unsigned char c=line[i];
- if (c!=' ' && c!=0x89)
- {
- if (*first_non_blank==-1)
- *first_non_blank=i;
- *last_non_blank=i;
- }
- }
-}
-
-unsigned get_decoder_line_basic (unsigned char *buffer, int line_num, struct eia608_screen *data)
-{
unsigned char *line = data->characters[line_num];
- int last_non_blank=-1;
- int first_non_blank=-1;
- unsigned char *orig=buffer; // Keep for debugging
- int i;
- find_limit_characters (line, &first_non_blank, &last_non_blank);
+ unsigned char *orig = buffer; // Keep for debugging
+ int first = 0, last = 31;
- if (first_non_blank==-1)
+ find_limit_characters(line, &first, &last);
+ for (i = first; i <= last; i++)
{
- *buffer=0;
- return 0;
- }
+ // Handle color
+ font_color = data->colors[line_num][i];
+ font_style = data->fonts[line_num][i];
- int bytes=0;
- for (i=first_non_blank;i<=last_non_blank;i++)
- {
- char c=line[i];
- switch (encoding)
+ // Handle reset to defaults
+ if ((font_style & FONT_STYLE_MASK) == 0 && font_color == COL_WHITE)
{
- case ENC_UTF_8:
- bytes=get_char_in_utf_8 (buffer,c);
- break;
- case ENC_LATIN_1:
- get_char_in_latin_1 (buffer,c);
- bytes=1;
- break;
- case ENC_UNICODE:
- get_char_in_unicode (buffer,c);
- bytes=2;
- break;
+ if (((font_style ^ prev_font_style) & FONT_STYLE_MASK) ||
+ (font_color != prev_font_color))
+ {
+ buffer += encode_line(buffer, (uint8_t*)"{\\r}");
+ }
}
- buffer+=bytes;
- }
- *buffer=0;
- return (unsigned) (buffer-orig); // Return length
-}
+ else
+ {
+ // Open markup
+ if (((font_style ^ prev_font_style) & FONT_STYLE_MASK) ||
+ (font_color != prev_font_color))
+ {
+ // style changed
+ buffer += encode_line(buffer, (uint8_t*)"{");
+ }
-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 i;
+ // Handle underlined
+ if ((font_style ^ prev_font_style) & FONT_UNDERLINED)
+ {
+ int enable = !!(font_style & FONT_UNDERLINED);
+ buffer += encode_line(buffer, (uint8_t*)"\\u");
+ *buffer++ = enable + 0x30;
+ }
- unsigned char *line = data->characters[line_num];
- unsigned char *orig=buffer; // Keep for debugging
- int first=0, last=31;
- if (trim_subs)
- find_limit_characters(line,&first,&last);
- for (i=first;i<=last;i++)
- {
- // Handle color
- int its_col = data->colors[line_num][i];
- if (its_col != col && !nofontcolor)
- {
- if (col!=COL_WHITE) // We need to close the previous font tag
+ // Handle italics
+ if ((font_style ^ prev_font_style) & FONT_ITALICS)
{
- buffer+= encode_line (buffer,(unsigned char *) "</font>");
+ int enable = !!(font_style & FONT_ITALICS);
+ buffer += encode_line(buffer, (uint8_t*)"\\i");
+ *buffer++ = enable + 0x30;
}
- // Add new font tag
- buffer+=encode_line (buffer, (unsigned char*) color_text[its_col][1]);
- if (its_col==COL_USERDEFINED)
+
+ // Handle color
+ if (font_color != prev_font_color)
{
- // 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*) "\">");
+ buffer += encode_line(buffer, (uint8_t*)"\\1c");
+ buffer += encode_line(buffer,
+ (uint8_t*)color_text[font_color][1]);
}
- col = its_col;
- }
- // Handle underlined
- int is_underlined = data->fonts[line_num][i] & FONT_UNDERLINED;
- if (is_underlined && underlined==0) // Open underline
- {
- buffer+=encode_line (buffer, (unsigned char *) "<u>");
- }
- if (is_underlined==0 && underlined) // Close underline
- {
- buffer+=encode_line (buffer, (unsigned char *) "</u>");
- }
- underlined=is_underlined;
- // Handle italics
- int has_ita = data->fonts[line_num][i] & FONT_ITALICS;
- if (has_ita && italics==0) // Open italics
- {
- buffer+=encode_line (buffer, (unsigned char *) "<i>");
- }
- if (has_ita==0 && italics) // Close italics
- {
- buffer+=encode_line (buffer, (unsigned char *) "</i>");
- }
- italics=has_ita;
- int bytes=0;
- switch (encoding)
- {
- case ENC_UTF_8:
- bytes=get_char_in_utf_8 (buffer,line[i]);
- break;
- case ENC_LATIN_1:
- get_char_in_latin_1 (buffer,line[i]);
- bytes=1;
- break;
- case ENC_UNICODE:
- get_char_in_unicode (buffer,line[i]);
- bytes=2;
- break;
+ // Close markup
+ if (((font_style ^ prev_font_style) & FONT_STYLE_MASK) ||
+ (font_color != prev_font_color))
+ {
+ // style changed
+ buffer += encode_line(buffer, (uint8_t*)"}");
+ }
}
- buffer+=bytes;
- }
- if (italics)
- {
- buffer+=encode_line (buffer, (unsigned char *) "</i>");
- }
- if (underlined)
- {
- buffer+=encode_line (buffer, (unsigned char *) "</u>");
- }
- if (col != COL_WHITE && !nofontcolor)
- {
- buffer+=encode_line (buffer, (unsigned char *) "</font>");
+ prev_font_style = font_style;
+ prev_font_color = font_color;
+
+ int bytes = 0;
+ bytes = get_char_in_utf8(buffer, line[i]);
+ buffer += bytes;
}
- *buffer=0;
- return (unsigned) (buffer-orig); // Return length
+ *buffer = 0;
+ return (unsigned) (buffer - orig); // Return length
}
-void delete_all_lines_but_current (struct eia608_screen *data, int row)
+static void delete_all_lines_but_current (struct eia608_screen *data, int row)
{
int i;
for (i=0;i<15;i++)
@@ -1271,7 +674,7 @@ void delete_all_lines_but_current (struct eia608_screen *data, int row)
}
}
-void clear_eia608_cc_buffer (struct eia608_screen *data)
+static void clear_eia608_cc_buffer (struct eia608_screen *data)
{
int i;
@@ -1286,27 +689,26 @@ void clear_eia608_cc_buffer (struct eia608_screen *data)
data->empty=1;
}
-void init_eia608 (struct eia608 *data)
+static void init_eia608 (struct eia608 *data)
{
- data->cursor_column=0;
- data->cursor_row=0;
+ data->cursor_column = 0;
+ data->cursor_row = 0;
clear_eia608_cc_buffer (&data->buffer1);
clear_eia608_cc_buffer (&data->buffer2);
- data->visible_buffer=1;
- data->last_c1=0;
- data->last_c2=0;
- data->mode=MODE_POPUP;
- // data->current_visible_start_cc=0;
- data->current_visible_start_ms=0;
- data->srt_counter=0;
- data->screenfuls_counter=0;
- data->channel=1;
- data->color=default_color;
- data->font=FONT_REGULAR;
- data->rollup_base_row=14;
+ data->visible_buffer = 1;
+ data->last_c1 = 0;
+ data->last_c2 = 0;
+ data->mode = MODE_POPUP;
+ data->current_visible_start_ms = 0;
+ data->ssa_counter = 0;
+ data->screenfuls_counter = 0;
+ data->channel = 1;
+ data->color = default_color;
+ data->font = FONT_REGULAR;
+ data->rollup_base_row = 14;
}
-struct eia608_screen *get_current_hidden_buffer(struct s_write *wb)
+static struct eia608_screen *get_current_hidden_buffer(struct s_write *wb)
{
struct eia608_screen *data;
if (wb->data608->visible_buffer == 1)
@@ -1316,7 +718,7 @@ struct eia608_screen *get_current_hidden_buffer(struct s_write *wb)
return data;
}
-struct eia608_screen *get_current_visible_buffer(struct s_write *wb)
+static struct eia608_screen *get_current_visible_buffer(struct s_write *wb)
{
struct eia608_screen *data;
if (wb->data608->visible_buffer == 1)
@@ -1331,7 +733,7 @@ static void swap_visible_buffer(struct s_write *wb)
wb->data608->visible_buffer = (wb->data608->visible_buffer == 1) ? 2 : 1;
}
-struct eia608_screen *get_writing_buffer (struct s_write *wb)
+static struct eia608_screen *get_writing_buffer(struct s_write *wb)
{
struct eia608_screen *use_buffer=NULL;
switch (wb->data608->mode)
@@ -1350,27 +752,28 @@ struct eia608_screen *get_writing_buffer (struct s_write *wb)
return use_buffer;
}
-void write_char (const unsigned char c, struct s_write *wb)
+static void write_char(const unsigned char c, struct s_write *wb)
{
- if (wb->data608->mode!=MODE_TEXT)
+ if (wb->data608->mode != MODE_TEXT)
{
- struct eia608_screen * use_buffer=get_writing_buffer(wb);
+ struct eia608_screen * use_buffer = get_writing_buffer(wb);
/* hb_log ("\rWriting char [%c] at %s:%d:%d\n",c,
use_buffer == &wb->data608->buffer1?"B1":"B2",
wb->data608->cursor_row,wb->data608->cursor_column); */
- use_buffer->characters[wb->data608->cursor_row][wb->data608->cursor_column]=c;
- use_buffer->colors[wb->data608->cursor_row][wb->data608->cursor_column]=wb->data608->color;
- use_buffer->fonts[wb->data608->cursor_row][wb->data608->cursor_column]=wb->data608->font;
- use_buffer->row_used[wb->data608->cursor_row]=1;
- use_buffer->empty=0;
- if (wb->data608->cursor_column<31)
+ use_buffer->characters[wb->data608->cursor_row][wb->data608->cursor_column] = c;
+ use_buffer->colors[wb->data608->cursor_row][wb->data608->cursor_column] = wb->data608->color;
+ use_buffer->fonts[wb->data608->cursor_row][wb->data608->cursor_column] = wb->data608->font;
+ use_buffer->row_used[wb->data608->cursor_row] = 1;
+ use_buffer->empty = 0;
+ if (wb->data608->cursor_column < 31)
wb->data608->cursor_column++;
}
}
/* Handle MID-ROW CODES. */
-void handle_text_attr (const unsigned char c1, const unsigned char c2, struct s_write *wb)
+static void handle_text_attr(const unsigned char c1, const unsigned char c2,
+ struct s_write *wb)
{
// Handle channel change
wb->data608->channel=wb->new_channel;
@@ -1389,56 +792,34 @@ void handle_text_attr (const unsigned char c1, const unsigned char c2, struct s_
wb->data608->color=pac2_attribs[i][0];
wb->data608->font=pac2_attribs[i][1];
if (debug_608)
- hb_log (" -- Color: %s, font: %s\n",
- color_text[wb->data608->color][0],
- font_text[wb->data608->font]);
+ hb_log(" -- Color: %s, font: %s\n",
+ color_text[wb->data608->color][0],
+ font_text[wb->data608->font]);
if (wb->data608->cursor_column<31)
wb->data608->cursor_column++;
}
}
-void mstotime (int64_t milli, unsigned *hours, unsigned *minutes,
- unsigned *seconds, unsigned *ms)
+static int write_cc_buffer_as_ssa(struct eia608_screen *data,
+ struct s_write *wb)
{
- // int64_t milli = (int64_t) ((ccblock*1000)/29.97);
- *ms=(unsigned) (milli%1000); // milliseconds
- milli=(milli-*ms)/1000; // Remainder, in seconds
- *seconds = (int) (milli%60);
- milli=(milli-*seconds)/60; // Remainder, in minutes
- *minutes = (int) (milli%60);
- milli=(milli-*minutes)/60; // Remainder, in hours
- *hours=(int) milli;
-}
-
-void fhb_log_encoded (FILE *fh, const char *string)
-{
- //GUARANTEE(wb, strlen (string)*3);
- //wb->enc_buffer_used=encode_line (wb->enc_buffer,(unsigned char *) string);
- //fwrite (wb->enc_buffer,wb->enc_buffer_used,1,fh);
-}
-
-int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_write *wb)
-{
- unsigned h1,m1,s1,ms1;
- unsigned h2,m2,s2,ms2;
int wrote_something = 0;
- int64_t ms_start= wb->data608->current_visible_start_ms;
int i;
+ int64_t ms_start = wb->data608->current_visible_start_ms;
+ //int64_t ms_end = get_last_pts(wb) + subs_delay;
+ int row = -1, col = -1;
- ms_start+=subs_delay;
+ ms_start += subs_delay;
if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;
- int64_t ms_end = get_fts(wb)+subs_delay;
- 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];
- wb->data608->srt_counter++;
- sprintf (timeline,"%u\r\n",wb->data608->srt_counter);
-
if (debug_608)
{
- hb_log ("\n- - - SRT caption - - -\n");
+ char timeline[128];
+ wb->data608->ssa_counter++;
+ sprintf (timeline,"%u\r\n",wb->data608->ssa_counter);
+
+ hb_log ("\n- - - SSA caption - - -\n");
hb_log ("%s", timeline);
}
@@ -1447,58 +828,122 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_write *wb)
* ensure that we only have two lines, insert a newline after the first one,
* and have a big bottom line (strip spaces from any joined lines).
*/
+ int rows = 0, columns = 0;
+ for (i = 0; i < 15; i++)
+ {
+ if (data->row_used[i])
+ {
+ int first, last;
+
+ rows++;
+ find_limit_characters(data->characters[i], &first, &last);
+ if (last - first + 1 > columns)
+ columns = last - first + 1;
+ }
+ }
+
wb->enc_buffer_used = 0;
int line = 1;
- for (i=0;i<15;i++)
+ for (i = 0; i < 15; i++)
{
if (data->row_used[i])
{
- if (sentence_cap)
+ // Get position for this CC
+ if (row == -1)
{
- capitalize(i,data, &wb->new_sentence);
- correct_case(i,data);
+ int last, x, y, safe_zone, cell_width, cell_height;
+ int cropped_width, cropped_height, font_size;
+ char *pos;
+
+ row = i;
+ find_limit_characters(data->characters[i], &col, &last);
+
+ // CC grid is 16 rows by 62 colums
+ // Our SSA resolution is the title resolution
+ // Tranlate CC grid to SSA coordinates
+ // The numbers are tweaked to keep things off the very
+ // edges of the screen and in the "safe" zone
+ cropped_height = wb->height - wb->crop[0] - wb->crop[1];
+ cropped_width = wb->width - wb->crop[2] - wb->crop[3];
+ font_size = cropped_height * .066;
+ safe_zone = wb->height * 0.025;
+ cell_height = (wb->height - 2 * safe_zone) / 16;
+ cell_width = (wb->width - 2 * safe_zone) / 32;
+
+ // Calculate position assuming the position defines
+ // the baseline of the text which is lower left corner
+ // of bottom row of characters
+ y = cell_height * (row + 1 + rows) + safe_zone - wb->crop[0];
+ x = cell_width * col + safe_zone - wb->crop[2];
+ if (y < 0)
+ y = (rows * font_size) + safe_zone;
+ if (x < 0)
+ x = safe_zone;
+ if (y > cropped_height)
+ y = cropped_height - safe_zone;
+ if (x + columns * cell_width > cropped_width)
+ x = cropped_width - columns * cell_width - safe_zone;
+ pos = hb_strdup_printf("{\\a1\\pos(%d,%d)}", x, y);
+ wb->enc_buffer_used += encode_line(
+ wb->enc_buffer + wb->enc_buffer_used, (uint8_t*)pos);
+ free(pos);
}
+
/*
- * The intention was to use a newline but QT doesn't like it, old code still
- * here just in case..
+ * The intention was to use a newline but QT doesn't like it,
+ * old code still here just in case..
*/
if (line == 1) {
- wb->enc_buffer_used = get_decoder_line_encoded(wb->enc_buffer, i, data);
+ wb->enc_buffer_used += get_decoder_line_encoded(
+ wb->enc_buffer + wb->enc_buffer_used, i, data);
line = 2;
} else {
- wb->enc_buffer_used += encode_line(wb->enc_buffer+wb->enc_buffer_used,
- (unsigned char *) "\n");
- wb->enc_buffer_used += get_decoder_line_encoded(wb->enc_buffer+wb->enc_buffer_used, i, data);
+ wb->enc_buffer_used += encode_line(
+ wb->enc_buffer + wb->enc_buffer_used, (uint8_t*)"\\N");
+ wb->enc_buffer_used += get_decoder_line_encoded(
+ wb->enc_buffer + wb->enc_buffer_used, i, data);
}
}
}
- if (wb->enc_buffer_used)
+ if (wb->enc_buffer_used && wb->enc_buffer[0] != 0)
{
- hb_buffer_t *buffer = hb_buffer_init( wb->enc_buffer_used + 1 );
+ hb_buffer_t *buffer;
+ int len;
+
+ // bump past null terminator
+ wb->enc_buffer_used++;
+ buffer = hb_buffer_init(wb->enc_buffer_used + SSA_PREAMBLE_LEN);
buffer->s.frametype = HB_FRAME_SUBTITLE;
buffer->s.start = ms_start;
buffer->s.stop = AV_NOPTS_VALUE;
- memcpy( buffer->data, wb->enc_buffer, wb->enc_buffer_used + 1 );
- if (wb->hb_last_buffer) {
+ sprintf((char*)buffer->data, "%d,,Default,,0,0,0,,", ++wb->line);
+ len = strlen((char*)buffer->data);
+ memcpy(buffer->data + len, wb->enc_buffer, wb->enc_buffer_used);
+ if (wb->hb_last_buffer)
+ {
wb->hb_last_buffer->next = buffer;
- } else {
+ }
+ else
+ {
wb->hb_buffer = buffer;
}
wb->hb_last_buffer = buffer;
-
wrote_something=1;
wb->clear_sub_needed = 1;
}
else if (wb->clear_sub_needed)
{
- hb_buffer_t *buffer = hb_buffer_init( 1 );
+ hb_buffer_t *buffer = hb_buffer_init(1);
buffer->s.frametype = HB_FRAME_SUBTITLE;
buffer->s.start = ms_start;
buffer->s.stop = ms_start;
buffer->data[0] = 0;
- if (wb->hb_last_buffer != NULL) {
+ if (wb->hb_last_buffer != NULL)
+ {
wb->hb_last_buffer->next = buffer;
- } else {
+ }
+ else
+ {
wb->hb_buffer = buffer;
}
wb->hb_last_buffer = buffer;
@@ -1511,18 +956,18 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct s_write *wb)
return wrote_something;
}
-int write_cc_buffer(struct s_write *wb)
+static int write_cc_buffer(struct s_write *wb)
{
struct eia608_screen *data;
int wrote_something=0;
data = get_current_visible_buffer(wb);
wb->new_sentence=1;
- wrote_something = write_cc_buffer_as_srt (data, wb);
+ wrote_something = write_cc_buffer_as_ssa(data, wb);
return wrote_something;
}
-void roll_up(struct s_write *wb)
+static void roll_up(struct s_write *wb)
{
struct eia608_screen *use_buffer;
int i, j;
@@ -1532,29 +977,29 @@ void roll_up(struct s_write *wb)
switch (wb->data608->mode)
{
case MODE_ROLLUP_2:
- keep_lines=2;
+ keep_lines = 2;
break;
case MODE_ROLLUP_3:
- keep_lines=3;
+ keep_lines = 3;
break;
case MODE_ROLLUP_4:
- keep_lines=4;
+ keep_lines = 4;
break;
default: // Shouldn't happen
- keep_lines=0;
+ keep_lines = 0;
break;
}
- int firstrow=-1, lastrow=-1;
+ int firstrow = -1, lastrow = -1;
// Look for the last line used
- int rows_now=0; // Number of rows in use right now
- for (i=0;i<15;i++)
+ int rows_now = 0; // Number of rows in use right now
+ for (i = 0; i < 15; i++)
{
if (use_buffer->row_used[i])
{
rows_now++;
- if (firstrow==-1)
- firstrow=i;
- lastrow=i;
+ if (firstrow == -1)
+ firstrow = i;
+ lastrow = i;
}
}
@@ -1564,37 +1009,37 @@ void roll_up(struct s_write *wb)
if (lastrow==-1) // Empty screen, nothing to rollup
return;
- for (j=lastrow-keep_lines+1;j<lastrow; j++)
+ for (j = lastrow - keep_lines + 1; j < lastrow; j++)
{
- if (j>=0)
+ if (j >= 0)
{
- memcpy (use_buffer->characters[j],use_buffer->characters[j+1],CC608_SCREEN_WIDTH+1);
- memcpy (use_buffer->colors[j],use_buffer->colors[j+1],CC608_SCREEN_WIDTH+1);
- memcpy (use_buffer->fonts[j],use_buffer->fonts[j+1],CC608_SCREEN_WIDTH+1);
- use_buffer->row_used[j]=use_buffer->row_used[j+1];
+ memcpy(use_buffer->characters[j], use_buffer->characters[j+1], CC608_SCREEN_WIDTH+1);
+ memcpy(use_buffer->colors[j], use_buffer->colors[j+1], CC608_SCREEN_WIDTH+1);
+ memcpy(use_buffer->fonts[j], use_buffer->fonts[j+1], CC608_SCREEN_WIDTH+1);
+ use_buffer->row_used[j] = use_buffer->row_used[j+1];
}
}
- for (j=0;j<(1+wb->data608->cursor_row-keep_lines);j++)
+ for (j = 0; j < (1 + wb->data608->cursor_row - keep_lines); j++)
{
- memset(use_buffer->characters[j],' ',CC608_SCREEN_WIDTH);
- memset(use_buffer->colors[j],COL_WHITE,CC608_SCREEN_WIDTH);
- memset(use_buffer->fonts[j],FONT_REGULAR,CC608_SCREEN_WIDTH);
- use_buffer->characters[j][CC608_SCREEN_WIDTH]=0;
- use_buffer->row_used[j]=0;
+ memset(use_buffer->characters[j], ' ', CC608_SCREEN_WIDTH);
+ memset(use_buffer->colors[j], COL_WHITE, CC608_SCREEN_WIDTH);
+ memset(use_buffer->fonts[j], FONT_REGULAR, CC608_SCREEN_WIDTH);
+ use_buffer->characters[j][CC608_SCREEN_WIDTH] = 0;
+ use_buffer->row_used[j] = 0;
}
- memset(use_buffer->characters[lastrow],' ',CC608_SCREEN_WIDTH);
- memset(use_buffer->colors[lastrow],COL_WHITE,CC608_SCREEN_WIDTH);
- memset(use_buffer->fonts[lastrow],FONT_REGULAR,CC608_SCREEN_WIDTH);
+ memset(use_buffer->characters[lastrow], ' ', CC608_SCREEN_WIDTH);
+ memset(use_buffer->colors[lastrow], COL_WHITE, CC608_SCREEN_WIDTH);
+ memset(use_buffer->fonts[lastrow], FONT_REGULAR, CC608_SCREEN_WIDTH);
- use_buffer->characters[lastrow][CC608_SCREEN_WIDTH]=0;
- use_buffer->row_used[lastrow]=0;
+ use_buffer->characters[lastrow][CC608_SCREEN_WIDTH] = 0;
+ use_buffer->row_used[lastrow] = 0;
// Sanity check
- rows_now=0;
- for (i=0;i<15;i++)
+ rows_now = 0;
+ for (i = 0; i < 15; i++)
if (use_buffer->row_used[i])
rows_now++;
- if (rows_now>keep_lines)
+ if (rows_now > keep_lines)
hb_log ("Bug in roll_up, should have %d lines but I have %d.\n",
keep_lines, rows_now);
}
@@ -1613,7 +1058,7 @@ void erase_memory (struct s_write *wb, int displayed)
clear_eia608_cc_buffer (buf);
}
-int is_current_row_empty (struct s_write *wb)
+static int is_current_row_empty (struct s_write *wb)
{
struct eia608_screen *use_buffer;
int i;
@@ -1628,7 +1073,8 @@ int is_current_row_empty (struct s_write *wb)
}
/* Process GLOBAL CODES */
-void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct s_write *wb)
+static void handle_command(unsigned char c1, const unsigned char c2,
+ struct s_write *wb)
{
// Handle channel change
wb->data608->channel=wb->new_channel;
@@ -1674,7 +1120,7 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
if (wb->data608->cursor_column>0)
{
wb->data608->cursor_column--;
- get_writing_buffer(wb)->characters[wb->data608->cursor_row][wb->data608->cursor_column]=' ';
+ get_writing_buffer(wb)->characters[wb->data608->cursor_row][wb->data608->cursor_column] = ' ';
}
break;
case COM_TABOFFSET1:
@@ -1693,11 +1139,11 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
break;
case COM_RESUMECAPTIONLOADING:
wb->data608->mode=MODE_POPUP;
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
break;
case COM_RESUMETEXTDISPLAY:
wb->data608->mode=MODE_TEXT;
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
break;
case COM_ROLLUP2:
if (wb->data608->mode==MODE_POPUP)
@@ -1714,11 +1160,11 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
handle_command(0x14, 0x2D, wb);
wb->rollup_cr = 1;
}
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
wb->data608->mode=MODE_ROLLUP_2;
erase_memory (wb, 0);
- wb->data608->cursor_column=0;
- wb->data608->cursor_row=wb->data608->rollup_base_row;
+ wb->data608->cursor_column = 0;
+ wb->data608->cursor_row = wb->data608->rollup_base_row;
break;
case COM_ROLLUP3:
if (wb->data608->mode==MODE_POPUP)
@@ -1734,11 +1180,11 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
handle_command(0x14, 0x2D, wb);
wb->rollup_cr = 1;
}
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
wb->data608->mode=MODE_ROLLUP_3;
erase_memory (wb, 0);
- wb->data608->cursor_column=0;
- wb->data608->cursor_row=wb->data608->rollup_base_row;
+ wb->data608->cursor_column = 0;
+ wb->data608->cursor_row = wb->data608->rollup_base_row;
break;
case COM_ROLLUP4:
if (wb->data608->mode==MODE_POPUP)
@@ -1754,10 +1200,10 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
handle_command(0x14, 0x2D, wb);
wb->rollup_cr = 1;
}
- wb->data608->current_visible_start_ms = get_fts(wb);
- wb->data608->mode=MODE_ROLLUP_4;
- wb->data608->cursor_column=0;
- wb->data608->cursor_row=wb->data608->rollup_base_row;
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
+ wb->data608->mode = MODE_ROLLUP_4;
+ wb->data608->cursor_column = 0;
+ wb->data608->cursor_row = wb->data608->rollup_base_row;
erase_memory (wb, 0);
break;
case COM_CARRIAGERETURN:
@@ -1768,17 +1214,16 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
if (wb->rollup_cr && is_current_row_empty(wb))
{
wb->rollup_cr = 0;
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
break;
}
-
if (norollup)
delete_all_lines_but_current(get_current_visible_buffer(wb), wb->data608->cursor_row);
if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
roll_up(wb);
- wb->data608->cursor_column=0;
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->cursor_column = 0;
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
break;
case COM_ERASENONDISPLAYEDMEMORY:
erase_memory (wb,0);
@@ -1791,7 +1236,7 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
{
// If popup, the last pts is the time to remove the
// popup from the screen
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
}
// Write "clear" subtitle if necessary
write_cc_buffer(wb);
@@ -1802,15 +1247,15 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
if (wb->data608->mode == MODE_POPUP)
{
swap_visible_buffer(wb);
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
}
if (write_cc_buffer(wb))
wb->data608->screenfuls_counter++;
if (wb->data608->mode != MODE_POPUP)
swap_visible_buffer(wb);
- wb->data608->cursor_column=0;
- wb->data608->cursor_row=0;
+ wb->data608->cursor_column = 0;
+ wb->data608->cursor_row = 0;
wb->data608->color=default_color;
wb->data608->font=FONT_REGULAR;
break;
@@ -1823,14 +1268,15 @@ void handle_command (/*const */ unsigned char c1, const unsigned char c2, struct
}
}
-void handle_end_of_data (struct s_write *wb)
+static void handle_end_of_data(struct s_write *wb)
{
// We issue a EraseDisplayedMemory here so if there's any captions pending
// they get written to file.
handle_command (0x14, 0x2c, wb); // EDM
}
-void handle_double (const unsigned char c1, const unsigned char c2, struct s_write *wb)
+static void handle_double(const unsigned char c1, const unsigned char c2,
+ struct s_write *wb)
{
unsigned char c;
if (wb->data608->channel!=cc_channel)
@@ -1845,7 +1291,8 @@ void handle_double (const unsigned char c1, const unsigned char c2, struct s_wri
}
/* Process EXTENDED CHARACTERS */
-unsigned char handle_extended (unsigned char hi, unsigned char lo, struct s_write *wb)
+static unsigned char handle_extended(unsigned char hi, unsigned char lo,
+ struct s_write *wb)
{
// Handle channel change
if (wb->new_channel > 2)
@@ -1886,7 +1333,7 @@ unsigned char handle_extended (unsigned char hi, unsigned char lo, struct s_writ
}
/* Process PREAMBLE ACCESS CODES (PAC) */
-void handle_pac (unsigned char c1, unsigned char c2, struct s_write *wb)
+static void handle_pac(unsigned char c1, unsigned char c2, struct s_write *wb)
{
// Handle channel change
if (wb->new_channel > 2)
@@ -1926,19 +1373,19 @@ void handle_pac (unsigned char c1, unsigned char c2, struct s_write *wb)
int indent=pac2_attribs[c2][2];
if (debug_608)
hb_log (" -- Position: %d:%d, color: %s, font: %s\n",row,
- indent,color_text[color][0],font_text[font]);
- if (wb->data608->mode!=MODE_TEXT)
+ indent,color_text[color][0],font_text[font]);
+ if (wb->data608->mode != MODE_TEXT)
{
// According to Robson, row info is discarded in text mode
// but column is accepted
- wb->data608->cursor_row=row-1 ; // Since the array is 0 based
+ wb->data608->cursor_row = row - 1 ; // Since the array is 0 based
}
- wb->data608->rollup_base_row=row-1;
- wb->data608->cursor_column=indent;
+ wb->data608->rollup_base_row = row - 1;
+ wb->data608->cursor_column = indent;
}
-void handle_single (const unsigned char c1, struct s_write *wb)
+static void handle_single(const unsigned char c1, struct s_write *wb)
{
if (c1<0x20 || wb->data608->channel!=cc_channel)
return; // We don't allow special stuff here
@@ -1950,7 +1397,7 @@ void handle_single (const unsigned char c1, struct s_write *wb)
write_char (c1,wb);
}
-int check_channel (unsigned char c1, struct s_write *wb)
+static int check_channel(unsigned char c1, struct s_write *wb)
{
if (c1==0x14)
{
@@ -1984,7 +1431,7 @@ int check_channel (unsigned char c1, struct s_write *wb)
/* Handle Command, special char or attribute and also check for
* channel changes.
* Returns 1 if something was written to screen, 0 otherwise */
-int disCommand (unsigned char hi, unsigned char lo, struct s_write *wb)
+static int disCommand(unsigned char hi, unsigned char lo, struct s_write *wb)
{
int wrote_to_screen=0;
@@ -2050,7 +1497,8 @@ int disCommand (unsigned char hi, unsigned char lo, struct s_write *wb)
return wrote_to_screen;
}
-void process608 (const unsigned char *data, int length, struct s_write *wb)
+static void process608(const unsigned char *data, int length,
+ struct s_write *wb)
{
static int textprinted = 0;
int i;
@@ -2125,7 +1573,7 @@ void process608 (const unsigned char *data, int length, struct s_write *wb)
if ( debug_608 && !textprinted && wb->data608->channel==cc_channel )
{ // Current FTS information after the characters are shown
- //hb_log("Current FTS: %s\n", print_mstime(get_fts()));
+ //hb_log("Current FTS: %s\n", print_mstime(get_last_pts()));
}
if (wrote_to_screen && direct_rollup && // If direct_rollup is enabled and
@@ -2135,55 +1583,19 @@ void process608 (const unsigned char *data, int length, struct s_write *wb)
{
// We don't increase screenfuls_counter here.
write_cc_buffer(wb);
- wb->data608->current_visible_start_ms = get_fts(wb);
+ wb->data608->current_visible_start_ms = get_last_pts(wb);
}
}
}
}
-
-/* Return a pointer to a string that holds the printable characters
- * of the caption data block. FOR DEBUG PURPOSES ONLY! */
-unsigned char *debug_608toASC (unsigned char *cc_data, int channel)
-{
- static unsigned char output[3];
-
- unsigned char cc_valid = (cc_data[0] & 4) >>2;
- unsigned char cc_type = cc_data[0] & 3;
- unsigned char hi, lo;
-
- output[0]=' ';
- output[1]=' ';
- output[2]='\x00';
-
- if (cc_valid && cc_type==channel)
- {
- hi = cc_data[1] & 0x7F; // Get rid of parity bit
- lo = cc_data[2] & 0x7F; // Get rid of parity bit
- if (hi>=0x20)
- {
- output[0]=hi;
- output[1]=(lo>=20 ? lo : '.');
- output[2]='\x00';
- }
- else
- {
- output[0]='<';
- output[1]='>';
- output[2]='\x00';
- }
- }
- return output;
-}
-
-
struct hb_work_private_s
{
hb_job_t * job;
struct s_write * cc608;
};
-int decccInit( hb_work_object_t * w, hb_job_t * job )
+static int decccInit( hb_work_object_t * w, hb_job_t * job )
{
int retval = 1;
hb_work_private_t * pv;
@@ -2199,6 +1611,9 @@ int decccInit( hb_work_object_t * w, hb_job_t * job )
if( pv->cc608 )
{
+ pv->cc608->width = job->title->width;
+ pv->cc608->height = job->title->height;
+ memcpy(pv->cc608->crop, job->crop, sizeof(int[4]));
retval = general_608_init(pv->cc608);
if( !retval )
{
@@ -2211,10 +1626,17 @@ int decccInit( hb_work_object_t * w, hb_job_t * job )
}
}
}
+ if (!retval)
+ {
+ // Generate generic SSA Script Info.
+ int height = job->title->height - job->crop[0] - job->crop[1];
+ int width = job->title->width - job->crop[2] - job->crop[3];
+ hb_subtitle_add_ssa_header(w->subtitle, width, height);
+ }
return retval;
}
-int decccWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+static int decccWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
hb_work_private_t * pv = w->private_data;
@@ -2254,7 +1676,7 @@ int decccWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
return HB_WORK_OK;
}
-void decccClose( hb_work_object_t * w )
+static void decccClose( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
general_608_close( pv->cc608 );