AuxSubtitlesFormats_sami.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:16k
- /**************************************************************
- * AuxSubtitlesFormats_sami.c
- **************************************************************
- * Description:
- * ============
- * Format specific data and functions for subtitles files.
- **************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #if defined (USE_AUX_SUBTITLES) && defined(SUPPORT_SAMI_SUBTITLE)
- #ifdef _DEBUG
- #undef IFTRACE
- #ifdef DEBUG_AUX_SUBTITLES
- #define IFTRACE if (gTraceNavigator)
- #else
- #define IFTRACE
- #endif // DEBUG_AUX_SUBTITLES
- #include "Debugdbgmain.h"
- #endif // _DEBUG
- #include <string.h>
- #include "PlaycoreNav_ClipsreadTextFile.h"
- #include "PlaycoreNav_ClipsAuxSubtitlesCommonPrivate.h"
- #include "PlaycoreNav_ClipsAuxSubtitles.h"
- #include "PlaycoreNav_ClipsAuxSubtitlesFormats_sami.h"
- // <<< Robin_0907_2004
- //#include "PlaycoreNav_ClipsAVI_private.h"
- //#include "PlaycoreNav_Clipsnav_clips.h"
- #include "PlaycoreCoremainCoreGDef.h"
- #include "PlaycoreScPadScPadAlloc.h"
- static void parse_body(void);
- static void parse_style(BOOL bClass);
- // >>> Robin_0907_2004
- static void ParseAttrs(void);
- static void parse_class_define(char* lang_id);
- static BOOL get_token(int mode);
- static TOKEN_TYPE ScanTable(void);
- static BOOL next_char( char* p );
- #define IsWhite(C) (c==' ' || c=='t')
- #define IsLetter(C) (((c>='a' && c<='z') || (c>='A' && c<='Z')))
- typedef struct{
- TOKEN token;
- textFilePtr tfpFile;
- char current_class[10];
- char prefered_class[10];
- ULONG current_time;
- }SAMI_MEM;
- SAMI_MEM *sami_mem;
- const TOKEN_LUT token_lut_array[] =
- {
- { PARAGRAPH, "p" },
- { TAG_SYNC, "sync" },
- { START, "start" },
- { CLASS, "class" },
- { TAG_BR, "br" },
- { TAG_SAMI, "sami" },
- { TAG_END_SAMI, "/sami" },
- { TAG_BODY, "body" },
- { TAG_END_BODY, "/body" },
- { TAG_STYLE, "style" },
- { TAG_END_STYLE, "/style" },
- { SAMI_ID, "id" },
- { LANG, "lang" },
- { SAMI_FONT, "font" },
- { SAMI_FONT_COLOR, "color" },
- { SAMI_FONT_END, "/font" },
- };
- BOOL probeSubtitlesFileSami(DWORD dwSubtitlesFileAddress, DWORD dwSubtitlesFileSize)
- {
-
- if (NULL == (sami_mem = malloc(sizeof(SAMI_MEM))) )
- return FALSE;
- sami_mem->tfpFile=textFileOpen(dwSubtitlesFileAddress,dwSubtitlesFileSize);
- if ( NULL == sami_mem->tfpFile )
- {
- free(sami_mem);
- return FALSE;
- }
- if(FALSE == textFileIsCurrentChar(sami_mem->tfpFile, '<') ||
- FALSE == textFileIsCurrentChar(sami_mem->tfpFile, 'S') ||
- FALSE == textFileIsCurrentChar(sami_mem->tfpFile, 'A') ||
- FALSE == textFileIsCurrentChar(sami_mem->tfpFile, 'M') ||
- FALSE == textFileIsCurrentChar(sami_mem->tfpFile, 'I') ||
- FALSE == textFileIsCurrentChar(sami_mem->tfpFile, '>'))
- {
- textFileClose(sami_mem->tfpFile);
- free(sami_mem);
- return FALSE;
- }
- subtitleStorageInitWriting();
- while (1)
- {
- if (FALSE == get_token(NORMAL) )
- break;
- switch (sami_mem->token.type)
- {
- case NULL_TOKEN:
- case TAG_END_SAMI:
- free(sami_mem);
- textFileClose(sami_mem->tfpFile);
- // subtitleStorageMarkLastEntry();
- return FALSE;
- case TAG_BODY:
- case PARAGRAPH:
- case TAG_SYNC:
- // parse_body();
- break;
- case TAG_STYLE:
- parse_style(TRUE);
- free(sami_mem);
- textFileClose(sami_mem->tfpFile);
- return TRUE;
- // break;
- default:
- break;
- }
- }
- textFileClose(sami_mem->tfpFile);
- free(sami_mem);
-
- // subtitleStorageMarkLastEntry();
- return FALSE;
- }
- // >>> Robin_0907_2004
- BOOL parseSubtitlesFileSami(DWORD dwSubtitlesFileAddress, DWORD dwSubtitlesFileSize,DWORD dwScale, DWORD dwRate)
- {
-
- if (NULL == (sami_mem = malloc(sizeof(SAMI_MEM))) )
- return FALSE;
- memset(sami_mem,0,sizeof(SAMI_MEM));
- sami_mem->tfpFile=textFileOpen(dwSubtitlesFileAddress,dwSubtitlesFileSize);
- if ( NULL == sami_mem->tfpFile )
- {
- free(sami_mem);
- return FALSE;
- }
- subtitleStorageInitWriting();
- while (1)
- {
- if (FALSE == get_token(NORMAL) )
- break;
- switch (sami_mem->token.type)
- {
- case NULL_TOKEN:
- case TAG_END_SAMI:
- free(sami_mem);
- textFileClose(sami_mem->tfpFile);
- subtitleStorageMarkLastEntry();
- return TRUE;
- case TAG_BODY:
- case PARAGRAPH:
- case TAG_SYNC:
- parse_body();
- break;
- case TAG_STYLE:
- // <<< Robin_0907_2004
- parse_style(FALSE);
- // >>> Robin_0907_2004
- break;
- default:
- break;
- }
- }
- textFileClose(sami_mem->tfpFile);
- free(sami_mem);
-
- subtitleStorageMarkLastEntry();
- return TRUE;
- }
- static void parse_body()
- {
- long start_time = -1;
- int entry_state = 0; //Ready to write start entry
- while (1)
- {
- if ( FALSE == get_token(IN_BODY) )
- return;
- switch (sami_mem->token.type)
- {
- case NULL:
- case TAG_END_SAMI:
- return;
- case PARAGRAPH:
- break;
- case TAG_BR:
- if (0 == strcmp(sami_mem->current_class, sami_mem->prefered_class) ||
- 0 == strlen(sami_mem->current_class) )
- subtitleStorageWriteByte(FORMAT_NEW_LINE);
- break;
- case TAG_END_BODY:
- if (entry_state == 1)
- subtitleStorageEndEntry(sami_mem->current_time + 1000);
- break;
- case TAG_SYNC:
- start_time = sami_mem->current_time;
- break;
- case BLANK_SYNC:
- if (entry_state == 1)
- {
- subtitleStorageEndEntry(sami_mem->current_time);
- entry_state = 0; //Ready to write start entry
- }
- break;
- case CONTENT_STRING:
- if (0 == strcmp(sami_mem->current_class, sami_mem->prefered_class) ||
- 0 == strlen(sami_mem->current_class) )
- {
- int i, len = strlen(sami_mem->token.string);
- if (entry_state == 1 && start_time != -1) //Ready to write end entry
- {
- subtitleStorageEndEntry(start_time);
- entry_state = 0; //Ready to write start entry
- }
- if (entry_state == 0)
- {
- if (start_time == -1) //Didn't get <SYNC Start=...>
- break;
- subtitleStorageStartEntry(start_time);
- entry_state = 1; //Ready to write content
- }
- for (i = 0; i < len; i++)
- {
- subtitleStorageWriteByte(sami_mem->token.string[i]);
- }
- start_time = -1;
- }
- break;
- }
- }
- }
- // <<< Robin_0907_2004
- static void parse_style(BOOL bClass)
- {
- // char class_name[10], lang_id[10];
- char lang_id[16]; //BT0907: was lang_id[10]
- MPEG4SubtitleStreamInfo mpeg4SubtitleStreamInfo;
- while (1)
- {
- get_token(IN_STYLE);
- switch (sami_mem->token.type)
- {
- case NULL_TOKEN:
- case TAG_END_STYLE:
- return;
- case CLASS_DEFINE:
- if (TRUE == bClass) // store class_name
- {
- // <<< Robin_1027_2004
- lang_id[0] = ' ';
- parse_class_define(lang_id);
- if (lang_id[0] == ' ')
- continue;
- // >>> Robin_1027_2004
- // Robin_1119_2004, display SAMI subtitle language
- memset(&mpeg4SubtitleStreamInfo, 0, sizeof(MPEG4SubtitleStreamInfo));
- mpeg4SubtitleStreamInfo.streamID = NO_STREAM;
- mpeg4SubtitleStreamInfo.type = SAMI;
- strncpy(mpeg4SubtitleStreamInfo.languageCode.language, lang_id, 2);
- strcpy(mpeg4SubtitleStreamInfo.className, sami_mem->token.string);
-
- sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (SI_CLIPS_SUB_AVAILABLE_NUM * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&mpeg4SubtitleStreamInfo
- );
-
- SI_CLIPS_SUB_AVAILABLE_NUM ++;
- }
- else
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (SI_CLIPS_SUB_CURRENT_DISP_IDX * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
-
- strcpy(sami_mem->prefered_class, _mpeg4SubtitleStreamInfo.className);
- }
- // strcpy(class_name, sami_mem->token.string);
- // parse_class_define(lang_id);
- //#ifndef USE_AUX_SUBTITLES_KSC5601 //BillTang_0724_04: to support Korean also, but will cause problem if the file contains more than one subtitle
- // if (0 == strncmp(lang_id, "en-", 3)) //Only support English
- //#endif
- // {
- // strcpy(sami_mem->prefered_class, sami_mem->token.string);
- // }
- break;
- case STYLE_DEFINE:
- if (FALSE == textFileFindString(sami_mem->tfpFile,"}",0) )
- return;
- break;
- }
- }
- }
- // >>> Robin_0907_2004
- static void ParseAttrs()
- {
- char c, str[10];
- int i;
- TOKEN_TYPE attribute;
- while(1)
- {
- if ((attribute = ScanTable()) == NULL_TOKEN)
- {
- //eat until '>'
- if (FALSE == textFileFindString(sami_mem->tfpFile,">",0) )
- return;
-
- break;
- }
- //eat until '='
- if (FALSE == textFileFindString(sami_mem->tfpFile,"=",0) )
- return;
- if (START == attribute && sami_mem->token.type == TAG_SYNC)
- {
- textFileReadNumber(sami_mem->tfpFile, &sami_mem->current_time);
- }
- else
- {
- //Consume whilte space before lang id.
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c))
- return;
- if ( !IsWhite(c) )
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return;
- break;
- }
- }
- //Copy class name
- i = 0;
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c))
- return;
- if ( IsWhite(c) || c=='>')
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return;
- break;
- }
- str[i++] = c;
- }
- str[i++] = ' ';
- if (CLASS == attribute && sami_mem->token.type == PARAGRAPH)
- {
- strcpy(sami_mem->current_class, str);
- }
- }
- }
- }
- static void parse_class_define(char* lang_id)
- {
- char c;
- int i;
- TOKEN_TYPE attribute;
- //Consume stream until '}'
- // <<< Robin_1027_2004
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- return;
- if (IsWhite(c))
- continue;
-
- if ( c == '{')
- break;
- else
- return;
- }
-
- // if (FALSE == textFileFindString(sami_mem->tfpFile,"{",0) )
- // return;
- // >>> Robin_1027_2004
- while(1)
- {
- if ((attribute = ScanTable()) == NULL_TOKEN)
- {
- //eat until '}'
- if (FALSE == textFileFindString(sami_mem->tfpFile,"}",0) )
- return;
-
- break;
- }
- if (attribute == LANG)
- {
- //eat until ':'
- if (FALSE == textFileFindString(sami_mem->tfpFile,":",0) )
- return;
- //Consume whilte space before lang id.
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- return;
- if ( !IsWhite(c) )
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return;
- break;
- }
- }
- //Copy lang id
- i = 0;
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- return;
- if ( IsWhite(c) || c==';')
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return;
- break;
- }
- lang_id[i++] = c;
-
- //<<<BT0907: add condition to avoid illegal op
- if (i ==15)
- break;
- //>>>BT0907
- }
- lang_id[i++] = ' ';
- }
- //eat until ';'
- if (FALSE == textFileFindString(sami_mem->tfpFile,";",0) )
- return;
-
- }
- }
- static BOOL get_token(int mode)
- {
- static LEXER_STATE lexer_state = LEX_CONTENT;
- int lexer_point;
- char c;
- sami_mem->token.type = UNKNOWN;
- lexer_point = 0;
- if ( FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- {
- sami_mem->token.type = NULL_TOKEN;
- return FALSE;
- }
- while ( FALSE == textFileEOF(sami_mem->tfpFile) )
- {
- switch (lexer_state)
- {
- case LEX_CONTENT:
- if (c == '<')
- {
- lexer_state = LEX_GT;
- continue;
- }
- else if (c=='n' || c=='r')
- {
- if (lexer_point != 0)
- {
- sami_mem->token.type = CONTENT_STRING;
- sami_mem->token.string[lexer_point] = ' ';
- return TRUE;
- }
- break;
- }
- else if (c == ' ')
- {
- if (mode!=IN_BODY || lexer_point==0)
- break;
- }
- else if (c=='.')
- {
- if (mode==IN_STYLE && lexer_point==0)
- {
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- return FALSE;
-
- // Robin_0408_2005, for some special token: EN-USCC
- if ( IsWhite(c) )
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return FALSE;
- break;
- }
- sami_mem->token.string[lexer_point++] = c;
- }
- sami_mem->token.type = CLASS_DEFINE;
- sami_mem->token.string[lexer_point] = ' ';
- return TRUE;
- }
- }
- else if (c=='P' || c=='#')
- {
- if (mode==IN_STYLE && lexer_point==0)
- {
- sami_mem->token.type = STYLE_DEFINE;
- return TRUE;
- }
- }
- else if (c == ';' && mode==IN_BODY)
- {
- if (0 == strncmp(sami_mem->token.string, " ", 5) )
- {
- sami_mem->token.type = BLANK_SYNC;
- return TRUE;
- }
- }
- if (mode==IN_BODY && lexer_point < (LEN_CONTENT_STR-2))
- sami_mem->token.string[lexer_point++] = c;
- break;
- case LEX_GT:
- if ( FALSE == next_char(&c) )
- return FALSE;
- if (c == '/')
- {
- lexer_state = LEX_ENDTAG;
- if (lexer_point != 0)
- {
- sami_mem->token.type = CONTENT_STRING;
- sami_mem->token.string[lexer_point] = ' ';
- return TRUE;
- }
- continue;
- }
- if (IsLetter(c))
- {
- lexer_state = LEX_STARTTAG;
- if (lexer_point != 0)
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR)) //Rewind the first character after '<'
- return FALSE;
- sami_mem->token.type = CONTENT_STRING;
- sami_mem->token.string[lexer_point] = ' ';
- return TRUE;
- }
- continue;
- }
- lexer_state = LEX_CONTENT;
- break;
- case LEX_ENDTAG:
- sami_mem->token.type = ScanTable();
- if (FALSE == textFileFindString(sami_mem->tfpFile,">",0) )
- return FALSE;
- lexer_state = LEX_CONTENT;
- if (sami_mem->token.type != UNKNOWN)
- return TRUE;
- break;
- case LEX_STARTTAG:
- sami_mem->token.type = ScanTable();
- if ( FALSE == next_char(&c) )
- return FALSE;
- if (c != '>' && sami_mem->token.type!=UNKNOWN)
- ParseAttrs();
- else
- {
- //eat until end of tag '>'
- if (FALSE == textFileFindString(sami_mem->tfpFile,">",0) )
- return FALSE;
- }
- lexer_state = LEX_CONTENT;
- if (sami_mem->token.type != UNKNOWN)
- return TRUE;
- break;
- }
- if ( FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- {
- sami_mem->token.type = NULL_TOKEN;
- return FALSE;
- }
- }
- return FALSE;
- }
- static TOKEN_TYPE ScanTable()
- {
- char c, str[10];
- int i = 0;
- //Consume whilte space before attribute.
- while(1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c) )
- return NULL_TOKEN;
- if ( !IsWhite(c) && (c != 'r') && (c != 'n'))
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return NULL_TOKEN;
- break;
- }
- }
- while (1)
- {
- if (FALSE == textFileReadChar(sami_mem->tfpFile, 1, &c))
- return NULL_TOKEN;
- if (c=='=' || c==':' || c=='>' || c=='{' || c=='}' || IsWhite(c) )
- {
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return NULL_TOKEN;
- break;
- }
- str[i++] = c;
- }
- str[i] = ' ';
- if (i == 0)
- return NULL_TOKEN;
- strlwr(str); //Convert to lower case
- for (i=0; i<(sizeof(token_lut_array)/sizeof(TOKEN_LUT)); i++)
- {
- if (0 == strcmp(str, token_lut_array[i].str))
- return token_lut_array[i].token;
- }
- return UNKNOWN;
- }
- static BOOL next_char( char* p )
- {
- if ( FALSE == textFileReadChar(sami_mem->tfpFile, 1, p ))
- return FALSE;
- if (FALSE == textFileSeek(sami_mem->tfpFile,-1,TF_SEEK_CUR))
- return FALSE;
- return TRUE;
- }
- #endif //defined (USE_AUX_SUBTITLES) && defined(SUPPORT_SAMI_SUBTITLE)