1 /*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a BSD-style license that can
4  *  be found in the License.html file in the root of the source tree.
5  */
6 
7 //---------------------------------------------------------------------------
8 // Pre-compilation
9 #include "MediaInfo/PreComp.h"
10 #ifdef __BORLANDC__
11     #pragma hdrstop
12 #endif
13 //---------------------------------------------------------------------------
14 
15 //---------------------------------------------------------------------------
16 #include "MediaInfo/Setup.h"
17 //---------------------------------------------------------------------------
18 
19 //---------------------------------------------------------------------------
20 #if defined(MEDIAINFO_N19_YES)
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Text/File_N19.h"
25 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
26 #if MEDIAINFO_EVENTS
27     #include "MediaInfo/MediaInfo_Events_Internal.h"
28 #endif //MEDIAINFO_EVENTS
29 using namespace std;
30 //---------------------------------------------------------------------------
31 
32 namespace MediaInfoLib
33 {
34 
35 //***************************************************************************
36 // Constants
37 //***************************************************************************
38 
39 //---------------------------------------------------------------------------
N19_CodePageNumber(int32u CPN)40 static const char* N19_CodePageNumber(int32u CPN)
41 {
42     switch (CPN)
43     {
44         case 0x343337 : return "United States";
45         case 0x383530 : return "Multilingual";
46         case 0x383630 : return "Portugal";
47         case 0x383633 : return "Canada-French";
48         case 0x383635 : return "Nordic";
49         default       : return "";
50     }
51 }
52 
53 //---------------------------------------------------------------------------
N19_CharacterCodeTable(int16u CCT)54 static const char* N19_CharacterCodeTable(int16u CCT)
55 {
56     switch (CCT)
57     {
58         case 0x3030 : return "Latin, ISO 6937-2";
59         case 0x3031 : return "Latin/Cyrillic, ISO 8859-5";
60         case 0x3032 : return "Latin/Arabic, ISO 8859-6";
61         case 0x3033 : return "Latin/Greek, ISO 8859-7";
62         case 0x3034 : return "Latin/Hebrew, ISO 8859-8";
63         default       : return "";
64     }
65 }
66 
67 //---------------------------------------------------------------------------
N19_DiskFormatCode_FrameRate(int64u DFC)68 static float64 N19_DiskFormatCode_FrameRate(int64u DFC)
69 {
70     switch (DFC)
71     {
72         case 0x53544C32332E3031LL : return (float64)24000/(float64)1001;
73         case 0x53544C32342E3031LL : return (float64)24;
74         case 0x53544C32352E3031LL : return (float64)25;
75         case 0x53544C32392E3031LL : return (float64)30000/(float64)1001;
76         case 0x53544C33302E3031LL : return (float64)30;
77         case 0x53544C34372E3031LL : return (float64)48000/(float64)1001;
78         case 0x53544C34382E3031LL : return (float64)48;
79         case 0x53544C35302E3031LL : return (float64)50;
80         case 0x53544C35392E3031LL : return (float64)60000/(float64)1001;
81         case 0x53544C36302E3031LL : return (float64)60;
82         default                   : return (float64) 0;
83     }
84 }
85 
86 //---------------------------------------------------------------------------
N19_DisplayStandardCode(int8u DSC)87 static const char* N19_DisplayStandardCode(int8u DSC)
88 {
89     switch (DSC)
90     {
91         case 0x30 : return "Open subtitling";
92         case 0x31 : return "Level-1 teletext";
93         case 0x32 : return "Level-2 teletext";
94         default   : return "";
95     }
96 }
97 
98 //---------------------------------------------------------------------------
N19_LanguageCode(int16u LC)99 static const char* N19_LanguageCode(int16u LC)
100 {
101     switch (LC)
102     {
103         case 0x3030 : return "";
104         case 0x3031 : return "sq";
105         case 0x3032 : return "br";
106         case 0x3033 : return "ca";
107         case 0x3034 : return "hr";
108         case 0x3035 : return "cy";
109         case 0x3036 : return "cs";
110         case 0x3037 : return "da";
111         case 0x3038 : return "de";
112         case 0x3039 : return "en";
113         case 0x3041 : return "es";
114         case 0x3042 : return "eo";
115         case 0x3043 : return "et";
116         case 0x3044 : return "eu";
117         case 0x3045 : return "fo";
118         case 0x3046 : return "fr";
119         case 0x3130 : return "fy";
120         case 0x3131 : return "ga";
121         case 0x3132 : return "gd";
122         case 0x3133 : return "gl";
123         case 0x3134 : return "is";
124         case 0x3135 : return "it";
125         case 0x3136 : return "Lappish";
126         case 0x3137 : return "la";
127         case 0x3138 : return "lv";
128         case 0x3139 : return "lb";
129         case 0x3141 : return "lt";
130         case 0x3142 : return "hu";
131         case 0x3143 : return "mt";
132         case 0x3144 : return "nl";
133         case 0x3145 : return "no";
134         case 0x3146 : return "oc";
135         case 0x3230 : return "pl";
136         case 0x3231 : return "pt";
137         case 0x3232 : return "ro";
138         case 0x3233 : return "Romansh";
139         case 0x3234 : return "sr";
140         case 0x3235 : return "sk";
141         case 0x3236 : return "sl";
142         case 0x3237 : return "fi";
143         case 0x3238 : return "sv";
144         case 0x3239 : return "tr";
145         case 0x3241 : return "Flemish";
146         case 0x3242 : return "wa";
147         case 0x3435 : return "zu";
148         case 0x3436 : return "vi";
149         case 0x3437 : return "uz";
150         case 0x3438 : return "ur";
151         case 0x3439 : return "uk";
152         case 0x3441 : return "th";
153         case 0x3442 : return "te";
154         case 0x3443 : return "tt";
155         case 0x3444 : return "ta";
156         case 0x3445 : return "Tadzhik";
157         case 0x3446 : return "sw";
158         case 0x3530 : return "Sranan Tongo";
159         case 0x3531 : return "so";
160         case 0x3532 : return "si";
161         case 0x3533 : return "sn";
162         case 0x3534 : return "sr";
163         case 0x3535 : return "Ruthenian";
164         case 0x3536 : return "ru";
165         case 0x3537 : return "qu";
166         case 0x3538 : return "ps";
167         case 0x3539 : return "Punjabi";
168         case 0x3541 : return "fa";
169         case 0x3542 : return "Papamiento";
170         case 0x3543 : return "or";
171         case 0x3544 : return "ne";
172         case 0x3545 : return "nr";
173         case 0x3546 : return "mr";
174         case 0x3630 : return "mo";
175         case 0x3631 : return "ms";
176         case 0x3632 : return "mg";
177         case 0x3633 : return "mk";
178         case 0x3634 : return "Laotian";
179         case 0x3635 : return "kr";
180         case 0x3636 : return "km";
181         case 0x3637 : return "kk";
182         case 0x3638 : return "kn";
183         case 0x3639 : return "jp";
184         case 0x3641 : return "id";
185         case 0x3642 : return "hi";
186         case 0x3643 : return "he";
187         case 0x3644 : return "ha";
188         case 0x3645 : return "Gurani";
189         case 0x3646 : return "Gujurati";
190         case 0x3730 : return "hr";
191         case 0x3731 : return "ka";
192         case 0x3732 : return "ff";
193         case 0x3733 : return "Dari";
194         case 0x3734 : return "Churash";
195         case 0x3735 : return "zh";
196         case 0x3736 : return "my";
197         case 0x3737 : return "bg";
198         case 0x3738 : return "bn";
199         case 0x3739 : return "be";
200         case 0x3741 : return "bm";
201         case 0x3742 : return "az";
202         case 0x3743 : return "as";
203         case 0x3744 : return "hy";
204         case 0x3745 : return "ar";
205         case 0x3746 : return "am";
206         default     : return "";
207     }
208 }
209 
210 //***************************************************************************
211 // Constructor/Destructor
212 //***************************************************************************
213 
214 //---------------------------------------------------------------------------
File_N19()215 File_N19::File_N19()
216 :File__Analyze()
217 {
218     //Configuration
219     #if MEDIAINFO_EVENTS
220         ParserIDs[0]=MediaInfo_Parser_N19;
221         StreamIDs_Width[0]=0;
222     #endif //MEDIAINFO_EVENTS
223 
224     #if MEDIAINFO_DEMUX
225         TCP_Offset=0;
226         Row_Values=NULL;
227     #endif //MEDIAINFO_DEMUX
228 }
229 
230 //---------------------------------------------------------------------------
~File_N19()231 File_N19::~File_N19()
232 {
233     #if MEDIAINFO_DEMUX
234         if (Row_Values)
235         {
236             for (int8u Row_Pos=0; Row_Pos<Row_Max; ++Row_Pos)
237                 delete[] Row_Values[Row_Pos];
238             delete[] Row_Values;
239         }
240     #endif //MEDIAINFO_DEMUX
241 }
242 
243 //***************************************************************************
244 // Buffer - File header
245 //***************************************************************************
246 
247 //---------------------------------------------------------------------------
FileHeader_Begin()248 bool File_N19::FileHeader_Begin()
249 {
250     //Element_Size
251     if (Buffer_Size<11)
252         return false; //Must wait for more data
253 
254     if (Buffer[ 3]!=0x53
255      || Buffer[ 4]!=0x54
256      || Buffer[ 5]!=0x4C
257      || Buffer[ 8]!=0x2E
258      || Buffer[ 9]!=0x30
259      || Buffer[10]!=0x31) // "STLxx.01"
260     {
261         Reject("N19");
262         return false;
263     }
264 
265     //Element_Size
266     if (Buffer_Size<1024)
267         return false; //Must wait for more data about GSI
268 
269     //All should be OK...
270     return true;
271 }
272 
273 //---------------------------------------------------------------------------
FileHeader_Parse()274 void File_N19::FileHeader_Parse()
275 {
276     Element_Name("General Subtitle Information");
277 
278     //Parsing
279     Ztring OPT, RD, TNS, MNC, MNR, CO, EN;
280     string TCP;
281     int16u LC;
282     int8u  DSC, TCS;
283     Info_C3   (    CPN,                                         "CPN - Code Page Number"); Param_Info1(N19_CodePageNumber(CPN));
284     Get_C8    (    DFC,                                         "DFC - Disk Format Code"); Param_Info1C(N19_DiskFormatCode_FrameRate(DFC), N19_DiskFormatCode_FrameRate(DFC));
285     Get_C1    (    DSC,                                         "DSC - Display Standard Code"); Param_Info1(N19_DisplayStandardCode(DSC));
286     Get_C2    (    CCT,                                         "CCT - Character Code Table number"); Param_Info1(N19_CharacterCodeTable(CCT));
287     Get_C2    (    LC,                                          "LC - Language Code"); Param_Info1(N19_LanguageCode(LC));
288     Get_Local (32, OPT,                                         "OPT - Original Programme Title");
289     Skip_Local(32,                                              "OET - Original Episode Title");
290     Skip_Local(32,                                              "TPT - Translated Programme");
291     Skip_Local(32,                                              "TET - Translated Episode");
292     Skip_Local(32,                                              "TN - Translator's Name");
293     Skip_Local(32,                                              "TCD - Translator's Contact Details");
294     Skip_Local(16,                                              "SLR - Subtitle List Reference Code");
295     Skip_Local( 6,                                              "CD - Creation Date");
296     Get_Local ( 6, RD,                                          "RD - Revision Date");
297     Skip_C2   (                                                 "RN - Revision number");
298     Skip_C5   (                                                 "TNB - Total Number of Text and Timing Information (TTI) blocks");
299     Get_Local ( 5, TNS,                                         "TNS - Total Number of Subtitles");
300     Skip_C3   (                                                 "TNG - Total Number of Subtitle Groups");
301     Get_Local ( 2, MNC,                                         "MNC - Maximum Number of Displayable Characters in any text row");
302     Get_Local ( 2, MNR,                                         "MNR - Maximum Number of Displayable Rows");
303     Get_C1    (    TCS,                                         "TCS - Time Code: Status");
304     Get_String( 8, TCP,                                         "TCP - Time Code: Start-of-Programme");
305     Skip_Local( 8,                                              "TCF - Time Code: First In-Cue");
306     Skip_C1   (                                                 "TND - Total Number of Disks");
307     Skip_C1   (                                                 "DSN - Disk Sequence Number");
308     Get_Local ( 3, CO,                                          "CO - Country of Origin");
309     Skip_Local(32,                                              "PUB - Publisher");
310     Get_Local (32, EN,                                          "EN - Editor's Name");
311     Skip_Local(32,                                              "ECD - Editor's Contact Details");
312     Skip_XX(75,                                                 "Spare Bytes");
313     Skip_XX(576,                                                "UDA - User-Defined Area");
314 
315     FILLING_BEGIN();
316         Accept("N19");
317 
318         Fill(Stream_General, 0, General_Format, "N19");
319         Fill(Stream_General, 0, General_Title, OPT);
320         RD.insert(0, __T("20"));
321         RD.insert(4, __T("-"));
322         RD.insert(7, __T("-"));
323         Fill(Stream_General, 0, General_Recorded_Date, RD);
324         Fill(Stream_General, 0, General_Country, Ztring(CO).MakeLowerCase());
325         EN.Trim();
326         Fill(Stream_General, 0, General_DistributedBy, EN);
327 
328         Stream_Prepare(Stream_Text);
329         Fill(Stream_Text, 0, Text_Format, "N19");
330         if (N19_DiskFormatCode_FrameRate(DFC))
331         {
332             Fill(Stream_Text, 0, "FrameRate", N19_DiskFormatCode_FrameRate(DFC));
333             if (TCS==0x31 && TCP.size()==8
334              && TCP[0]>='0' && TCP[0]<='9'
335              && TCP[1]>='0' && TCP[1]<='9'
336              && TCP[2]>='0' && TCP[2]<='6'
337              && TCP[3]>='0' && TCP[3]<='9'
338              && TCP[4]>='0' && TCP[4]<='6'
339              && TCP[5]>='0' && TCP[5]<='9'
340              && TCP[6]>='0' && TCP[6]<='2'
341              && TCP[7]>='0' && TCP[7]<='9')
342             {
343                 int64u Delay=0;
344                 Delay+=(((int32u)TCP[0])-'0')*10*60*60*1000;
345                 Delay+=(((int32u)TCP[1])-'0')*   60*60*1000;
346                 Delay+=(((int32u)TCP[2])-'0')*   10*60*1000;
347                 Delay+=(((int32u)TCP[3])-'0')*      60*1000;
348                 Delay+=(((int32u)TCP[4])-'0')*      10*1000;
349                 Delay+=(((int32u)TCP[5])-'0')*         1000;
350                 int8u Frames=0;
351                 Frames+=(((int8u)TCP[6])-'0')*10;
352                 Frames+=(((int8u)TCP[7])-'0');
353                 if (N19_DiskFormatCode_FrameRate(DFC))
354                     Delay+=float64_int64s(Frames*1000/N19_DiskFormatCode_FrameRate(DFC));
355                 //Fill(Stream_Text, 0, Text_Delay, Delay); //TODO is 0???
356                 TCP.insert(TCP.begin()+2, ':');
357                 TCP.insert(TCP.begin()+5, ':');
358                 TCP.insert(TCP.begin()+8, ':');
359                 //Fill(Stream_Text, 0, "Delay/String4", TCP);
360                 Fill(Stream_Text, 0, "TimeCode_First", TCP);
361 
362 #if MEDIAINFO_DEMUX
363                 TCP_Offset=Delay;
364 #endif
365             }
366         }
367         Fill(Stream_Text, 0, Text_Width, MNC.To_int32u());
368         Fill(Stream_Text, 0, Text_Height, MNR.To_int32u());
369         Fill(Stream_Text, 0, Text_Language, N19_LanguageCode(LC));
370 
371         //Init
372         FirstFrame_TCI=(int64u)-1;
373         #if MEDIAINFO_DEMUX
374             Frame_Count=0;
375             TCO_Latest=(int64u)-1;
376             Row_Max=MNR.To_int8u();
377             if ((DSC=='1' || DSC=='2') && Row_Max<23)
378             {
379                 Row_Max=23;
380                 IsTeletext=true;
381             }
382             else
383                 IsTeletext=false;
384             Column_Max=MNC.To_int8u();
385             Row_Values=new wchar_t*[Row_Max];
386             for (int8u Row_Pos=0; Row_Pos<Row_Max; ++Row_Pos)
387             {
388                 Row_Values[Row_Pos]=new wchar_t[Column_Max+1];
389                 Row_Values[Row_Pos][Column_Max]=__T('\0');
390             }
391         #endif //MEDIAINFO_DEMUX
392     FILLING_END();
393 }
394 
395 //***************************************************************************
396 // Buffer - Global
397 //***************************************************************************
398 
399 //---------------------------------------------------------------------------
400 #if MEDIAINFO_SEEK
Read_Buffer_Seek(size_t Method,int64u Value,int64u ID)401 size_t File_N19::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
402 {
403     #if MEDIAINFO_DEMUX
404         TCO_Latest=(int64u)-1;
405     #endif //MEDIAINFO_DEMUX
406 
407     GoTo(0x400);
408     Open_Buffer_Unsynch();
409     return 1;
410 }
411 #endif //MEDIAINFO_SEEK
412 
413 //***************************************************************************
414 // Buffer - Per element
415 //***************************************************************************
416 
417 //---------------------------------------------------------------------------
Header_Parse()418 void File_N19::Header_Parse()
419 {
420     //Filling
421     Header_Fill_Size(128);
422     Header_Fill_Code(0, __T("TTI"));
423 }
424 
425 //---------------------------------------------------------------------------
Data_Parse()426 void File_N19::Data_Parse()
427 {
428     //Parsing
429     Ztring TF;
430     int32u TCI, TCO;
431     int8u  VP, JC;
432     Skip_B1   (                                                 "SGN - Subtitle Group Number");
433     Skip_B2   (                                                 "SN - Subtitle Number");
434     Skip_B1   (                                                 "EBN - Extension Block Number");
435     Skip_B1   (                                                 "CS - Cumulative Status");
436     Get_B4    (TCI,                                             "TCI - Time Code In");
437     TCI=((TCI>>24)&0xFF)*60*60*1000
438       + ((TCI>>16)&0xFF)   *60*1000
439       + ((TCI>>8 )&0xFF)      *1000
440       + (N19_DiskFormatCode_FrameRate(DFC)?((int32u)float64_int64s((TCI     &0xFF)      *1000/N19_DiskFormatCode_FrameRate(DFC))):0);
441     Param_Info1(Ztring().Duration_From_Milliseconds((int64u)TCI));
442     Get_B4    (TCO,                                             "TCO - Time Code Out");
443     TCO=((TCO>>24)&0xFF)*60*60*1000
444       + ((TCO>>16)&0xFF)   *60*1000
445       + ((TCO>>8 )&0xFF)      *1000
446       + (N19_DiskFormatCode_FrameRate(DFC)?((int32u)float64_int64s((TCO     &0xFF)      *1000/N19_DiskFormatCode_FrameRate(DFC))):0);
447     Param_Info1(Ztring().Duration_From_Milliseconds((int64u)TCO));
448     Get_B1    (VP,                                              "VP - Vertical Position");
449     if (VP
450 #if MEDIAINFO_DEMUX
451         && IsTeletext
452 #endif
453         )
454         VP--; //1-Based
455     Get_B1    (JC,                                              "JC - Justification Code");
456     Skip_B1   (                                                 "CF - Comment Flag");
457     switch (CCT)
458     {
459         case 0x3030 :   //Latin ISO 6937-2
460                         Get_ISO_6937_2(112, TF,                 "TF - Text Field");
461                         break;
462         case 0x3031 :   //Latin ISO 8859-5
463                         Get_ISO_8859_5(112, TF,                 "TF - Text Field");
464                         break;
465         default:
466                         //Not yet supported, basic default
467                         Get_ISO_8859_1(112, TF,                 "TF - Text Field");
468     }
469     #if MEDIAINFO_TRACE
470         for (size_t i = 0; i < TF.size(); ++i)
471             switch (TF[i])
472             {
473                 case 0x8A:  //EOL
474                             TF[i] = EOL[0];
475                             {
476                                 size_t j = 1;
477                                 while (EOL[j] != __T('\0'))
478                                     TF.insert(++i, 1, EOL[j++]);
479                             };
480                             break;
481                 case 0x8F:  // Padding
482                             TF.erase(i--, 1);
483                             break;
484                 default:
485                     if ( TF[i]< 0x20
486                      || (TF[i]>=0x80 && TF[i]<0xA0))
487                         TF.erase(i--, 1);
488             }
489         Param_Info1(TF);
490     #endif //MEDIAINFO_TRACE
491 
492     FILLING_BEGIN();
493         #if MEDIAINFO_DEMUX
494             for (size_t i = 0; i < TF.size(); ++i)
495                 switch (TF[i])
496                 {
497                     case 0x8A:  //EOL
498                                 TF[i] = EOL[0];
499                                 {
500                                     size_t j = 1;
501                                     while (EOL[j] != __T('\0'))
502                                         TF.insert(++i, 1, EOL[j++]);
503                                 };
504                                 break;
505                     case 0x8F:  // Padding
506                                 TF.erase(i--, 1);
507                                 break;
508                     default:
509                         if ( TF[i]< 0x20
510                          || (TF[i]>=0x80 && TF[i]<0xA0))
511                             TF.erase(i--, 1);
512                 }
513 
514             Frame_Count_NotParsedIncluded=Frame_Count;
515 
516             int8u Row_Pos=0;
517             for (; Row_Pos<Row_Max; ++Row_Pos)
518                 for (int8u Column_Pos=0; Column_Pos<Column_Max; ++Column_Pos)
519                     Row_Values[Row_Pos][Column_Pos]=__T(' ');
520 
521             if (TCO_Latest!=(int64u)-1 && TCI!=TCO_Latest)
522             {
523                 EVENT_BEGIN (Global, SimpleText, 0)
524                     Event.DTS=((int64u)(TCO_Latest))*1000000; // "-TCP_Offset" removed for the moment. TODO: find a way for when TCP_Offset should be removed and when it should not
525                     Event.PTS=Event.DTS;
526                     Event.DUR=((int64u)(TCI-TCO_Latest))*1000000;
527                     Event.Content=L"";
528                     Event.Flags=0;
529                     Event.MuxingMode=(int8u)-1;
530                     Event.Service=(int8u)-1;
531                     Event.Row_Max=Row_Max;
532                     Event.Column_Max=Column_Max;
533                     Event.Row_Values=Row_Values;
534                     Event.Row_Attributes=NULL;
535                 EVENT_END   ()
536             }
537 
538             ZtringList List;
539             List.Separator_Set(0, EOL);
540             List.Write(TF);
541             Row_Pos=0;
542             if (VP+List.size()>Row_Max)
543             {
544                 if (List.size()<=Row_Max)
545                     VP=Row_Max-(int8u)List.size();
546                 else
547                 {
548                     VP=0;
549                     List.resize(Row_Max);
550                 }
551             }
552             Row_Pos=VP;
553             for (; Row_Pos<Row_Max; ++Row_Pos)
554             {
555                 if (Row_Pos-VP>=(int8u)List.size())
556                     break;
557                 if (List[Row_Pos-VP].size()>Column_Max)
558                     List[Row_Pos-VP].resize(Column_Max);
559 
560                 switch (JC)
561                 {
562                     case 1 :    //Left-justified
563                     case 0 :    //Unchanged
564                                 for (int8u Column_Pos=0; Column_Pos<Column_Max; ++Column_Pos)
565                                 {
566                                     if (JC==1) //Left-justified
567                                         List[Row_Pos-VP].Trim();
568                                     if (Column_Pos>=List[Row_Pos-VP].size())
569                                         break;
570                                     if (List[Row_Pos-VP][Column_Pos]>=0x20)
571                                         Row_Values[Row_Pos][Column_Pos]=List[Row_Pos-VP][Column_Pos];
572                                 }
573                                 break;
574                     case 2 :    //Centered
575                                 for (int8u Column_Pos=(Column_Max-(int8u)List[Row_Pos-VP].size())/2; Column_Pos<Column_Max; ++Column_Pos)
576                                 {
577                                     List[Row_Pos-VP].Trim();
578                                     if (Column_Pos-(Column_Max-List[Row_Pos-VP].size())/2>=List[Row_Pos-VP].size())
579                                         break;
580                                     if (List[Row_Pos-VP][Column_Pos-(Column_Max-List[Row_Pos-VP].size())/2]>=0x20)
581                                         Row_Values[Row_Pos][Column_Pos]=List[Row_Pos-VP][Column_Pos-(Column_Max-List[Row_Pos-VP].size())/2];
582                                 }
583                                 break;
584                     case 3 :    //Right-justified
585                                 for (int8u Column_Pos=Column_Max-(int8u)List[Row_Pos-VP].size(); Column_Pos<Column_Max; ++Column_Pos)
586                                 {
587                                     List[Row_Pos-VP].Trim();
588                                     if (Column_Pos-(Column_Max-List[Row_Pos-VP].size())>=List[Row_Pos-VP].size())
589                                         break;
590                                     if (List[Row_Pos-VP][Column_Pos-(Column_Max-List[Row_Pos-VP].size())]>=0x20)
591                                         Row_Values[Row_Pos][Column_Pos]=List[Row_Pos-VP][Column_Pos-(Column_Max-List[Row_Pos-VP].size())];
592                                 }
593                                 break;
594                     default:    ;
595                 }
596             }
597 
598             EVENT_BEGIN (Global, SimpleText, 0)
599                 Event.DTS=((int64u)(TCI))*1000000; // "-TCP_Offset" removed for the moment. TODO: find a way for when TCP_Offset should be removed and when it should not
600                 Event.PTS=Event.DTS;
601                 Event.DUR=((int64u)(TCO-TCI))*1000000;
602                 Event.Content=TF.To_Unicode().c_str();
603                 Event.Flags=0;
604                 Event.MuxingMode=(int8u)-1;
605                 Event.Service=(int8u)-1;
606                 Event.Row_Max=Row_Max;
607                 Event.Column_Max=Column_Max;
608                 Event.Row_Values=Row_Values;
609                 Event.Row_Attributes=NULL;
610             EVENT_END   ()
611 
612             Frame_Count++;
613             TCO_Latest=TCO;
614         #endif //MEDIAINFO_DEMUX
615 
616         if (FirstFrame_TCI==(int64u)-1)
617         {
618             FirstFrame_TCI=TCI;
619             Fill(Stream_Text, 0, Text_Delay, TCI);
620             Fill(Stream_Text, 0, Text_Delay_Source, "Container");
621         }
622         if (File_Offset+Buffer_Offset+Element_Size+128>File_Size)
623         {
624             Fill(Stream_Text, 0, Text_Duration, TCO-FirstFrame_TCI);
625         }
626         else if (Config->ParseSpeed<1.0)
627             //Jumping
628             GoToFromEnd(128, "N19");
629     FILLING_END();
630 }
631 
632 //***************************************************************************
633 // C++
634 //***************************************************************************
635 
636 } //NameSpace
637 
638 #endif //MEDIAINFO_N19_YES
639