📄 subreader.c
字号:
// next = p,i=0; while ((next =sub_readtext (next, &(current->text[i])))) { if (current->text[i]==ERR) {return ERR;} i++; if (i>=SUB_MAX_TEXT) { mp_msg(MSGT_SUBREADER,MSGL_WARN,"Too many lines in a subtitle\n");current->lines=i;return current;} } current->lines=i+1; } } return current;}subtitle *sub_read_line_rt(FILE *fd,subtitle *current) { //TODO: This format uses quite rich (sub/super)set of xhtml // I couldn't check it since DTD is not included. // WARNING: full XML parses can be required for proper parsing char line[LINE_LEN+1]; int a1,a2,a3,a4,b1,b2,b3,b4; char *p=NULL,*next=NULL; int i,len,plen; while (!current->text[0]) { if (!fgets (line, LINE_LEN, fd)) return NULL; //TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0 //to describe the same moment in time. Maybe there are even more formats in use. //if ((len=sscanf (line, "<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8) plen=a1=a2=a3=a4=b1=b2=b3=b4=0; if ( ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d.%d\" %*[Ee]nd=\"%d.%d\"%*[^<]<clear/>%n",&a3,&a4,&b3,&b4,&plen)) < 4) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a3,&a4,&b2,&b3,&b4,&plen)) < 5) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&plen)) < 4) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&b4,&plen)) < 5) &&// ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&plen)) < 5) && ((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) && ((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) && //now try it without end time ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d.%d\"%*[^<]<clear/>%n",&a3,&a4,&plen)) < 2) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&plen)) < 2) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&plen)) < 3) && ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\"%*[^<]<clear/>%n",&a1,&a2,&a3,&a4,&plen)) < 4) ) continue; current->start = a1*360000+a2*6000+a3*100+a4/10; current->end = b1*360000+b2*6000+b3*100+b4/10; if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0) current->end = current->start+200; p=line; p+=plen;i=0; // TODO: I don't know what kind of convention is here for marking multiline subs, maybe <br/> like in xml? next = strstr(line,"<clear/>"); if(next && strlen(next)>8){ next+=8;i=0; while ((next =sub_readtext (next, &(current->text[i])))) { if (current->text[i]==ERR) {return ERR;} i++; if (i>=SUB_MAX_TEXT) { mp_msg(MSGT_SUBREADER,MSGL_WARN,"Too many lines in a subtitle\n");current->lines=i;return current;} } } current->lines=i+1; } return current;}subtitle *sub_read_line_ssa(FILE *fd,subtitle *current) {/* * Sub Station Alpha v4 (and v2?) scripts have 9 commas before subtitle * other Sub Station Alpha scripts have only 8 commas before subtitle * Reading the "ScriptType:" field is not reliable since many scripts appear * w/o it * * http://www.scriptclub.org is a good place to find more examples * http://www.eswat.demon.co.uk is where the SSA specs can be found */ int comma; static int max_comma = 32; /* let's use 32 for the case that the */ /* amount of commas increase with newer SSA versions */ int hour1, min1, sec1, hunsec1, hour2, min2, sec2, hunsec2, nothing; int num; char line[LINE_LEN+1], line3[LINE_LEN+1], *line2; char *tmp; do { if (!fgets (line, LINE_LEN, fd)) return NULL; } while (sscanf (line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d," "%[^\n\r]", ¬hing, &hour1, &min1, &sec1, &hunsec1, &hour2, &min2, &sec2, &hunsec2, line3) < 9 && sscanf (line, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d," "%[^\n\r]", ¬hing, &hour1, &min1, &sec1, &hunsec1, &hour2, &min2, &sec2, &hunsec2, line3) < 9 ); line2=strchr(line3, ','); for (comma = 4; comma < max_comma; comma ++) { tmp = line2; if(!(tmp=strchr(++tmp, ','))) break; if(*(++tmp) == ' ') break; /* a space after a comma means we're already in a sentence */ line2 = tmp; } if(comma < max_comma)max_comma = comma; /* eliminate the trailing comma */ if(*line2 == ',') line2++; current->lines=0;num=0; current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1; current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2; while (((tmp=strstr(line2, "\\n")) != NULL) || ((tmp=strstr(line2, "\\N")) != NULL) ){ current->text[num]=(char *)malloc(tmp-line2+1); strncpy (current->text[num], line2, tmp-line2); current->text[num][tmp-line2]='\0'; line2=tmp+2; num++; current->lines++; if (current->lines >= SUB_MAX_TEXT) return current; } current->text[num]=strdup(line2); current->lines++; return current;}void sub_pp_ssa(subtitle *sub) { int l=sub->lines; char *so,*de,*start; while (l){ /* eliminate any text enclosed with {}, they are font and color settings */ so=de=sub->text[--l]; while (*so) { if(*so == '{' && so[1]=='\\') { for (start=so; *so && *so!='}'; so++); if(*so) so++; else so=start; } if(*so) { *de=*so; so++; de++; } } *de=*so; }}/* * PJS subtitles reader. * That's the "Phoenix Japanimation Society" format. * I found some of them in http://www.scriptsclub.org/ (used for anime). * The time is in tenths of second. * * by set, based on code by szabi (dunnowhat sub format ;-) */subtitle *sub_read_line_pjs(FILE *fd,subtitle *current) { char line[LINE_LEN+1]; char text[LINE_LEN+1], *s, *d; if (!fgets (line, LINE_LEN, fd)) return NULL; /* skip spaces */ for (s=line; *s && isspace(*s); s++); /* allow empty lines at the end of the file */ if (*s==0) return NULL; /* get the time */ if (sscanf (s, "%ld,%ld,", &(current->start), &(current->end)) <2) { return ERR; } /* the files I have are in tenths of second */ current->start *= 10; current->end *= 10; /* walk to the beggining of the string */ for (; *s; s++) if (*s==',') break; if (*s) { for (s++; *s; s++) if (*s==',') break; if (*s) s++; } if (*s!='"') { return ERR; } /* copy the string to the text buffer */ for (s++, d=text; *s && *s!='"'; s++, d++) *d=*s; *d=0; current->text[0] = strdup(text); current->lines = 1; return current;}subtitle *sub_read_line_mpsub(FILE *fd, subtitle *current) { char line[LINE_LEN+1]; float a,b; int num=0; char *p, *q; do { if (!fgets(line, LINE_LEN, fd)) return NULL; } while (sscanf (line, "%f %f", &a, &b) !=2); mpsub_position += a*mpsub_multiplier; current->start=(int) mpsub_position; mpsub_position += b*mpsub_multiplier; current->end=(int) mpsub_position; while (num < SUB_MAX_TEXT) { if (!fgets (line, LINE_LEN, fd)) { if (num == 0) return NULL; else return current; } p=line; while (isspace(*p)) p++; if (eol(*p) && num > 0) return current; if (eol(*p)) return NULL; for (q=p; !eol(*q); q++); *q='\0'; if (strlen(p)) { current->text[num]=strdup(p);// printf (">%s<\n",p); current->lines = ++num; } else { if (num) return current; else return NULL; } } return NULL; // we should have returned before if it's OK}#ifndef USE_SORTSUB//we don't need this if we use previous_sub_endsubtitle *previous_aqt_sub = NULL;#endifsubtitle *sub_read_line_aqt(FILE *fd,subtitle *current) { char line[LINE_LEN+1]; char *next; int i; while (1) { // try to locate next subtitle if (!fgets (line, LINE_LEN, fd)) return NULL; if (!(sscanf (line, "-->> %ld", &(current->start)) <1)) break; } #ifdef USE_SORTSUB previous_sub_end = (current->start) ? current->start - 1 : 0; #else if (previous_aqt_sub != NULL) previous_aqt_sub->end = current->start-1; previous_aqt_sub = current;#endif if (!fgets (line, LINE_LEN, fd)) return NULL; sub_readtext((char *) &line,¤t->text[0]); current->lines = 1; current->end = current->start; // will be corrected by next subtitle if (!fgets (line, LINE_LEN, fd)) return current; next = line,i=1; while ((next =sub_readtext (next, &(current->text[i])))) { if (current->text[i]==ERR) {return ERR;} i++; if (i>=SUB_MAX_TEXT) { mp_msg(MSGT_SUBREADER,MSGL_WARN,"Too many lines in a subtitle\n");current->lines=i;return current;} } current->lines=i+1; if ((current->text[0]=="") && (current->text[1]=="")) {#ifdef USE_SORTSUB previous_sub_end = 0;#else // void subtitle -> end of previous marked and exit previous_aqt_sub = NULL;#endif return NULL; } return current;}#ifndef USE_SORTSUBsubtitle *previous_subrip09_sub = NULL;#endifsubtitle *sub_read_line_subrip09(FILE *fd,subtitle *current) { char line[LINE_LEN+1]; int a1,a2,a3; char * next=NULL; int i,len; while (1) { // try to locate next subtitle if (!fgets (line, LINE_LEN, fd)) return NULL; if (!((len=sscanf (line, "[%d:%d:%d]",&a1,&a2,&a3)) < 3)) break; } current->start = a1*360000+a2*6000+a3*100; #ifdef USE_SORTSUB previous_sub_end = (current->start) ? current->start - 1 : 0; #else if (previous_subrip09_sub != NULL) previous_subrip09_sub->end = current->start-1; previous_subrip09_sub = current;#endif if (!fgets (line, LINE_LEN, fd)) return NULL; next = line,i=0; current->text[0]=""; // just to be sure that string is clear while ((next =sub_readtext (next, &(current->text[i])))) { if (current->text[i]==ERR) {return ERR;} i++; if (i>=SUB_MAX_TEXT) { mp_msg(MSGT_SUBREADER,MSGL_WARN,"Too many lines in a subtitle\n");current->lines=i;return current;} } current->lines=i+1; if ((current->text[0]=="") && (i==0)) {#ifdef USE_SORTSUB previous_sub_end = 0;#else // void subtitle -> end of previous marked and exit previous_subrip09_sub = NULL;#endif return NULL; } return current;}subtitle *sub_read_line_jacosub(FILE * fd, subtitle * current){ char line1[LINE_LEN], line2[LINE_LEN], directive[LINE_LEN], *p, *q; unsigned a1, a2, a3, a4, b1, b2, b3, b4, comment = 0; static unsigned jacoTimeres = 30; static int jacoShift = 0; memset(current, 0, sizeof(subtitle)); memset(line1, 0, LINE_LEN); memset(line2, 0, LINE_LEN); memset(directive, 0, LINE_LEN); while (!current->text[0]) { if (!fgets(line1, LINE_LEN, fd)) { return NULL; } if (sscanf (line1, "%u:%u:%u.%u %u:%u:%u.%u %[^\n\r]", &a1, &a2, &a3, &a4, &b1, &b2, &b3, &b4, line2) < 9) { if (sscanf(line1, "@%u @%u %[^\n\r]", &a4, &b4, line2) < 3) { if (line1[0] == '#') { int hours = 0, minutes = 0, seconds, delta, inverter = 1; unsigned units = jacoShift; switch (toupper(line1[1])) { case 'S': if (isalpha(line1[2])) { delta = 6; } else { delta = 2; } if (sscanf(&line1[delta], "%d", &hours)) { if (hours < 0) { hours *= -1; inverter = -1; } if (sscanf(&line1[delta], "%*d:%d", &minutes)) { if (sscanf (&line1[delta], "%*d:%*d:%d", &seconds)) { sscanf(&line1[delta], "%*d:%*d:%*d.%d", &units); } else { hours = 0; sscanf(&line1[delta], "%d:%d.%d", &minutes, &seconds, &units); minutes *= inverter; } } else { hours = minutes = 0; sscanf(&line1[delta], "%d.%d", &seconds, &units); seconds *= inverter; } jacoShift = ((hours * 3600 + minutes * 60 + seconds) * jacoTimeres + units) * inverter; } break; case 'T': if (isalpha(line1[2])) { delta = 8; } else { delta = 2; } sscanf(&line1[delta], "%u", &jacoTimeres); break; } } continue; } else { current->start = (unsigned long) ((a4 + jacoShift) * 100.0 / jacoTimeres); current->end = (unsigned long) ((b4 + jacoShift) * 100.0 / jacoTimeres); } } else { current->start = (unsigned long) (((a1 * 3600 + a2 * 60 + a3) * jacoTimeres + a4 + jacoShift) * 100.0 / jacoTimeres); current->end = (unsigned long) (((b1 * 3600 + b2 * 60 + b3) * jacoTimeres + b4 + jacoShift) * 100.0 / jacoTimeres); } current->lines = 0; p = line2; while ((*p == ' ') || (*p == '\t')) { ++p; } if (isalpha(*p)||*p == '[') { int cont, jLength; if (sscanf(p, "%s %[^\n\r]", directive, line1) < 2) return (subtitle *) ERR; jLength = strlen(directive); for (cont = 0; cont < jLength; ++cont) { if (isalpha(*(directive + cont))) *(directive + cont) = toupper(*(directive + cont));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -