コード例 #1
0
ファイル: demux_subreader.c プロジェクト: Aseeker/mpv
static void sami_add_line(subtitle *current, char *buffer, char **pos) {
    char *p = *pos;
    *p = 0;
    trail_space(buffer);
    if (*buffer && current->lines < SUB_MAX_TEXT)
        current->text[current->lines++] = strdup(buffer);
    *pos = buffer;
}
コード例 #2
0
ファイル: demux_subreader.c プロジェクト: Aseeker/mpv
static subtitle *sub_read_line_jacosub(stream_t* st, subtitle * current,
                                       struct readline_args *args)
{
    int utf16 = args->utf16;
    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 (!stream_read_line(st, line1, LINE_LEN, utf16)) {
	    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));
	    }
	    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;
	    }
            snprintf(line2, sizeof(line2), "%s", 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, utf16))
			return NULL;
		    trail_space(directive);
		    av_strlcat(line2, directive, LINE_LEN);
		    break;
		}
	    default:
		if (!comment) {
		    *q = *p;
		    ++q;
		}
	    }			//-- switch
	}			//-- for
	*q = '\0';
	if (current->lines < SUB_MAX_TEXT)
	    current->text[current->lines] = strdup(line1);
    }				//-- while
    if (current->lines < SUB_MAX_TEXT)
        current->lines++;
    return current;
}
コード例 #3
0
ファイル: demux_subreader.c プロジェクト: Aseeker/mpv
static subtitle *sub_read_line_sami(stream_t* st, subtitle *current,
                                    struct readline_args *args)
{
    int utf16 = args->utf16;
    static char line[LINE_LEN+1];
    static char *s = NULL, *slacktime_s;
    char text[LINE_LEN+1], *p=NULL, *q;
    int state;

    current->lines = current->start = current->end = 0;
    current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
    state = 0;

    /* read the first line */
    if (!s)
	    if (!(s = stream_read_line(st, line, LINE_LEN, utf16))) return 0;

    do {
	switch (state) {

	case 0: /* find "START=" or "Slacktime:" */
	    slacktime_s = stristr (s, "Slacktime:");
	    if (slacktime_s)
                args->sub_slacktime = strtol (slacktime_s+10, NULL, 0) / 10;

	    s = stristr (s, "Start=");
	    if (s) {
		current->start = strtol (s + 6, &s, 0) / 10;
                /* eat '>' */
                for (; *s != '>' && *s != '\0'; s++);
                s++;
		state = 1; continue;
	    }
	    break;

	case 1: /* find (optional) "<P", skip other TAGs */
	    for  (; *s == ' ' || *s == '\t'; s++); /* strip blanks, if any */
	    if (*s == '\0') break;
	    if (*s != '<') { state = 3; p = text; continue; } /* not a TAG */
	    s++;
	    if (*s == 'P' || *s == 'p') { s++; state = 2; continue; } /* found '<P' */
	    for (; *s != '>' && *s != '\0'; s++); /* skip remains of non-<P> TAG */
	    if (*s == '\0')
	      break;
	    s++;
	    continue;

	case 2: /* find ">" */
	    if ((s = strchr (s, '>'))) { s++; state = 3; p = text; continue; }
	    break;

	case 3: /* get all text until '<' appears */
	    if (p - text >= LINE_LEN)
	        sami_add_line(current, text, &p);
	    if (*s == '\0') break;
	    else if (!strncasecmp (s, "<br>", 4)) {
                sami_add_line(current, text, &p);
		s += 4;
	    }
	    else if (*s == '{') { state = 5; ++s; continue; }
	    else if (*s == '<') { state = 4; }
	    else if (!strncasecmp (s, "&nbsp;", 6)) { *p++ = ' '; s += 6; }
	    else if (*s == '\t') { *p++ = ' '; s++; }
	    else if (*s == '\r' || *s == '\n') { s++; }
	    else *p++ = *s++;

	    /* skip duplicated space */
	    if (p > text + 2) if (*(p-1) == ' ' && *(p-2) == ' ') p--;

	    continue;

	case 4: /* get current->end or skip <TAG> */
	    q = stristr (s, "Start=");
	    if (q) {
		current->end = strtol (q + 6, &q, 0) / 10 - 1;
		*p = '\0'; trail_space (text);
		if (text[0] != '\0')
		    current->text[current->lines++] = strdup (text);
		if (current->lines > 0) { state = 99; break; }
		state = 0; continue;
	    }
	    s = strchr (s, '>');
	    if (s) { s++; state = 3; continue; }
	    break;
       case 5: /* get rid of {...} text, but read the alignment code */
	    if ((*s == '\\') && (*(s + 1) == 'a')) {
               if (stristr(s, "\\a1") != NULL) {
                   current->alignment = SUB_ALIGNMENT_BOTTOMLEFT;
                   s = s + 3;
               }
               if (stristr(s, "\\a2") != NULL) {
                   current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
                   s = s + 3;
               } else if (stristr(s, "\\a3") != NULL) {
                   current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
                   s = s + 3;
               } else if ((stristr(s, "\\a4") != NULL) || (stristr(s, "\\a5") != NULL) || (stristr(s, "\\a8") != NULL)) {
                   current->alignment = SUB_ALIGNMENT_TOPLEFT;
                   s = s + 3;
               } else if (stristr(s, "\\a6") != NULL) {
                   current->alignment = SUB_ALIGNMENT_TOPCENTER;
                   s = s + 3;
               } else if (stristr(s, "\\a7") != NULL) {
                   current->alignment = SUB_ALIGNMENT_TOPRIGHT;
                   s = s + 3;
               } else if (stristr(s, "\\a9") != NULL) {
                   current->alignment = SUB_ALIGNMENT_MIDDLELEFT;
                   s = s + 3;
               } else if (stristr(s, "\\a10") != NULL) {
                   current->alignment = SUB_ALIGNMENT_MIDDLECENTER;
                   s = s + 4;
               } else if (stristr(s, "\\a11") != NULL) {
                   current->alignment = SUB_ALIGNMENT_MIDDLERIGHT;
                   s = s + 4;
               }
	    }
	    if (*s == '}') state = 3;
	    ++s;
	    continue;
	}

	/* read next line */
	if (state != 99 && !(s = stream_read_line (st, line, LINE_LEN, utf16))) {
	    if (current->start > 0) {
		break; // if it is the last subtitle
	    } else {
		return 0;
	    }
	}

    } while (state != 99);

    // For the last subtitle
    if (current->end <= 0) {
        current->end = current->start + args->sub_slacktime;
        sami_add_line(current, text, &p);
    }

    return current;
}
コード例 #4
0
Tsubtitle* TsubtitleParserSami::parse(Tstream &fd, int flags, REFERENCE_TIME start, REFERENCE_TIME stop)
{
    wchar_t text[this->LINE_LEN + 1], *p = NULL, *q;
    int state;

    /* read the first line */
    if (!s)
        if ((s = fd.fgets(line, this->LINE_LEN)) == NULL) {
            return NULL;
        }

    TsubtitleText current(this->format);
    current.start = current.stop = 0;
    state = 0;

    do {
        switch (state) {

        case 0: /* find "START=" or "Slacktime:" */
            slacktime_s = stristr(s, L"Slacktime:");
            if (slacktime_s) {
                sub_slacktime = strtol(slacktime_s + 10, NULL, 0) / 10;
            }

            s = (wchar_t*)stristr(s, L"Start=");
            if (s) {
                int sec1000 = strtol(s + 6, &s, 0);
                current.start = this->hmsToTime(0, 0, sec1000 / 1000, (sec1000 % 1000) / 10);
                /* eat '>' */
                for (; *s != '>' && *s != '\0'; s++) {
                    ;
                }
                s++;
                state = 1;
                continue;
            }
            break;

        case 1: /* find (optionnal) "<P", skip other TAGs */
            for (; *s == ' ' || *s == '\t'; s++) {
                ;    /* strip blanks, if any */
            }
            if (*s == '\0') {
                break;
            }
            if (*s != '<') {
                state = 3;    /* not a TAG */
                p = text;
                continue;
            }
            s++;
            if (*s == 'P' || *s == 'p') {
                s++;    /* found '<P' */
                state = 2;
                continue;
            }
            for (; *s != '>' && *s != '\0'; s++) {
                ;    /* skip remains of non-<P> TAG */
            }
            if (s == '\0') {
                break;
            }
            s++;
            continue;

        case 2: /* find ">" */
            if ((s = strchr(s, '>')) != NULL) {
                s++;
                state = 3;
                p = text;
                continue;
            }
            break;

        case 3: /* get all text until '<' appears */
            if (*s == '\0') {
                break;
            } else if (!_strnicmp(s, L"<br>", 4)) {
                *p = '\0';
                p = text;
                trail_space(text);
                if (text[0] != '\0') {
                    current.add(text);
                }
                s += 4;
            } else if ((*s == '{') && !sub_no_text_pp) {
                state = 5;
                ++s;
                continue;
            } else if (*s == '<') {
                state = 4;
            } else if (!_strnicmp(s, L"&nbsp;", 6)) {
                *p++ = ' ';
                s += 6;
            } else if (*s == '\t') {
                *p++ = ' ';
                s++;
            } else if (*s == '\r' || *s == '\n') {
                s++;
            } else {
                *p++ = *s++;
            }

            /* skip duplicated space */
            if (p > text + 2) if (*(p - 1) == ' ' && *(p - 2) == ' ') {
                    p--;
                }

            continue;

        case 4: /* get current->end or skip <TAG> */
            q = (wchar_t*)stristr(s, L"Start=");
            if (q) {
                int sec1000 = strtol(q + 6, &q, 0);
                current.stop = this->hmsToTime(0, 0, sec1000 / 1000, (sec1000 % 1000) / 10 - 1);
                *p = '\0';
                trail_space(text);
                if (text[0] != '\0') {
                    current.add(text);
                }
                if (current.size() > 0) {
                    state = 99;
                    break;
                }
                state = 0;
                continue;
            }
            s = strchr(s, '>');
            if (s) {
                s++;
                state = 3;
                continue;
            }
            break;
        case 5: /* get rid of {...} text, but read the alignment code */
            if ((*s == '\\') && (*(s + 1) == 'a') && !sub_no_text_pp) {
                if (stristr(s, L"\\a1") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_BOTTOMLEFT;
                    s = s + 3;
                }
                if (stristr(s, L"\\a2") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
                    s = s + 3;
                } else if (stristr(s, L"\\a3") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
                    s = s + 3;
                } else if ((stristr(s, L"\\a4") != NULL) || (stristr(s, L"\\a5") != NULL) || (stristr(s, L"\\a8") != NULL)) {
                    //current->alignment = SUB_ALIGNMENT_TOPLEFT;
                    s = s + 3;
                } else if (stristr(s, L"\\a6") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_TOPCENTER;
                    s = s + 3;
                } else if (stristr(s, L"\\a7") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_TOPRIGHT;
                    s = s + 3;
                } else if (stristr(s, L"\\a9") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_MIDDLELEFT;
                    s = s + 3;
                } else if (stristr(s, L"\\a10") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_MIDDLECENTER;
                    s = s + 4;
                } else if (stristr(s, L"\\a11") != NULL) {
                    //current->alignment = SUB_ALIGNMENT_MIDDLERIGHT;
                    s = s + 4;
                }
            }
            if (*s == '}') {
                state = 3;
            }
            ++s;
            continue;
        }

        /* read next line */
        if (state != 99 && (s = fd.fgets(line, this->LINE_LEN)) == NULL) {
            if (current.start > 0) {
                break; // if it is the last subtitle
            } else {
                return NULL;
            }
        }

    } while (state != 99);

    // For the last subtitle
    if (current.stop <= 0) {
        current.stop = current.start + this->hmsToTime(0, 0, sub_slacktime / 1000, (sub_slacktime % 1000) / 10);
        *p = '\0';
        trail_space(text);
        if (text[0] != '\0') {
            current.add(text);
        }
    }
    return store(current);
}