41 #include <sys/types.h> 45 #define LOG_MODULE "demux_sputext" 51 #define ERR ((void *)-1) 53 #define LINE_LEN_QUOT "1000" 59 #define FORMAT_UNKNOWN (-1) 60 #define FORMAT_MICRODVD 0 61 #define FORMAT_SUBRIP 1 62 #define FORMAT_SUBVIEWER 2 64 #define FORMAT_VPLAYER 4 68 #define FORMAT_MPSUB 8 69 #define FORMAT_AQTITLE 9 70 #define FORMAT_JACOBSUB 10 71 #define FORMAT_SUBVIEWER2 11 72 #define FORMAT_SUBRIP09 12 73 #define FORMAT_MPL2 13 75 static int eol(
char p) {
76 return (p==
'\r' || p==
'\n' || p==
'\0');
89 while (i > 0 && isspace(s[i]))
106 nread = len - demuxstr->
buflen;
110 printf(
"read failed.\n");
122 demuxstr->
buflen += nread;
125 s = strchr(demuxstr->
buf,
'\n');
127 if (line && (s || demuxstr->
buflen)) {
129 linelen = s ? (s - demuxstr->
buf) + 1 : demuxstr->
buflen;
131 memcpy(line, demuxstr->
buf, linelen);
132 line[linelen] =
'\0';
135 demuxstr->
buflen -= linelen;
147 static char *s =
nullptr;
164 s = strstr (s,
"Start=");
166 current->start = strtol (s + 6, &s, 0) / 10;
172 if ((s = strstr (s,
"<P"))) { s += 2; state = 2;
continue; }
176 if ((s = strchr (s,
'>'))) { s++; state = 3; p = text;
continue; }
180 if (*s ==
'\0') {
break; }
181 else if (*s ==
'<') { state = 4; }
182 else if (!strncasecmp (s,
" ", 6)) { *p++ =
' '; s += 6; }
183 else if (*s ==
'\r') { s++; }
184 else if (!strncasecmp (s,
"<br>", 4) || *s ==
'\n') {
188 if (*s ==
'\n') s++;
else s += 4;
194 q = strstr (s,
"Start=");
196 current->end = strtol (q + 6, &q, 0) / 10 - 1;
200 if (
current->lines > 0) { state = 99;
break; }
204 if (s) { s++; state = 3;
continue; }
212 }
while (state != 99);
222 while ( !
eol(*p) && *p!=
'|' ) {
229 *
dest= (
char *)malloc (len+1);
233 strncpy(*
dest, source, len);
236 while (*p==
'\r' || *p==
'\n' || *p==
'|')
240 else return (
char*)
nullptr;
266 printf (
"Too many lines in a subtitle\n");
279 int a1,a2,a3,a4,b1,b2,b3,b4;
280 char *p=
nullptr, *q=
nullptr;
287 if (sscanf (line,
"%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) {
288 if (sscanf (line,
"%d:%d:%d,%d,%d:%d:%d,%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8)
291 current->start = a1*360000+a2*6000+a3*100+a4;
292 current->end = b1*360000+b2*6000+b3*100+b4;
299 for (q=p,len=0; *p && *p!=
'\r' && *p!=
'\n' && *p!=
'|' &&
300 (strncasecmp(p,
"[br]",4) != 0); p++,len++);
305 if (!*p || *p==
'\r' || *p==
'\n')
break;
306 if (*p==
'[')
while (*p++!=
']');
317 int a1,a2,a3,a4,b1,b2,b3,b4;
324 i = sscanf(line,
"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4);
326 current->start = a1*360000+a2*6000+a3*100+a4/10;
327 current->end = b1*360000+b2*6000+b3*100+b4/10;
344 if(*(p+1)==
'N' || *(p+1)==
'n') {
345 temp_line[temp_index++]=
'\0';
348 temp_line[temp_index++]=*p;
352 if(!strncmp(p,
"{\\i1}",5) && temp_index+3<
SUB_BUFSIZE) {
353 temp_line[temp_index++]=
'<';
354 temp_line[temp_index++]=
'i';
355 temp_line[temp_index++]=
'>';
357 if(!strncmp(p,
"{\\i1}",5)) {
362 else if(!strncmp(p,
"{\\i0}",5) && temp_index+4<
SUB_BUFSIZE) {
363 temp_line[temp_index++]=
'<';
364 temp_line[temp_index++]=
'/';
365 temp_line[temp_index++]=
'i';
366 temp_line[temp_index++]=
'>';
368 else if(!strncmp(p,
"{\\i0}",5)) {
373 temp_line[temp_index++]=*p;
378 temp_line[temp_index++]=
'\0';
381 temp_line[temp_index++]=*p;
386 printf(
"Too many characters in a subtitle line\n");
387 if(temp_line[temp_index-1]==
'\0' || temp_index==
SUB_BUFSIZE) {
389 current->text[i]=(
char *)malloc(temp_index);
392 strncpy(
current->text[i],temp_line,temp_index);
402 printf(
"Too many lines in a subtitle\n");
409 int a1,a2,a3,b1,b2,b3;
410 char *p=
nullptr, *
next, *
p2;
429 if( (sscanf( line,
"%d:%d:%d:", &a1, &a2, &a3) < 3) ||
430 (sscanf( demuxstr->
next_line,
"%d:%d:%d:", &b1, &b2, &b3) < 3) )
432 current->start = a1*360000+a2*6000+a3*100;
433 current->end = b1*360000+b2*6000+b3*100;
441 if(
p2 ==
nullptr )
break;
452 printf(
"Too many lines in a subtitle\n");
469 int a1,a2,a3,a4,b1,b2,b3,b4;
470 char *p=
nullptr,*
next=
nullptr;
481 if ((len=sscanf (line,
"<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8)
483 plen=a1=a2=a3=a4=b1=b2=b3=b4=0;
485 ((len=sscanf (line,
"<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&plen)) < 4) &&
486 ((len=sscanf (line,
"<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&b4,&plen)) < 5) &&
488 ((len=sscanf (line,
"<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&b4,&plen)) < 6) &&
489 ((len=sscanf (line,
"<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\" %*[Ee]nd=\"%d:%d:%d.%d\"%*[^<]<clear/>%n",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4,&plen)) < 8)
492 current->start = a1*360000+a2*6000+a3*100+a4/10;
493 current->end = b1*360000+b2*6000+b3*100+b4/10;
496 next = strstr(line,
"<clear/>")+8;i=0;
502 printf(
"Too many lines in a subtitle\n");
514 static int max_comma = 32;
517 int hour1, min1, sec1, hunsec1, hour2, min2, sec2, hunsec2, nothing;
524 }
while (sscanf (line,
"Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d," 526 &hour1, &min1, &sec1, &hunsec1,
527 &hour2, &min2, &sec2, &hunsec2,
530 sscanf (line,
"Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d," 532 &hour1, &min1, &sec1, &hunsec1,
533 &hour2, &min2, &sec2, &hunsec2,
536 line2=strchr(line3,
',');
540 for (comma = 4; comma < max_comma; comma ++)
543 if(!(
tmp=strchr(++
tmp,
',')))
break;
544 if(*(++
tmp) ==
' ')
break;
549 if(comma < max_comma)max_comma = comma;
551 if(*line2 ==
',') line2++;
554 current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1;
555 current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2;
557 while (((
tmp=strstr(line2,
"\\n")) !=
nullptr) || ((
tmp=strstr(line2,
"\\N")) !=
nullptr) ){
558 current->text[num]=(
char *)malloc(
tmp-line2+1);
559 strncpy (
current->text[num], line2,
tmp-line2);
567 current->text[num]=strdup(line2);
593 for (s = line; *s && isspace(*s); s++);
596 if (sscanf (line,
"%ld,%ld,", &(
current->start),
604 for (; *s; s++)
if (*s==
',')
break;
606 for (s++; *s; s++)
if (*s==
',')
break;
613 for (s++,
d=text; *s && *s!=
'"'; s++,
d++)
616 current->text[0] = strdup(text);
631 }
while (sscanf (line,
"%f %f", &a, &
b) !=2);
646 if (
eol(*p) && num > 0)
652 for (q=p; !
eol(*q); q++);
678 if (!(sscanf (line,
"-->> %ld", &(
current->start)) <1))
704 unsigned a1, a2, a3, a4, b1, b2, b3, b4, comment = 0;
705 static unsigned jacoTimeres = 30;
706 static int jacoShift = 0;
717 (line1,
"%u:%u:%u.%u %u:%u:%u.%u %" LINE_LEN_QUOT "[^\n\r]", &a1, &a2, &a3, &a4,
718 &b1, &b2, &b3, &b4, line2) < 9) {
719 if (sscanf(line1,
"@%u @%u %" LINE_LEN_QUOT "[^\n\r]", &a4, &b4, line2) < 3) {
720 if (line1[0] ==
'#') {
721 int hours = 0, minutes = 0, seconds, delta, inverter =
723 unsigned units = jacoShift;
724 switch (toupper(line1[1])) {
726 if (isalpha(line1[2])) {
731 if (sscanf(&line1[delta],
"%d", &hours)) {
736 if (sscanf(&line1[delta],
"%*d:%d", &minutes)) {
738 (&line1[delta],
"%*d:%*d:%d",
740 sscanf(&line1[delta],
"%*d:%*d:%*d.%u",
744 sscanf(&line1[delta],
"%d:%d.%u",
745 &minutes, &seconds, &units);
750 sscanf(&line1[delta],
"%d.%u", &seconds,
755 ((hours * 3600 + minutes * 60 +
756 seconds) * jacoTimeres +
761 if (isalpha(line1[2])) {
766 sscanf(&line1[delta],
"%u", &jacoTimeres);
773 (
unsigned long) ((a4 + jacoShift) * 100.0 /
776 (
unsigned long) ((b4 + jacoShift) * 100.0 /
782 long) (((a1 * 3600 + a2 * 60 + a3) * jacoTimeres + a4 +
783 jacoShift) * 100.0 / jacoTimeres);
786 long) (((b1 * 3600 + b2 * 60 + b3) * jacoTimeres + b4 +
787 jacoShift) * 100.0 / jacoTimeres);
791 while ((*p ==
' ') || (*p ==
'\t')) {
794 if (isalpha(*p)||*p ==
'[') {
799 jLength = strlen(directive);
800 for (cont = 0; cont < jLength; ++cont) {
801 if (isalpha(*(directive + cont)))
802 *(directive + cont) = toupper(*(directive + cont));
804 if ((strstr(directive,
"RDB") !=
nullptr)
805 || (strstr(directive,
"RDC") !=
nullptr)
806 || (strstr(directive,
"RLB") !=
nullptr)
807 || (strstr(directive,
"RLG") !=
nullptr)) {
812 if (strstr(directive,
"JL") !=
nullptr) {
813 current->alignment = SUB_ALIGNMENT_HLEFT;
814 }
else if (strstr(directive,
"JR") !=
nullptr) {
815 current->alignment = SUB_ALIGNMENT_HRIGHT;
817 current->alignment = SUB_ALIGNMENT_HCENTER;
820 strcpy(line2, line1);
832 if ((*(p + 1)) ==
' ')
844 if ((*(p + 1) ==
' ') || (*(p + 1) ==
'\t'))
852 if (*(p + 1) ==
'n') {
859 if ((toupper(*(p + 1)) ==
'C')
860 || (toupper(*(p + 1)) ==
'F')) {
864 if ((*(p + 1) ==
'B') || (*(p + 1) ==
'b') ||
867 (*(p + 1) ==
'I') || (*(p + 1) ==
'i') ||
871 (*(p + 1) ==
'U') || (*(p + 1) ==
'u')) {
875 if ((*(p + 1) ==
'\\') ||
876 (*(p + 1) ==
'~') || (*(p + 1) ==
'{')) {
878 }
else if (
eol(*(p + 1))) {
882 strncat(line2, directive,
901 printf (
"Too many lines in a subtitle\n");
917 if ((len=sscanf (line,
"{T %d:%d:%d:%d",&a1,&a2,&a3,&a4)) < 4)
919 current->start = a1*360000+a2*6000+a3*100+a4/10;
922 if (line[0]==
'}')
break;
924 for (p=line; *p!=
'\n' && *p!=
'\r' && *p; ++p,++len);
926 current->text[i]=(
char *)malloc (len+1);
928 strncpy (
current->text[i], line, len);
current->text[i][len]=
'\0';
949 }
while (sscanf (line,
"[%d:%d:%d]", &h, &m, &s) != 3);
953 current->start = 360000 * h + 6000 * m + 100 * s;
962 printf(
"Too many lines in a subtitle\n");
985 }
while ((sscanf (line,
997 printf(
"Too many lines in a subtitle\n");
1019 if ((sscanf (line,
"{%d}{}", &i)==1) ||
1020 (sscanf (line,
"{%d}{%d}", &i, &i)==2)) {
1025 if (sscanf (line,
"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d", &i, &i, &i, &i, &i, &i, &i, &i)==8) {
1030 if (sscanf (line,
"%d:%d:%d.%d,%d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i)==8){
1035 if (sscanf (line,
"%d:%d:%d,%d,%d:%d:%d,%d", &i, &i, &i, &i, &i, &i, &i, &i)==8){
1040 if (strstr (line,
"<SAMI>")) {
1044 if (sscanf (line,
"%d:%d:%d:", &i, &i, &i )==3) {
1052 if ( !strcasecmp(line,
"<window") ) {
1056 if ((!memcmp(line,
"Dialogue: Marked", 16)) || (!memcmp(line,
"Dialogue: ", 10))) {
1060 if (sscanf (line,
"%d,%d,\"%c", &i, &i, (
char *) &i) == 3) {
1064 if (sscanf (line,
"FORMAT=%d", &i) == 1) {
1068 if (sscanf (line,
"FORMAT=TIM%c", &p)==1 && p==
'E') {
1072 if (strstr (line,
"-->>")) {
1076 if (sscanf(line,
"@%d @%d", &i, &i) == 2 ||
1077 sscanf(line,
"%d:%d:%d.%d %d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i) == 8) {
1081 if (sscanf(line,
"{T %d:%d:%d:%d",&i, &i, &i, &i) == 4) {
1085 if (sscanf(line,
"[%d:%d:%d]", &i, &i, &i) == 3) {
1090 if (sscanf (line,
"[%d][%d]", &i, &i) == 2) {
1138 demuxstr->
num=0;n_max=32;
1140 if(!first)
return nullptr;
1149 if(demuxstr->
num>=n_max){
1152 if (new_first ==
nullptr) {
1159 sub = func[demuxstr->
format] (demuxstr, &first[demuxstr->num]);
1164 demuxstr->emptyReads = 0;
1170 if (demuxstr->num > 0 && first[demuxstr->num-1].
end == -1) {
1175 first[demuxstr->num-1].
end = sub->
start;
1180 first[demuxstr->num-1].
end = sub->
start;
1187 if (demuxstr->
num > 0 && first[demuxstr->
num-1].
end == -1)
1192 #ifdef DEBUG_XINE_DEMUX_SPUTEXT 1196 sprintf(buffer,
"Read %i subtitles", demuxstr->
num);
1199 sprintf(buffer + strlen(buffer),
", %i bad line(s).\n", demuxstr->
errs);
1201 strcat(buffer,
"\n");
1203 printf(
"%s", buffer);
static subtitle_t * sub_read_line_subviewer2(demux_sputext_t *demuxstr, subtitle_t *current)
long end
Ending time in msec or starting frame.
static subtitle_t * sub_read_line_microdvd(demux_sputext_t *demuxstr, subtitle_t *current)
subtitle_t * sub_read_file(demux_sputext_t *demuxstr)
#define FORMAT_SUBVIEWER2
static subtitle_t * sub_read_line_subrip(demux_sputext_t *demuxstr, subtitle_t *current)
long long copy(QFile &dst, QFile &src, uint block_size)
Copies src file to dst file.
static subtitle_t * sub_read_line_vplayer(demux_sputext_t *demuxstr, subtitle_t *current)
static subtitle_t * sub_read_line_sami(demux_sputext_t *demuxstr, subtitle_t *current)
static subtitle_t * sub_read_line_jacobsub(demux_sputext_t *demuxstr, subtitle_t *current)
static const uint16_t * d
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
static subtitle_t * sub_read_line_subrip09(demux_sputext_t *demuxstr, subtitle_t *current)
static char * read_line_from_input(demux_sputext_t *demuxstr, char *line, off_t len)
static int sub_autodetect(demux_sputext_t *demuxstr)
static subtitle_t * sub_read_line_rt(demux_sputext_t *demuxstr, subtitle_t *current)
PictureAttribute next(PictureAttributeSupported supported, PictureAttribute attribute)
static subtitle_t * sub_read_line_mpl2(demux_sputext_t *demuxstr, subtitle_t *current)
static subtitle_t * sub_read_line_ssa(demux_sputext_t *demuxstr, subtitle_t *current)
static subtitle_t * sub_read_line_pjs(demux_sputext_t *demuxstr, subtitle_t *current)
static char * sub_readtext(char *source, char **dest)
static subtitle_t * sub_read_line_subviewer(demux_sputext_t *demuxstr, subtitle_t *current)
static subtitle_t * sub_read_line_aqt(demux_sputext_t *demuxstr, subtitle_t *current)
static void trail_space(char *s)
static subtitle_t * sub_read_line_mpsub(demux_sputext_t *demuxstr, subtitle_t *current)
long start
Starting time in msec or starting frame.
char next_line[SUB_BUFSIZE]