| | 1433 | static int ParseJSS( demux_t *p_demux, subtitle_t *p_subtitle, int i_idx ) |
|---|
| | 1434 | { |
|---|
| | 1435 | demux_sys_t *p_sys = p_demux->p_sys; |
|---|
| | 1436 | text_t *txt = &p_sys->txt; |
|---|
| | 1437 | char *psz_text, *psz_orig; |
|---|
| | 1438 | char *psz_text2, *psz_orig2; |
|---|
| | 1439 | int h1, h2, m1, m2, s1, s2, f1, f2; |
|---|
| | 1440 | static int i_comment = 0; |
|---|
| | 1441 | |
|---|
| | 1442 | static int jss_time_resolution = 30; |
|---|
| | 1443 | static int jss_time_shift = 0; |
|---|
| | 1444 | |
|---|
| | 1445 | /* Parse the main lines */ |
|---|
| | 1446 | for( ;; ) |
|---|
| | 1447 | { |
|---|
| | 1448 | const char *s = TextGetLine( txt ); |
|---|
| | 1449 | if( !s ) |
|---|
| | 1450 | return VLC_EGENERIC; |
|---|
| | 1451 | |
|---|
| | 1452 | psz_text = malloc( strlen( s ) + 1 ); |
|---|
| | 1453 | psz_orig = psz_text; |
|---|
| | 1454 | |
|---|
| | 1455 | if( sscanf( s, "%d:%d:%d.%d %d:%d:%d.%d %[^\n\r]", |
|---|
| | 1456 | &h1, &m1, &s1, &f1, &h2, &m2, &s2, &f2, psz_text ) == 9 ) |
|---|
| | 1457 | { |
|---|
| | 1458 | p_subtitle->i_start = ( (int64_t)( h1 *3600 + m1 * 60 + s1 ) + |
|---|
| | 1459 | (int64_t)( ( f1 + jss_time_shift ) / jss_time_resolution ) ) |
|---|
| | 1460 | * 1000000; |
|---|
| | 1461 | p_subtitle->i_stop = ( (int64_t)( h2 *3600 + m2 * 60 + s2 ) + |
|---|
| | 1462 | (int64_t)( ( f2 + jss_time_shift ) / jss_time_resolution ) ) |
|---|
| | 1463 | * 1000000; |
|---|
| | 1464 | } |
|---|
| | 1465 | else if( sscanf( s, "@%d @%d %[^\n\r]", &f1, &f2, psz_text ) == 3 ) |
|---|
| | 1466 | { |
|---|
| | 1467 | p_subtitle->i_start = (int64_t)( |
|---|
| | 1468 | ( f1 + jss_time_shift ) / jss_time_resolution * 1000000.0 ); |
|---|
| | 1469 | p_subtitle->i_stop = (int64_t)( |
|---|
| | 1470 | ( f2 + jss_time_shift ) / jss_time_resolution * 1000000.0 ); |
|---|
| | 1471 | } |
|---|
| | 1472 | else if( s[0] == '#' ) |
|---|
| | 1473 | { |
|---|
| | 1474 | int h = 0, m =0, sec = 1, f = 1; |
|---|
| | 1475 | unsigned shift = 1; |
|---|
| | 1476 | int inv = 1; |
|---|
| | 1477 | |
|---|
| | 1478 | strcpy( psz_text, s ); |
|---|
| | 1479 | |
|---|
| | 1480 | switch( toupper( psz_text[1] ) ) |
|---|
| | 1481 | { |
|---|
| | 1482 | case 'S': |
|---|
| | 1483 | shift = isalpha( psz_text[2] ) ? 6 : 2 ; |
|---|
| | 1484 | |
|---|
| | 1485 | if( sscanf( &psz_text[shift], "%d", &h ) ) |
|---|
| | 1486 | { |
|---|
| | 1487 | /* Negative shifting */ |
|---|
| | 1488 | if( h < 0 ) |
|---|
| | 1489 | { |
|---|
| | 1490 | h *= -1; |
|---|
| | 1491 | inv = -1; |
|---|
| | 1492 | } |
|---|
| | 1493 | |
|---|
| | 1494 | if( sscanf( &psz_text[shift], "%*d:%d", &m ) ) |
|---|
| | 1495 | { |
|---|
| | 1496 | if( sscanf( &psz_text[shift], "%*d:%*d:%d", &sec ) ) |
|---|
| | 1497 | { |
|---|
| | 1498 | sscanf( &psz_text[shift], "%*d:%*d:%*d.%d", &f ); |
|---|
| | 1499 | } |
|---|
| | 1500 | else |
|---|
| | 1501 | { |
|---|
| | 1502 | h = 0; |
|---|
| | 1503 | sscanf( &psz_text[shift], "%d:%d.%d", &m, &sec, &f ); |
|---|
| | 1504 | m *= inv; |
|---|
| | 1505 | } |
|---|
| | 1506 | } |
|---|
| | 1507 | else |
|---|
| | 1508 | { |
|---|
| | 1509 | h = m = 0; |
|---|
| | 1510 | sscanf( &psz_text[shift], "%d.%d", &sec, &f); |
|---|
| | 1511 | sec *= inv; |
|---|
| | 1512 | } |
|---|
| | 1513 | jss_time_shift = ( ( h * 3600 + m * 60 + sec ) |
|---|
| | 1514 | * jss_time_resolution + f ) * inv; |
|---|
| | 1515 | } |
|---|
| | 1516 | break; |
|---|
| | 1517 | |
|---|
| | 1518 | case 'T': |
|---|
| | 1519 | shift = isalpha( psz_text[2] ) ? 8 : 2 ; |
|---|
| | 1520 | |
|---|
| | 1521 | sscanf( &psz_text[shift], "%d", &jss_time_resolution ); |
|---|
| | 1522 | break; |
|---|
| | 1523 | } |
|---|
| | 1524 | free( psz_text ); |
|---|
| | 1525 | continue; |
|---|
| | 1526 | } |
|---|
| | 1527 | else |
|---|
| | 1528 | /* Unkown line */ |
|---|
| | 1529 | { |
|---|
| | 1530 | free( psz_text ); |
|---|
| | 1531 | continue; |
|---|
| | 1532 | } |
|---|
| | 1533 | |
|---|
| | 1534 | /* Skip the blanks */ |
|---|
| | 1535 | while( *psz_text == ' ' || *psz_text == '\t' ) psz_text++; |
|---|
| | 1536 | |
|---|
| | 1537 | /* Parse the directives */ |
|---|
| | 1538 | if( isalpha( *psz_text ) || *psz_text == '[' ) |
|---|
| | 1539 | { |
|---|
| | 1540 | while( *psz_text != ' ' ) |
|---|
| | 1541 | { psz_text++ ;}; |
|---|
| | 1542 | |
|---|
| | 1543 | /* Directives are NOT parsed yet */ |
|---|
| | 1544 | /* directive = malloc( strlen( psz_text ) + 1 ); |
|---|
| | 1545 | if( sscanf( psz_text, "%s %[^\n\r]", directive, psz_text2 ) == 2 )*/ |
|---|
| | 1546 | } |
|---|
| | 1547 | |
|---|
| | 1548 | /* Skip the blanks after directives */ |
|---|
| | 1549 | while( *psz_text == ' ' || *psz_text == '\t' ) psz_text++; |
|---|
| | 1550 | |
|---|
| | 1551 | psz_text2 = calloc( strlen( psz_text) + 1, 1 ); |
|---|
| | 1552 | psz_orig2 = psz_text2; |
|---|
| | 1553 | |
|---|
| | 1554 | for( ; *psz_text != '\0' && *psz_text != '\n' && *psz_text != '\r'; ) |
|---|
| | 1555 | { |
|---|
| | 1556 | switch( *psz_text ) |
|---|
| | 1557 | { |
|---|
| | 1558 | case '{': |
|---|
| | 1559 | i_comment++; |
|---|
| | 1560 | break; |
|---|
| | 1561 | case '}': |
|---|
| | 1562 | if( i_comment ) |
|---|
| | 1563 | { |
|---|
| | 1564 | i_comment = 0; |
|---|
| | 1565 | if( (*(psz_text + 1 ) ) == ' ' ) psz_text++; |
|---|
| | 1566 | } |
|---|
| | 1567 | break; |
|---|
| | 1568 | case '~': |
|---|
| | 1569 | if( !i_comment ) |
|---|
| | 1570 | { |
|---|
| | 1571 | *psz_text2 = ' '; |
|---|
| | 1572 | psz_text2++; |
|---|
| | 1573 | } |
|---|
| | 1574 | break; |
|---|
| | 1575 | case ' ': |
|---|
| | 1576 | case '\t': |
|---|
| | 1577 | if( (*(psz_text + 1 ) ) == ' ' || (*(psz_text + 1 ) ) == '\t' ) |
|---|
| | 1578 | break; |
|---|
| | 1579 | if( !i_comment ) |
|---|
| | 1580 | { |
|---|
| | 1581 | *psz_text2 = ' '; |
|---|
| | 1582 | psz_text2++; |
|---|
| | 1583 | } |
|---|
| | 1584 | break; |
|---|
| | 1585 | case '\\': |
|---|
| | 1586 | if( (*(psz_text + 1 ) ) == 'n' ) |
|---|
| | 1587 | { |
|---|
| | 1588 | *psz_text2 = '\n'; |
|---|
| | 1589 | psz_text++; |
|---|
| | 1590 | psz_text2++; |
|---|
| | 1591 | break; |
|---|
| | 1592 | } |
|---|
| | 1593 | if( ( toupper(*(psz_text + 1 ) ) == 'C' ) || |
|---|
| | 1594 | ( toupper(*(psz_text + 1 ) ) == 'F' ) ) |
|---|
| | 1595 | { |
|---|
| | 1596 | psz_text++; psz_text++; |
|---|
| | 1597 | break; |
|---|
| | 1598 | } |
|---|
| | 1599 | if( (*(psz_text + 1 ) ) == 'B' || (*(psz_text + 1 ) ) == 'b' || |
|---|
| | 1600 | (*(psz_text + 1 ) ) == 'I' || (*(psz_text + 1 ) ) == 'i' || |
|---|
| | 1601 | (*(psz_text + 1 ) ) == 'U' || (*(psz_text + 1 ) ) == 'u' || |
|---|
| | 1602 | (*(psz_text + 1 ) ) == 'D' || (*(psz_text + 1 ) ) == 'N' ) |
|---|
| | 1603 | { |
|---|
| | 1604 | psz_text++; |
|---|
| | 1605 | break; |
|---|
| | 1606 | } |
|---|
| | 1607 | if( (*(psz_text + 1 ) ) == '~' || (*(psz_text + 1 ) ) == '{' || |
|---|
| | 1608 | (*(psz_text + 1 ) ) == '\\' ) |
|---|
| | 1609 | psz_text++; |
|---|
| | 1610 | else if( *(psz_text + 1 ) == '\r' || *(psz_text + 1 ) == '\n' |
|---|
| | 1611 | || *(psz_text + 1 ) == '\0' ) |
|---|
| | 1612 | { |
|---|
| | 1613 | char *s2 = TextGetLine( txt ); |
|---|
| | 1614 | if( !s2 ) |
|---|
| | 1615 | return VLC_EGENERIC; |
|---|
| | 1616 | |
|---|
| | 1617 | while ( *s2 == ' ' ) s2++; |
|---|
| | 1618 | |
|---|
| | 1619 | /* int i_len = strlen( psz_orig2 ); |
|---|
| | 1620 | |
|---|
| | 1621 | |
|---|
| | 1622 | psz_orig2 = realloc( psz_orig2, strlen( s2 ) + i_len + 1 ); |
|---|
| | 1623 | |
|---|
| | 1624 | |
|---|
| | 1625 | */ |
|---|
| | 1626 | } |
|---|
| | 1627 | default: |
|---|
| | 1628 | if( !i_comment ) |
|---|
| | 1629 | { |
|---|
| | 1630 | *psz_text2 = *psz_text; |
|---|
| | 1631 | psz_text2++; |
|---|
| | 1632 | } |
|---|
| | 1633 | } |
|---|
| | 1634 | psz_text++; |
|---|
| | 1635 | } |
|---|
| | 1636 | |
|---|
| | 1637 | p_subtitle->psz_text = psz_orig2; |
|---|
| | 1638 | free( psz_orig ); |
|---|
| | 1639 | return VLC_SUCCESS; |
|---|
| | 1640 | } |
|---|
| | 1641 | } |
|---|