?? subreader.c.svn-base
字號:
return (subtitle *) ERR; jLength = RMasciiLength(directive); for (cont = 0; cont < jLength; ++cont) { if (isalpha(*(directive + cont))) *(directive + cont) = toupper(*(directive + cont)); } if ((strstr(directive, "RDB") != NULL) || (strstr(directive, "RDC") != NULL) || (strstr(directive, "RLB") != NULL) || (strstr(directive, "RLG") != NULL)) { continue; } if (strstr(directive, "JL") != NULL) { current->alignment = SUB_ALIGNMENT_BOTTOMLEFT; } else if (strstr(directive, "JR") != NULL) { current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT; } else { current->alignment = SUB_ALIGNMENT_BOTTOMCENTER; } strcpy(line2, line1); p = line2; } for (q = line1; (!eol(*p)) && (current->lines < SUB_MAX_TEXT); ++p) { switch (*p) { case '{': comment++; break; case '}': if (comment) { --comment; //the next line to get rid of a blank after the comment if ((*(p + 1)) == ' ') p++; } break; case '~': if (!comment) { *q = ' '; ++q; } break; case ' ': case '\t': if ((*(p + 1) == ' ') || (*(p + 1) == '\t')) break; if (!comment) { *q = ' '; ++q; } break; case '\\': if (*(p + 1) == 'n') { *q = '\0'; q = line1; current->text[current->lines++] = strdup(line1); ++p; break; } if ((toupper(*(p + 1)) == 'C') || (toupper(*(p + 1)) == 'F')) { ++p,++p; break; } if ((*(p + 1) == 'B') || (*(p + 1) == 'b') || (*(p + 1) == 'D') || //actually this means "insert current date here" (*(p + 1) == 'I') || (*(p + 1) == 'i') || (*(p + 1) == 'N') || (*(p + 1) == 'T') || //actually this means "insert current time here" (*(p + 1) == 'U') || (*(p + 1) == 'u')) { ++p; break; } if ((*(p + 1) == '\\') || (*(p + 1) == '~') || (*(p + 1) == '{')) { ++p; } else if (eol(*(p + 1))) { if (!stream_read_line(st, directive, LINE_LEN)) return NULL; trail_space(directive); strncat(line2, directive, (LINE_LEN > 511) ? LINE_LEN : 511); break; } default: if (!comment) { *q = *p; ++q; } } //-- switch } //-- for *q = '\0'; current->text[current->lines] = strdup(line1); } //-- while current->lines++; return current;}static int sub_autodetect (stream_t* st, RMint32 *uses_time) { RMascii line[LINE_LEN+1]; int i,j=0; RMascii p; while (j < 100) { j++; if (!stream_read_line (st, line, LINE_LEN)) return SUB_INVALID; if (sscanf (line, "{%d}{%d}", &i, &i)==2) {*uses_time=0;return SUB_MICRODVD;} if (sscanf (line, "{%d}{}", &i)==1) {*uses_time=0;return SUB_MICRODVD;} if (sscanf (line, "[%d][%d]", &i, &i)==2) {*uses_time=1;return SUB_MPL2;} if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i)==8) {*uses_time=1;return SUB_SUBRIP;} if (sscanf (line, "%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d", &i, &i, &i, (RMascii *)&i, &i, &i, &i, &i, (RMascii *)&i, &i)==10) {*uses_time=1;return SUB_SUBVIEWER;} if (sscanf (line, "{T %d:%d:%d:%d",&i, &i, &i, &i)==4) {*uses_time=1;return SUB_SUBVIEWER2;} if (strstr (line, "<SAMI>")) {*uses_time=1; return SUB_SAMI;} if (sscanf(line, "%d:%d:%d.%d %d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i) == 8) {*uses_time = 1; return SUB_JACOSUB;} if (sscanf(line, "@%d @%d", &i, &i) == 2) {*uses_time = 1; return SUB_JACOSUB;} if (sscanf (line, "%d:%d:%d:", &i, &i, &i )==3) {*uses_time=1;return SUB_VPLAYER;} if (sscanf (line, "%d:%d:%d ", &i, &i, &i )==3) {*uses_time=1;return SUB_VPLAYER;} //TODO: just checking if first line of sub starts with "<" is WAY // too weak test for RT // Please someone who knows the format of RT... FIX IT!!! // It may conflict with other sub formats in the future (actually it doesn't) if ( *line == '<' ) {*uses_time=1;return SUB_RT;} if (!RMMemcmp(line, "Dialogue: Marked", 16)) {*uses_time=1; return SUB_SSA;} if (!RMMemcmp(line, "Dialogue: ", 10)) {*uses_time=1; return SUB_SSA;} if (sscanf (line, "%d,%d,\"%c", &i, &i, (RMascii *) &i) == 3) {*uses_time=1;return SUB_PJS;} if (sscanf (line, "FORMAT=%d", &i) == 1) {*uses_time=0; return SUB_MPSUB;} if (sscanf (line, "FORMAT=TIM%c", &p)==1 && p=='E') {*uses_time=1; return SUB_MPSUB;} if (strstr (line, "-->>")) {*uses_time=0; return SUB_AQTITLE;} if (sscanf (line, "[%d:%d:%d]", &i, &i, &i)==3) {*uses_time=1;return SUB_SUBRIP09;} } return SUB_INVALID; // too many bad lines}#ifdef DUMPSUBSint sub_utf8=0;#elseextern int sub_utf8;int sub_utf8_prev=0;#endifRMreal sub_delay= 0.0;RMreal sub_fps = 25;#ifdef USE_ICONVstatic iconv_t icdsc = (iconv_t)(-1);void subcp_open (stream_t *st){ RMascii *tocp = "UTF-8"; if (sub_cp){ RMascii *cp_tmp = sub_cp;#ifdef HAVE_ENCA RMascii enca_lang[3], enca_fallback[100]; int free_cp_tmp = 0; if (sscanf(sub_cp, "enca:%2s:%99s", enca_lang, enca_fallback) == 2 || sscanf(sub_cp, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) { if (st && st->flags & STREAM_SEEK ) { cp_tmp = guess_cp(st, enca_lang, enca_fallback); free_cp_tmp = 1; } else { cp_tmp = enca_fallback; } }#endif if ((icdsc = iconv_open (tocp, cp_tmp)) != (iconv_t)(-1)){ sub_utf8 = 2; }#ifdef HAVE_ENCA if (free_cp_tmp && cp_tmp) RFREE(cp_tmp);#endif }}void subcp_close (void){ if (icdsc != (iconv_t)(-1)){ (void) iconv_close (icdsc); icdsc = (iconv_t)(-1); }}subtitle* subcp_recode (subtitle *sub){ int l=sub->lines; size_t ileft, oleft; RMascii *op, *ip, *ot; if(icdsc == (iconv_t)(-1)) return sub; while (l){ ip = sub->text[--l]; ileft = RMasciiLength(ip); oleft = 4 * ileft; if (!(ot = MALLOC(oleft + 1))){ continue; } op = ot; if (iconv(icdsc, &ip, &ileft, &op, &oleft) == (size_t)(-1)) { RFREE(ot); continue; } *op='\0' ; RFREE (sub->text[l]); sub->text[l] = ot; } return sub;}#endif#ifdef USE_FRIBIDI#ifndef max#define max(a,b) (((a)>(b))?(a):(b))#endifsubtitle* sub_fribidi (subtitle *sub, int sub_utf8){ FriBidiChar logical[LINE_LEN+1], visual[LINE_LEN+1]; // Hopefully these two won't smash the stack RMascii *ip = NULL, *op = NULL; FriBidiCharType base; size_t len,orig_len; int l=sub->lines; int char_set_num; fribidi_boolean log2vis; if(flip_hebrew) { // Please fix the indentation someday fribidi_set_mirroring(1); fribidi_set_reorder_nsm(0); if( sub_utf8 == 0 ) { char_set_num = fribidi_parse_charset (fribidi_charset?fribidi_charset:"ISO8859-8"); }else { char_set_num = fribidi_parse_charset ("UTF-8"); } while (l) { ip = sub->text[--l]; orig_len = len = RMasciiLength( ip ); // We assume that we don't use full unicode, only UTF-8 or ISO8859-x if(len > LINE_LEN) { l++; break; } len = fribidi_charset_to_unicode (char_set_num, ip, len, logical); base = fribidi_flip_commas?FRIBIDI_TYPE_ON:FRIBIDI_TYPE_L; log2vis = fribidi_log2vis (logical, len, &base, /* output */ visual, NULL, NULL, NULL); if(log2vis) { len = fribidi_remove_bidi_marks (visual, len, NULL, NULL, NULL); if((op = MALLOC((max(2*orig_len,2*len) + 1))) == NULL) { l++; break; } fribidi_unicode_to_charset ( char_set_num, visual, len,op); RFREE (ip); sub->text[l] = op; } } if (l){ for (l = sub->lines; l;) RFREE (sub->text[--l]); return ERR; } } return sub;}#endifstatic void adjust_subs_time(subtitle* sub, RMreal subtime, RMreal fps, int block, int sub_num, int sub_uses_time) {// int n,m;// subtitle* nextsub;// int i = sub_num;// RMuint32 subfms = (sub_uses_time ? 100 : fps) * subtime;// RMuint32 overlap = (sub_uses_time ? 100 : fps) / 5; // 0.2s//// n=m=0;// if (i) for (;;){// if (sub->end <= sub->start){// sub->end = sub->start + subfms;// m++;// n++;// }// if (!--i) break;// nextsub = sub + 1;// if(block){// if ((sub->end > nextsub->start) && (sub->end <= nextsub->start + overlap)) {// // these subtitles overlap for less than 0.2 seconds// // and would result in very short overlapping subtitle// // so let's fix the problem here, before overlapping code// // get its hands on them// unsigned delta = sub->end - nextsub->start, half = delta / 2;// sub->end -= half + 1;// nextsub->start += delta - half;// }// if (sub->end >= nextsub->start){// sub->end = nextsub->start - 1;// if (sub->end - sub->start > subfms)// sub->end = sub->start + subfms;// if (!m)// n++;// }// }//// /* Theory:// * Movies are often converted from FILM (24 fps)// * to PAL (25) by simply speeding it up, so we// * to multiply the original timestmaps by// * (Movie's FPS / Subtitle's (guessed) FPS)// * so eg. for 23.98 fps movie and PAL time based// * subtitles we say -subfps 25 and we're fine!// *///// /* timed sub fps correction ::atmos *///// if(sub_uses_time && sub_fps) {//// sub->start *= sub_fps/fps;//// sub->end *= sub_fps/fps;//// }//// sub = nextsub;// m = 0;// }}struct subreader { subtitle * (*read)(stream_t *st,subtitle *dest); void (*post)(subtitle *dest); const RMascii *name;};sub_data* sub_read_file (RMascii *filename, RMreal fps) { stream_t* fd; RMint32 n_max, i; subtitle *first, *sub, *return_sub; sub_data *subt_data; RMint32 uses_time = 0, sub_num = 0, sub_errs = 0; struct subreader sr[]= { { sub_read_line_microdvd, NULL, "microdvd" }, { sub_read_line_subrip, NULL, "subrip" }, { sub_read_line_subviewer, NULL, "subviewer" }, { sub_read_line_sami, NULL, "sami" }, { sub_read_line_vplayer, NULL, "vplayer" }, { sub_read_line_rt, NULL, "rt" }, { sub_read_line_ssa, sub_pp_ssa, "ssa" }, { sub_read_line_pjs, NULL, "pjs" }, { sub_read_line_aqt, NULL, "aqt" }, { sub_read_line_subviewer2, NULL, "subviewer 2.0" }, { sub_read_line_subrip09, NULL, "subrip 0.9" }, { sub_read_line_jacosub, NULL, "jacosub" }, { sub_read_line_mpl2, NULL, "mpl2" } }; struct subreader *srp; if(filename==NULL) return NULL; //qnx segfault i = 0; fd=open_stream_gfx (filename, NULL, &i); if (!fd) return NULL; sub_format=sub_autodetect (fd, &uses_time); mpsub_multiplier = (uses_time ? 100.0 : 1.0); if (sub_format==SUB_INVALID) {free_stream(fd); return NULL;} srp=sr+sub_format; stream_reset(fd); stream_seek(fd,0); sub_num=0;n_max=512; first=MALLOC(n_max*sizeof(subtitle)); if(!first){ return NULL; } while(1){ if(sub_num>=n_max){ subtitle* _t; // RMuint32 _g = n_max; // RMuint32 g, h; n_max+=32; _t = MALLOC(n_max*sizeof(subtitle)); // printf("sub num: %d", (RMuint16) sub_num); RMMemcpy(_t, first, (sub_num) * sizeof(subtitle)); // for(g = 0; g < (RMuint32)(sub_num - 1); g++) // for(h = 0; h < first[g].lines; h ++) // RFREE(first[g].text[h]); RFREE(first); first = _t; _t = NULL;// // first=realloc(first,n_max*sizeof(subtitle)); } sub = &first[sub_num]; RMMemset(sub, '\0', sizeof(subtitle));// sub = NULL; sub=srp->read(fd,sub); if(!sub) break; // EOF if ( sub == ERR ) { // printf("error\n"); if ( first ) RFREE(first); return NULL; } // Apply any post processing that needs recoding first if ((sub!=ERR) && !sub_no_text_pp && srp->post) srp->post(sub); if(sub==ERR) ++sub_errs; else ++sub_num; // Error vs. Valid } free_stream(fd);// printf ("SUB: Subtitle format %s time.\n", uses_time?"uses":"doesn't use"); if(sub_num<=0){ RFREE(first);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -