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 //
9 // http://www.ffmpeg.org/~michael/ffv1.html
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 
13 //---------------------------------------------------------------------------
14 // Pre-compilation
15 #include "MediaInfo/PreComp.h"
16 #ifdef __BORLANDC__
17     #pragma hdrstop
18 #endif
19 //---------------------------------------------------------------------------
20 
21 //---------------------------------------------------------------------------
22 #include "MediaInfo/Setup.h"
23 //---------------------------------------------------------------------------
24 
25 //---------------------------------------------------------------------------
26 #if defined(MEDIAINFO_FFV1_YES)
27 //---------------------------------------------------------------------------
28 
29 //---------------------------------------------------------------------------
30 #include "MediaInfo/Video/File_Ffv1.h"
31 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
32 #include "ZenLib/BitStream.h"
33 //---------------------------------------------------------------------------
34 
35 #include <algorithm>
36 #include <math.h>
37 using namespace std;
38 
39 //---------------------------------------------------------------------------
40 namespace MediaInfoLib
41 {
42 
43 using namespace FFV1;
44 
45 //***************************************************************************
46 // Const
47 //***************************************************************************
48 
49 extern const int32u Psi_CRC_32_Table[256];
50 const int32u Slice::Context::N0 = 128;
51 const int32s Slice::Context::Cmax = 127;
52 const int32s Slice::Context::Cmin = -128;
53 
54 //***************************************************************************
55 // Helpers
56 //***************************************************************************
57 
58 //---------------------------------------------------------------------------
FFv1_CRC_Compute(const int8u * Buffer,size_t Size)59 static int32u FFv1_CRC_Compute(const int8u* Buffer, size_t Size)
60 {
61     int32u CRC_32 = 0;
62     const int8u* CRC_32_Buffer=Buffer;
63     const int8u* CRC_32_Buffer_End=CRC_32_Buffer+Size;
64 
65     while(CRC_32_Buffer<CRC_32_Buffer_End)
66     {
67         CRC_32=(CRC_32<<8) ^ Psi_CRC_32_Table[(CRC_32>>24)^(*CRC_32_Buffer)];
68         CRC_32_Buffer++;
69     }
70     return CRC_32;
71 }
72 
73 //---------------------------------------------------------------------------
74 #if MEDIAINFO_FIXITY
Ffv1_TryToFixCRC(const int8u * Buffer,size_t Buffer_Size)75 static size_t Ffv1_TryToFixCRC(const int8u* Buffer, size_t Buffer_Size)
76 {
77     //looking for a bit flip
78     int8u* Buffer2=new int8u[Buffer_Size];
79     memcpy(Buffer2, Buffer, Buffer_Size);
80     vector<size_t> BitPositions;
81     size_t BitPosition_Max=Buffer_Size*8;
82     for (size_t BitPosition=0; BitPosition<BitPosition_Max; BitPosition++)
83     {
84         size_t BytePosition=BitPosition>>3;
85         size_t BitInBytePosition=BitPosition&0x7;
86         Buffer2[BytePosition]^=1<<BitInBytePosition;
87         int32u crc_left_New=FFv1_CRC_Compute(Buffer2, Buffer_Size);
88         if (!crc_left_New)
89         {
90             BitPositions.push_back(BitPosition);
91         }
92         Buffer2[BytePosition]^=1<<BitInBytePosition;
93     }
94     delete[] Buffer2; //Buffer2=NULL
95 
96     return BitPositions.size()==1?BitPositions[0]:(size_t)-1;
97 }
98 #endif //MEDIAINFO_FIXITY
99 
100 //***************************************************************************
101 // RangeCoder
102 //***************************************************************************
103 
104 class RangeCoder
105 {
106 public:
107     RangeCoder(const int8u* Buffer, size_t Buffer_Size, const state_transitions default_state_transition);
108 
109     void AssignStateTransitions(const state_transitions new_state_transition);
110     void   ResizeBuffer(size_t Buffer_Size); //Adapt the buffer limit
111     size_t BytesUsed();
112     bool   Underrun();
113     void   ForceUnderrun();
114 
115     bool    get_rac(int8u* States);
116     int32u  get_symbol_u(int8u* States);
117     int32s  get_symbol_s(int8u* States);
118 
119     int32u Current;
120     int32u Mask;
121     state_transitions zero_state;
122     state_transitions one_state;
123 
124 private:
125     const int8u* Buffer_Beg;
126     const int8u* Buffer_Cur;
127     const int8u* Buffer_End;
128 };
129 
130 //---------------------------------------------------------------------------
RangeCoder(const int8u * Buffer,size_t Buffer_Size,const state_transitions default_state_transition)131 RangeCoder::RangeCoder (const int8u* Buffer, size_t Buffer_Size, const state_transitions default_state_transition)
132 {
133     //Assign buffer
134     Buffer_Beg=Buffer;
135     Buffer_Cur=Buffer;
136     Buffer_End=Buffer+Buffer_Size;
137 
138     //Init
139     if (Buffer_Size)
140         Current=*Buffer_Cur;
141     Mask=0xFF;
142     Buffer_Cur++;
143 
144     AssignStateTransitions(default_state_transition);
145 }
146 
AssignStateTransitions(const state_transitions new_state_transition)147 void RangeCoder::AssignStateTransitions (const state_transitions new_state_transition)
148 {
149     //Assign StateTransitions
150     std::memcpy (one_state, new_state_transition, state_transitions_size);
151     zero_state[0]=0;
152     for (size_t i=1; i<state_transitions_size; i++)
153         zero_state[i]=-one_state[state_transitions_size-i];
154 }
155 
156 //---------------------------------------------------------------------------
ResizeBuffer(size_t Buffer_Size)157 void RangeCoder::ResizeBuffer(size_t Buffer_Size)
158 {
159     Buffer_End=Buffer_Beg+Buffer_Size;
160 }
161 
162 //---------------------------------------------------------------------------
BytesUsed()163 size_t RangeCoder::BytesUsed()
164 {
165     if (Buffer_Cur>Buffer_End)
166         return Buffer_End-Buffer_Beg;
167     return Buffer_Cur-Buffer_Beg-(Mask<0x100?0:1);
168 }
169 
170 //---------------------------------------------------------------------------
Underrun()171 bool RangeCoder::Underrun()
172 {
173     return (Buffer_Cur-(Mask<0x100?0:1)>Buffer_End)?true:false;
174 }
175 
176 //---------------------------------------------------------------------------
ForceUnderrun()177 void RangeCoder::ForceUnderrun()
178 {
179     Mask=0;
180     Buffer_Cur=Buffer_End+1;
181 }
182 
183 //---------------------------------------------------------------------------
get_rac(int8u * States)184 bool RangeCoder::get_rac(int8u* States)
185 {
186     // Next byte
187     if (Mask<0x100)
188     {
189         Current<<=8;
190 
191         // If less, consume the next byte
192         // If equal, last byte assumed to be 0x00
193         // If more, underrun, we return 0
194         if (Buffer_Cur<Buffer_End)
195         {
196             Current|=*Buffer_Cur;
197         }
198         else if (Buffer_Cur>Buffer_End)
199         {
200             return false;
201         }
202 
203         Buffer_Cur++;
204         Mask<<=8;
205     }
206 
207     //Range Coder boolean value computing
208     int32u Mask2=(Mask*(*States))>>8;
209     Mask-=Mask2;
210     if (Current<Mask)
211     {
212         *States=zero_state[*States];
213         return false;
214     }
215     Current-=Mask;
216     Mask=Mask2;
217     *States=one_state[*States];
218     return true;
219 }
220 
221 //---------------------------------------------------------------------------
get_symbol_u(int8u * States)222 int32u RangeCoder::get_symbol_u(int8u* States)
223 {
224     if (get_rac(States))
225         return 0;
226 
227     int e = 0;
228     while (get_rac(States + 1 + min(e, 9))) // 1..10
229     {
230         e++;
231         if (e > 31)
232         {
233             ForceUnderrun(); // stream is buggy or unsupported, we disable it completely and we indicate that it is NOK
234             return 0;
235         }
236     }
237 
238     int32u a = 1;
239     int i = e - 1;
240     while (i >= 0)
241     {
242         a <<= 1;
243         if (get_rac(States + 22 + min(i, 9)))  // 22..31
244             ++a;
245         i--;
246     }
247 
248     return a;
249 }
250 
251 //---------------------------------------------------------------------------
get_symbol_s(int8u * States)252 int32s RangeCoder::get_symbol_s(int8u* States)
253 {
254     if (get_rac(States))
255         return 0;
256 
257     int e = 0;
258     while (get_rac(States + 1 + min(e, 9))) // 1..10
259     {
260         e++;
261         if (e > 31)
262         {
263             ForceUnderrun(); // stream is buggy or unsupported, we disable it completely and we indicate that it is NOK
264             return 0;
265         }
266     }
267 
268     int32s a = 1;
269     int i = e - 1;
270     while (i >= 0)
271     {
272         a <<= 1;
273         if (get_rac(States + 22 + min(i, 9)))  // 22..31
274             ++a;
275         i--;
276     }
277 
278     if (get_rac(States + 11 + min(e, 10))) // 11..21
279         return -a;
280     else
281         return a;
282 }
283 
284 //***************************************************************************
285 // Info
286 //***************************************************************************
287 
Ffv1_coder_type(int8u coder_type)288 static const char* Ffv1_coder_type(int8u coder_type)
289 {
290     switch (coder_type)
291     {
292         case 0 :
293                 return "Golomb Rice";
294         case 1 :
295         case 2 :
296                 return "Range Coder";
297         default:
298                 return "";
299     }
300 }
301 
Ffv1_colorspace_type(int8u colorspace_type,bool chroma_planes,bool alpha_plane)302 static const string Ffv1_colorspace_type(int8u colorspace_type, bool chroma_planes, bool alpha_plane)
303 {
304     string ToReturn;
305     switch (colorspace_type)
306     {
307         case 0 :
308                     ToReturn=chroma_planes?"YUV":"Y";
309                     break;
310         case 1 :    ToReturn="RGB"; break;
311         default:    return string();
312     }
313 
314     if (alpha_plane)
315         ToReturn+='A';
316 
317     return ToReturn;
318 }
319 
Ffv1_picture_structure_ScanType(int8u picture_structure)320 static const char* Ffv1_picture_structure_ScanType (int8u picture_structure)
321 {
322     switch (picture_structure)
323     {
324         case 1 :
325         case 2 : return "Interlaced";
326         case 3 : return "Progressive";
327         default: return "";
328     }
329 }
330 
Ffv1_picture_structure_ScanOrder(int8u picture_structure)331 static const char* Ffv1_picture_structure_ScanOrder (int8u picture_structure)
332 {
333     switch (picture_structure)
334     {
335         case 1 : return "TFF";
336         case 2 : return "BFF";
337         default: return "";
338     }
339 }
340 
341 static const state_transitions Ffv1_default_state_transition =
342 {
343       0,  0,  0,  0,  0,  0,  0,  0, 20, 21, 22, 23, 24, 25, 26, 27,
344      28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42,
345      43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57,
346      58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
347      74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
348      89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99,100,101,102,103,
349     104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118,
350     119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133,
351     134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,
352     150,151,152,152,153,154,155,156,157,158,159,160,161,162,163,164,
353     165,166,167,168,169,170,171,171,172,173,174,175,176,177,178,179,
354     180,181,182,183,184,185,186,187,188,189,190,190,191,192,194,194,
355     195,196,197,198,199,200,201,202,202,204,205,206,207,208,209,209,
356     210,211,212,213,215,215,216,217,218,219,220,220,222,223,224,225,
357     226,227,227,229,229,230,231,232,234,234,235,236,237,238,239,240,
358     241,242,243,244,245,246,247,248,248,  0,  0,  0,  0,  0,  0,  0,
359 };
360 
361 // Coming from FFv1 spec.
362 static const int8u log2_run[41]={
363     0 , 0, 0, 0, 1, 1, 1, 1,
364     2 , 2, 2, 2, 3, 3, 3, 3,
365     4 , 4, 5, 5, 6, 6, 7, 7,
366     8 , 9,10,11,12,13,14,15,
367     16,17,18,19,20,21,22,23,
368     24,
369 };
370 
371 static const int32u run[41] =
372 {
373     1 << 0,
374     1 << 0,
375     1 << 0,
376     1 << 0,
377     1 << 1,
378     1 << 1,
379     1 << 1,
380     1 << 1,
381     1 << 2,
382     1 << 2,
383     1 << 2,
384     1 << 2,
385     1 << 3,
386     1 << 3,
387     1 << 3,
388     1 << 3,
389     1 << 4,
390     1 << 4,
391     1 << 5,
392     1 << 5,
393     1 << 6,
394     1 << 6,
395     1 << 7,
396     1 << 7,
397     1 << 8,
398     1 << 9,
399     1 << 10,
400     1 << 11,
401     1 << 12,
402     1 << 13,
403     1 << 14,
404     1 << 15,
405     1 << 16,
406     1 << 17,
407     1 << 18,
408     1 << 19,
409     1 << 20,
410     1 << 21,
411     1 << 22,
412     1 << 23,
413     1 << 24,
414 };
415 
416 //***************************************************************************
417 // Slice
418 //***************************************************************************
419 
420 //---------------------------------------------------------------------------
contexts_clean()421 void Slice::contexts_clean()
422 {
423     for (size_t i = 0; i < MAX_PLANES; i++)
424     {
425         if (contexts[i])
426             delete[] contexts[i];
427     }
428 }
429 
430 //---------------------------------------------------------------------------
contexts_init(int32u plane_count,int32u quant_table_index[MAX_PLANES],int32u context_count[MAX_QUANT_TABLES])431 void Slice::contexts_init(int32u plane_count, int32u quant_table_index[MAX_PLANES], int32u context_count[MAX_QUANT_TABLES])
432 {
433     contexts_clean();
434 
435     for (size_t i = 0; i < MAX_PLANES; ++i)
436     {
437         if (i >= plane_count)
438         {
439             contexts[i] = NULL;
440             continue;
441         }
442         int32u idx = quant_table_index[i];
443         contexts[i] = new Context [context_count[idx]];
444     }
445 }
446 
447 //***************************************************************************
448 // Constructor/Destructor
449 //***************************************************************************
450 
451 //---------------------------------------------------------------------------
File_Ffv1()452 File_Ffv1::File_Ffv1()
453 :File__Analyze()
454 {
455     //Configuration
456     ParserName="FFV1";
457     #if MEDIAINFO_TRACE
458         Trace_Layers_Update(8); //Stream
459     #endif //MEDIAINFO_TRACE
460     StreamSource=IsStream;
461 
462     //use Ffv1_default_state_transition by default
463     memcpy(state_transitions_table, Ffv1_default_state_transition,
464            sizeof(Ffv1_default_state_transition));
465 
466     //Input
467     Width = (int32u)-1;
468     Height = (int32u)-1;
469 
470     //Temp
471     for (size_t i=0; i < MAX_QUANT_TABLES; ++i)
472     {
473         plane_states[i] = NULL;
474         plane_states_maxsizes[i] = 0;
475     }
476     Parameters_IsValid=false;
477     ConfigurationRecord_IsPresent=false;
478     RC=NULL;
479     slices = NULL;
480     version = (int32u)-1;
481     picture_structure = (int32u)-1;
482     sample_aspect_ratio_num = 0;
483     sample_aspect_ratio_den = 0;
484     KeyFramePassed = false;
485     memset(context_count, 0, MAX_QUANT_TABLES*sizeof(int32u));
486 }
487 
488 //---------------------------------------------------------------------------
~File_Ffv1()489 File_Ffv1::~File_Ffv1()
490 {
491     //Temp
492     if (slices)
493     {
494         for (size_t y = 0; y < num_v_slices; ++y)
495             for (size_t x = 0; x < num_h_slices; ++x)
496                 plane_states_clean(slices[x + y * num_h_slices].plane_states);
497         delete[] slices;
498     }
499     for (size_t i = 0; i < MAX_QUANT_TABLES; ++i)
500     {
501         if (!plane_states[i])
502             continue;
503         for (size_t j = 0; j < context_count[i]; ++j)
504             delete[] plane_states[i][j];
505         delete[] plane_states[i];
506         plane_states[i] = NULL;
507     }
508     delete RC; //RC=NULL
509 }
510 
511 //***************************************************************************
512 // Streams management
513 //***************************************************************************
514 
515 //---------------------------------------------------------------------------
Streams_Accept()516 void File_Ffv1::Streams_Accept()
517 {
518     Stream_Prepare(Stream_Video);
519     Fill(Stream_Video, 0, Video_Format, "FFV1");
520     if (version!=(int32u)-1)
521     {
522         Ztring Version=__T("Version ")+Ztring::ToZtring(version);
523         if (version>=3 && version<=4)
524         {
525             Version+=__T('.');
526             Version+=Ztring::ToZtring(micro_version);
527         }
528         Fill(Stream_Video, 0, Video_Format_Version, Version);
529     }
530     Fill(Stream_Video, 0, Video_BitRate_Mode, "VBR");
531 }
532 
533 //***************************************************************************
534 // RangeCoder
535 //***************************************************************************
536 
537 #if MEDIAINFO_TRACE
538 //---------------------------------------------------------------------------
Get_RB(states & States,bool & Info,const char * Name)539 void File_Ffv1::Get_RB (states &States, bool &Info, const char* Name)
540 {
541     Info=RC->get_rac(States);
542 
543     if (Trace_Activated)
544     {
545         Element_Offset+=RC->BytesUsed();
546         Param(Name, Info);
547         Element_Offset-=RC->BytesUsed();
548     }
549 }
550 
551 //---------------------------------------------------------------------------
Get_RU(states & States,int32u & Info,const char * Name)552 void File_Ffv1::Get_RU (states &States, int32u &Info, const char* Name)
553 {
554     Info=RC->get_symbol_u(States);
555 
556     if (Trace_Activated)
557     {
558         Element_Offset+=RC->BytesUsed();
559         Param(Name, Info);
560         Element_Offset-=RC->BytesUsed();
561     }
562 }
563 
564 //---------------------------------------------------------------------------
Get_RS(states & States,int32s & Info,const char * Name)565 void File_Ffv1::Get_RS (states &States, int32s &Info, const char* Name)
566 {
567     Info=RC->get_symbol_s(States);
568 
569     if (Trace_Activated)
570     {
571         Element_Offset+=RC->BytesUsed();
572         Param(Name, Info);
573         Element_Offset-=RC->BytesUsed();
574     }
575 }
576 
577 //---------------------------------------------------------------------------
Get_RS(int8u * & States,int32s & Info,const char * Name)578 void File_Ffv1::Get_RS (int8u* &States, int32s &Info, const char* Name)
579 {
580     Info=RC->get_symbol_s(States);
581 
582     if (Trace_Activated)
583     {
584         Element_Offset+=RC->BytesUsed();
585         Param(Name, Info);
586         Element_Offset-=RC->BytesUsed();
587     }
588 }
589 
590 //---------------------------------------------------------------------------
Skip_RC(states & States,const char * Name)591 void File_Ffv1::Skip_RC (states &States, const char* Name)
592 {
593     int8u Info=RC->get_rac(States);
594 
595     if (Trace_Activated)
596     {
597         Element_Offset+=RC->BytesUsed();
598         Param(Name, Info);
599         Element_Offset-=RC->BytesUsed();
600     }
601 }
602 
603 //---------------------------------------------------------------------------
Skip_RU(states & States,const char * Name)604 void File_Ffv1::Skip_RU (states &States, const char* Name)
605 {
606     if (Trace_Activated)
607     {
608         Element_Offset+=RC->BytesUsed();
609         Param(Name, RC->get_symbol_u(States));
610         Element_Offset-=RC->BytesUsed();
611     }
612     else
613         RC->get_symbol_u(States);
614 }
615 
616 //---------------------------------------------------------------------------
Skip_RS(states & States,const char * Name)617 void File_Ffv1::Skip_RS (states &States, const char* Name)
618 {
619     if (Trace_Activated)
620     {
621         Element_Offset+=RC->BytesUsed();
622         Param(Name, RC->get_symbol_s(States));
623         Element_Offset-=RC->BytesUsed();
624     }
625     else
626         RC->get_symbol_s(States);
627 }
628 
629 #else //MEDIAINFO_TRACE
630 //---------------------------------------------------------------------------
Get_RB_(states & States,bool & Info)631 void File_Ffv1::Get_RB_ (states &States, bool &Info)
632 {
633     Info=RC->get_rac(States);
634 }
635 
636 //---------------------------------------------------------------------------
Get_RU_(states & States,int32u & Info)637 void File_Ffv1::Get_RU_ (states &States, int32u &Info)
638 {
639     Info=RC->get_symbol_u(States);
640 }
641 
642 //---------------------------------------------------------------------------
Get_RS_(states & States,int32s & Info)643 void File_Ffv1::Get_RS_ (states &States, int32s &Info)
644 {
645     Info=RC->get_symbol_s(States);
646 }
647 
648 //---------------------------------------------------------------------------
Get_RS_(int8u * & States,int32s & Info)649 void File_Ffv1::Get_RS_ (int8u* &States, int32s &Info)
650 {
651     Info=RC->get_symbol_s(States);
652 }
653 
654 //---------------------------------------------------------------------------
Skip_RC_(states & States)655 void File_Ffv1::Skip_RC_ (states &States)
656 {
657     RC->get_rac(States);
658 }
659 
660 //---------------------------------------------------------------------------
Skip_RU_(states & States)661 void File_Ffv1::Skip_RU_ (states &States)
662 {
663     RC->get_symbol_u(States);
664 }
665 
666 //---------------------------------------------------------------------------
Skip_RS_(states & States)667 void File_Ffv1::Skip_RS_ (states &States)
668 {
669     RC->get_symbol_s(States);
670 }
671 
672 #endif //MEDIAINFO_TRACE
673 
674 //***************************************************************************
675 // Buffer - Global
676 //***************************************************************************
677 
678 //---------------------------------------------------------------------------
Read_Buffer_OutOfBand()679 void File_Ffv1::Read_Buffer_OutOfBand()
680 {
681     ConfigurationRecord_IsPresent=true;
682 
683     //Coherency tests
684     if (Buffer_Size<4)
685     {
686         Skip_XX(Element_Size,                                   "ConfigurationRecord");
687         Param_Error("FFV1-HEADER-END:1");
688         return;
689     }
690     int32u CRC_32=FFv1_CRC_Compute(Buffer+Buffer_Offset, (size_t)Element_Size);
691 
692     Element_Begin1("ConfigurationRecord");
693     delete RC; RC=new RangeCoder(Buffer, Buffer_Size-4, Ffv1_default_state_transition);
694     Parameters();
695     delete RC; RC=NULL;
696     if (Element_Offset+4<Element_Size)
697         Skip_XX(Element_Size-Element_Offset-4,                  "Reserved");
698     Skip_B4(                                                    "configuration_record_crc_parity");
699     if (CRC_32)
700         Param_Error("FFV1-HEADER-configuration_record_crc_parity:1");
701     Element_End0();
702 }
703 
704 //---------------------------------------------------------------------------
Skip_Frame()705 void File_Ffv1::Skip_Frame()
706 {
707     Skip_XX(Element_Size-Element_Offset, "Data");
708 
709     Frame_Count++;
710 
711     delete RC;
712     RC = NULL;
713 
714     Fill();
715     if (Config->ParseSpeed<1.0)
716         Finish();
717 }
718 
719 //---------------------------------------------------------------------------
Read_Buffer_Continue()720 void File_Ffv1::Read_Buffer_Continue()
721 {
722     if (ConfigurationRecord_IsPresent && !Parameters_IsValid)
723     {
724         Skip_Frame();
725         return;
726     }
727 
728     if (!RC)
729         RC = new RangeCoder(Buffer, Buffer_Size, Ffv1_default_state_transition);
730 
731     states States;
732     memset(States, 128, states_size);
733 
734     Element_Begin1("Frame");
735 
736     Get_RB (States, keyframe,                                   "keyframe");
737     if (intra && !keyframe)
738         Param_Error("FFV1-FRAME-key_frame-ISNOTINTRA:1");
739     if (keyframe)
740         KeyFramePassed=true;
741 
742     if (!ConfigurationRecord_IsPresent && keyframe)
743     {
744         #if MEDIAINFO_TRACE
745             bool Trace_Activated_Save=Trace_Activated;
746             if (Trace_Activated && Frame_Count)
747                 Trace_Activated=false; // Trace is relatively huge, temporarary deactivating it. TODO: an option for it
748         #endif //MEDIAINFO_TRACE
749 
750         Parameters();
751 
752         #if MEDIAINFO_TRACE
753             Trace_Activated=Trace_Activated_Save; // Trace is too huge, reactivating it.
754         #endif //MEDIAINFO_TRACE
755     }
756 
757     if (!Parameters_IsValid || !KeyFramePassed)
758     {
759         Skip_Frame();
760         return;
761     }
762 
763     int32u tail = (version >= 3) ? 3 : 0;
764     tail += ec == 1 ? 5 : 0;
765 
766     vector<int32u> Slices_BufferSizes;
767     if (version>=3)
768     {
769         int64u Slices_BufferPos=Element_Size;
770         while (Slices_BufferPos)
771         {
772             if (Slices_BufferPos<tail)
773             {
774                 //There is a problem
775                 Slices_BufferSizes.clear();
776                 break;
777             }
778 
779             int32u Size=BigEndian2int24u(Buffer+Buffer_Offset+(size_t)Slices_BufferPos-tail);
780             Size+=tail;
781 
782             if (Size>Slices_BufferPos)
783             {
784                 //There is a problem
785                 Slices_BufferSizes.clear();
786                 break;
787             }
788             Slices_BufferPos-=Size;
789 
790             Slices_BufferSizes.insert(Slices_BufferSizes.begin(), Size);
791         }
792     }
793 
794     size_t Pos=0;
795     BuggySlices=false;
796     while (Element_Offset<Element_Size || (!Pos && coder_type)) // With some v0 RC, content may be in the last byte of the RC which is also in the Parameter() part
797     {
798         Element_Begin1("Slice");
799         int64u Element_Offset_Begin=Element_Offset;
800         int64u Element_Size_Save=Element_Size;
801         if (Pos<Slices_BufferSizes.size())
802             Element_Size=Element_Offset+Slices_BufferSizes[Pos];
803         int32u crc_left=0;
804         if (ec == 1)
805             crc_left=FFv1_CRC_Compute(Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset));
806         Element_Size-=tail;
807 
808         if (Pos)
809         {
810             delete RC; RC = new RangeCoder(Buffer+Buffer_Offset+(size_t)Element_Offset, Element_Size-Element_Offset, state_transitions_table);
811         }
812         else
813         {
814             RC->ResizeBuffer(Element_Size);
815             RC->AssignStateTransitions(state_transitions_table);
816         }
817 
818         //SliceHeader
819         bool ParseContent;
820         if (version>=3)
821         {
822             ParseContent=SliceHeader(States);
823             if (!ParseContent)
824                 BuggySlices=true;
825         }
826         else
827             ParseContent=true;
828 
829         //SliceContent
830         #if MEDIAINFO_TRACE
831         if (ParseContent && (!Frame_Count || Trace_Activated)) // Parse slice only if trace feature is activated
832         {
833             SliceContent(States);
834         }
835         else
836         #endif //MEDIAINFO_TRACE
837             Skip_XX(Element_Size-Element_Offset,                "SliceContent");
838         if (version<=1 && Element_Offset+5==Element_Size)
839         {
840             crc_left=FFv1_CRC_Compute(Buffer+Buffer_Offset+(size_t)Element_Offset_Begin, (size_t)(Element_Size-Element_Offset_Begin));
841             Element_Size-=5;
842             ec = 1;
843             if (Frame_Count==0)
844                 Fill(Stream_Video, 0, "ErrorDetectionType", "Per slice");
845         }
846         if (Element_Offset<Element_Size)
847         {
848             Skip_XX(Element_Size-Element_Offset,                "Junk");
849             Param_Error("FFV1-SLICE-JUNK:1");
850         }
851 
852         //SliceFooter
853         Element_Size=Element_Size_Save;
854         if (version>=3 || ec == 1)
855             Element_Begin1("SliceFooter");
856         if (version>=3)
857         {
858             int32u slice_size;
859             Get_B3 (slice_size,                                 "slice_size");
860             if (Element_Offset_Begin+slice_size+3!=Element_Offset)
861                 Param_Error("FFV1-SLICE-slice_size:1");
862         }
863         {
864             if (ec == 1)
865             {
866                 int8u error_status;
867                 Get_B1 (error_status,                           "error_status");
868                 if (error_status)
869                     Param_Error("FFV1-SLICE-error_status:1");
870                 Skip_B4(                                        "slice_crc_parity");
871                 if (crc_left)
872                 {
873                     Param_Error("FFV1-SLICE-slice_crc_parity:1");
874 
875                     #if MEDIAINFO_FIXITY
876                         if (Config->TryToFix_Get())
877                         {
878                             size_t BitPosition=Ffv1_TryToFixCRC(Buffer+Buffer_Offset+(size_t)Element_Offset_Begin, Element_Offset-Element_Offset_Begin);
879                             if (BitPosition!=(size_t)-1)
880                             {
881                                 size_t BytePosition=BitPosition>>3;
882                                 size_t BitInBytePosition=BitPosition&0x7;
883                                 int8u Modified=Buffer[Buffer_Offset+(size_t)Element_Offset_Begin+BytePosition];
884                                 Modified^=1<<BitInBytePosition;
885                                 FixFile(File_Offset+Buffer_Offset+(size_t)Element_Offset_Begin+BytePosition, &Modified, 1)?Param_Info1("Fixed"):Param_Info1("Not fixed");
886                             }
887                         }
888                     #endif //MEDIAINFO_FIXITY
889                 }
890             }
891         }
892         if (version>=3 || ec==1)
893             Element_End0();
894 
895         Element_End0();
896         Pos++;
897     }
898 
899     //Integrity test
900     if (!BuggySlices && version>=3 && slices)
901     {
902         vector<size_t> SlicesPlaces;
903         size_t SlicesPlaces_Size=num_h_slices*num_v_slices;
904         SlicesPlaces.resize(num_h_slices*num_v_slices);
905         Slice* Slice_Max=slices+SlicesPlaces_Size;
906         current_slice=slices;
907         while (current_slice<Slice_Max)
908         {
909             if (current_slice->sample_buffer)
910                 SlicesPlaces[current_slice->slice_y*num_h_slices+current_slice->slice_x]++;
911 
912             current_slice++;
913         }
914         for (size_t i=0; i<SlicesPlaces_Size; i++)
915             if (SlicesPlaces[i]!=1)
916             {
917                 Element_Error("FFV1-FRAME-END:1");
918                 break;
919             }
920     }
921 
922     Element_End0();
923 
924     FILLING_BEGIN();
925         if (Frame_Count==0)
926         {
927             Fill(Stream_Video, 0, Video_ScanType, Ffv1_picture_structure_ScanType(picture_structure));
928             Fill(Stream_Video, 0, Video_ScanOrder, Ffv1_picture_structure_ScanOrder(picture_structure));
929             if (sample_aspect_ratio_num && sample_aspect_ratio_den)
930                 Fill(Stream_Video, 0, Video_PixelAspectRatio, ((float64)sample_aspect_ratio_num)/sample_aspect_ratio_den);
931         }
932 
933         Frame_Count++;
934     FILLING_END();
935 
936     delete RC;
937     RC = NULL;
938 
939     Fill();
940     if (Config->ParseSpeed<1.0)
941         Finish();
942 }
943 
944 //***************************************************************************
945 // Elements
946 //***************************************************************************
947 
948 //---------------------------------------------------------------------------
Parameters()949 void File_Ffv1::Parameters()
950 {
951     Element_Begin1("Parameters");
952 
953     //Parsing
954     states States;
955     memset(States, 128, states_size);
956     Get_RU (States, version,                                    "version");
957     if ( ConfigurationRecord_IsPresent && version<=1)
958     {
959         Param_Error("FFV1-HEADER-version-OUTOFBAND:1");
960         Accept(); //TODO: better check without removing error info in trace
961         Element_End0();
962         return;
963     }
964     if (!ConfigurationRecord_IsPresent && version> 1)
965     {
966         Param_Error("FFV1-HEADER-version-OUTOFBAND:1");
967         Accept(); //TODO: better check without removing error info in trace
968         Element_End0();
969         return;
970     }
971     if (version==2 || version>3)
972     {
973         Param_Error(version==2?"FFV1-HEADER-version-EXPERIMENTAL:1":"FFV1-HEADER-version-LATERVERSION:1");
974         if (version==2 || version>4)
975         {
976             Accept();
977             Element_End0();
978             return;
979         }
980     }
981     if (version>=3)
982         Get_RU (States, micro_version,                          "micro_version");
983     if ((version==3 && micro_version<4))
984     {
985         Param_Error("FFV1-HEADER-micro_version-EXPERIMENTAL:1");
986         Accept();
987         Element_End0();
988         return;
989     }
990     if (version==4) // Version 4 is still experimental at the time of writing but contains micro_version so we show it
991     {
992         Accept();
993         Element_End0();
994         return;
995     }
996     if (Frame_Count==0)
997         Accept(); //TODO: better check without removing error info in trace
998     Get_RU (States, coder_type,                                 "coder_type");
999     if (coder_type>2)
1000     {
1001         Param_Error("FFV1-HEADER-coder_type:1");
1002         Element_End0();
1003         return;
1004     }
1005     if (coder_type==2) //Range coder with custom state transition table
1006     {
1007         Element_Begin1("state_transition_deltas");
1008         for (size_t i = 1; i < state_transitions_size; i++)
1009         {
1010             int32s state_transition_delta;
1011             Get_RS (States, state_transition_delta,             "state_transition_delta");
1012             state_transition_delta+=RC->one_state[i];
1013             Param_Info1(state_transition_delta);
1014             if (state_transition_delta<0x00 || state_transition_delta>0xFF)
1015             {
1016                 Param_Error("FFV1-HEADER-state_transition_delta:1");
1017                 Element_End0();
1018                 Element_End0();
1019                 return;
1020             }
1021             state_transitions_table[i]=(int8u)state_transition_delta;
1022         }
1023         Element_End0();
1024     }
1025     Get_RU (States, colorspace_type,                            "colorspace_type");
1026     if (colorspace_type>1)
1027     {
1028         Param_Error("FFV1-HEADER-colorspace_type:1");
1029         Element_End0();
1030         Element_End0();
1031         return;
1032     }
1033     if (version)
1034     {
1035         Get_RU (States, bits_per_raw_sample,                    "bits_per_raw_sample");
1036         if (bits_per_raw_sample>64)
1037         {
1038             Param_Error("FFV1-HEADER-bits_per_raw_sample:1");
1039             Element_End0();
1040             return;
1041         }
1042         if (bits_per_raw_sample==0)
1043             bits_per_raw_sample=8; // Spec decision due to old encoders
1044     }
1045     else
1046     {
1047         bits_per_raw_sample=8;
1048     }
1049 
1050     Get_RB (States, chroma_planes,                              "chroma_planes");
1051     Get_RU (States, h_chroma_subsample_log2,                    "log2(h_chroma_subsample)");
1052     Get_RU (States, v_chroma_subsample_log2,                    "log2(h_chroma_subsample)");
1053     Get_RB (States, alpha_plane,                                "alpha_plane");
1054     if (version>1)
1055     {
1056         Get_RU (States, num_h_slices,                           "num_h_slices_minus1");
1057         if (num_h_slices>=Width)
1058         {
1059             Param_Error("FFV1-HEADER-num_h_slices:1");
1060             Element_End0();
1061             return;
1062         }
1063         Get_RU (States, num_v_slices,                           "num_v_slices_minus1");
1064         if (num_v_slices>=Height)
1065         {
1066             Param_Error("FFV1-HEADER-num_v_slices:1");
1067             Element_End0();
1068             return;
1069         }
1070         num_h_slices++;
1071         num_v_slices++;
1072         Get_RU (States, quant_table_count,                      "quant_table_count");
1073         if (quant_table_count>8)
1074         {
1075             Param_Error("FFV1-HEADER-quant_table_count:1");
1076             Element_End0();
1077             return;
1078         }
1079     }
1080     else
1081     {
1082         num_h_slices=1;
1083         num_v_slices=1;
1084         quant_table_count=1;
1085     }
1086     for (size_t i=0; i<quant_table_count; i++)
1087         if (!QuantizationTable(i))
1088         {
1089             Element_End0();
1090             return;
1091         }
1092     for (size_t i=0; i<quant_table_count; i++)
1093     {
1094         if (version>=2)
1095             Element_Begin1("initial_state");
1096         bool present=false;
1097         if (version>=2)
1098             Get_RB (States, present,                                "states_coded");
1099 
1100         if (coder_type && context_count[i]>plane_states_maxsizes[i])
1101         {
1102             states_context_plane plane_state_old = plane_states[i];
1103             plane_states[i] = new int8u*[context_count[i]];
1104             if (plane_state_old)
1105             {
1106                 memcpy(plane_states[i], plane_state_old, plane_states_maxsizes[i] * sizeof(int8u*));
1107                 delete[] plane_state_old;
1108             }
1109             for (size_t j = plane_states_maxsizes[i]; j < context_count[i]; j++)
1110                 plane_states[i][j] = new int8u[states_size];
1111             plane_states_maxsizes[i] = context_count[i];
1112         }
1113 
1114         for (size_t j = 0; j < context_count[i]; j++)
1115         {
1116             if (present)
1117             {
1118                 Element_Begin1("initial_state_deltas");
1119                 for (size_t k = 0; k < states_size; k++)
1120                 {
1121                     int32s value;
1122                     Get_RS (States, value,                  "initial_state_delta");
1123                     if (coder_type)
1124                         plane_states[i][j][k] = value;
1125                 }
1126                 Element_End0();
1127             }
1128             else if (coder_type)
1129             {
1130                 for (size_t k = 0; k < states_size; k++)
1131                     plane_states[i][j][k] = 128;
1132             }
1133         }
1134         if (version>=2)
1135             Element_End0();
1136     }
1137 
1138     if (version>=3)
1139     {
1140         Get_RU (States, ec,                                     "ec");
1141         if (ec>1)
1142         {
1143             Param_Error("FFV1-HEADER-ec:1");
1144             Element_End0();
1145             return;
1146         }
1147         if (micro_version)
1148         {
1149             Get_RU (States, intra,                              "intra");
1150             if (intra>1)
1151             {
1152                 Param_Error("FFV1-HEADER-intra:1");
1153                 Element_End0();
1154                 return;
1155             }
1156         }
1157         else
1158             intra=0;
1159     }
1160     else
1161     {
1162         ec=0;
1163         intra=0;
1164     }
1165 
1166     Element_End0();
1167 
1168     FILLING_BEGIN();
1169         //Marking handling of 16-bit overflow computing
1170         is_overflow_16bit=(colorspace_type==0 && bits_per_raw_sample==16 && (coder_type==1 || coder_type==2))?true:false; //TODO: check in FFmpeg the version when the stream is fixed. Note: only with YUV colorspace
1171 
1172         //quant_table_index_Count
1173         quant_table_index_count=1+(alpha_plane?1:0);
1174         if (version < 4 || chroma_planes) // Warning: chroma is considered as 1 plane
1175             quant_table_index_count++;
1176 
1177         //Slices
1178         if (!slices)
1179         {
1180             slices=new Slice[num_h_slices*num_v_slices];
1181             current_slice=&slices[0];
1182         }
1183         if (version<=1)
1184         {
1185             current_slice->x=0;
1186             current_slice->y=0;
1187             current_slice->w=Width;
1188             current_slice->h=Height;
1189             quant_table_index[0]=0;
1190             for (size_t i=1; i<quant_table_index_count; i++)
1191             {
1192                 quant_table_index[i]=0;
1193                 context_count[i]=context_count[0];
1194             }
1195         }
1196 
1197         //Filling
1198         if (Frame_Count==0)
1199         {
1200             Fill(Stream_Video, 0, "coder_type", Ffv1_coder_type(coder_type));
1201             Fill(Stream_Video, 0, Video_BitDepth, bits_per_raw_sample);
1202             if (version>1)
1203             {
1204                 Fill(Stream_Video, 0, "MaxSlicesCount", num_h_slices*num_v_slices);
1205                 if (version>=3)
1206                 {
1207                     if (ec)
1208                         Fill(Stream_Video, 0, "ErrorDetectionType", "Per slice");
1209                     if (micro_version && intra)
1210                         Fill(Stream_Video, 0, Video_Format_Settings_GOP, "N=1");
1211                 }
1212             }
1213             Fill(Stream_Video, 0, Video_ColorSpace, Ffv1_colorspace_type(colorspace_type, chroma_planes, alpha_plane));
1214             if (colorspace_type==0 && chroma_planes)
1215             {
1216                 string ChromaSubsampling;
1217                 switch (h_chroma_subsample_log2)
1218                 {
1219                     case 0 :
1220                             switch (v_chroma_subsample_log2)
1221                             {
1222                                 case 0 : ChromaSubsampling="4:4:4"; break;
1223                                 default: ;
1224                             }
1225                             break;
1226                     case 1 :
1227                             switch (v_chroma_subsample_log2)
1228                             {
1229                                 case 0 : ChromaSubsampling="4:2:2"; break;
1230                                 case 1 : ChromaSubsampling="4:2:0"; break;
1231                                 default: ;
1232                             }
1233                             break;
1234                     case 2 :
1235                             switch (v_chroma_subsample_log2)
1236                             {
1237                                 case 0 : ChromaSubsampling="4:1:1"; break;
1238                                 case 1 : ChromaSubsampling="4:1:0"; break;
1239                                 case 2 : ChromaSubsampling="4:1:0 (4x4)"; break;
1240                                 default: ;
1241                             }
1242                             break;
1243                     default: ;
1244                 }
1245                 if (!ChromaSubsampling.empty() && alpha_plane)
1246                     ChromaSubsampling+=":4";
1247                 Fill(Stream_Video, 0, Video_ChromaSubsampling, ChromaSubsampling);
1248             }
1249 
1250             Parameters_IsValid=true;
1251         }
1252     FILLING_END();
1253 }
1254 
1255 //---------------------------------------------------------------------------
SliceContent(states & States)1256 void File_Ffv1::SliceContent(states &States)
1257 {
1258     Element_Begin1("SliceContent");
1259 
1260     #if MEDIAINFO_TRACE
1261         bool Trace_Activated_Save=Trace_Activated;
1262         if (Trace_Activated)
1263             Trace_Activated=false; // Trace is too huge, deactivating it during pixel decoding
1264     #endif //MEDIAINFO_TRACE
1265 
1266     if (!coder_type)
1267     {
1268         if (version>=3)
1269         {
1270             int8u s = 129;
1271             RC->get_rac(&s);
1272         }
1273         Element_Offset+=RC->BytesUsed(); // Computing how many bytes where consumed by the range coder
1274         BS_Begin();
1275     }
1276 
1277     if (keyframe)
1278     {
1279         int8u plane_count=1+(alpha_plane?1:0);
1280         if (version < 4 || chroma_planes) // Warning: chroma is considered as 1 plane
1281             plane_count+=1;
1282         if (!coder_type)
1283             current_slice->contexts_init(plane_count, quant_table_index, context_count);
1284         else
1285             copy_plane_states_to_slice(plane_count);
1286     }
1287     current_slice->sample_buffer_new((current_slice->w + 6) * 3 * MAX_PLANES);
1288 
1289     if (colorspace_type == 0)
1290     {
1291         // YCbCr
1292         plane(0); // Y
1293         if (chroma_planes)
1294         {
1295             int32u w = current_slice->w;
1296             int32u h = current_slice->h;
1297 
1298             current_slice->w = w >> h_chroma_subsample_log2;
1299             if (w & ((1 << h_chroma_subsample_log2) - 1))
1300                 current_slice->w++; //Is ceil
1301             current_slice->h = h >> v_chroma_subsample_log2;
1302             if (h & ((1 << v_chroma_subsample_log2) - 1))
1303                 current_slice->h++; //Is ceil
1304             plane(1); // Cb
1305             plane(1); // Cr
1306             current_slice->w = w;
1307             current_slice->h = h;
1308         }
1309         if (alpha_plane)
1310             plane(2); // Alpha
1311     }
1312     else if (colorspace_type == 1)
1313         rgb();
1314 
1315     if (coder_type)
1316     {
1317         int8u s = 129;
1318         RC->get_rac(&s);
1319     }
1320 
1321     if (BS->BufferUnderRun || RC->Underrun())
1322         Element_Error("FFV1-SLICE-SliceContent:1");
1323 
1324     if (coder_type)
1325         Skip_XX(RC->BytesUsed(),                                "slice_data");
1326     else
1327         BS_End();
1328 
1329     #if MEDIAINFO_DECODE
1330         //Decode(Buffer, Buffer_Size);
1331     #endif //MEDIAINFO_DECODE
1332 
1333     #if MEDIAINFO_TRACE
1334         Trace_Activated=Trace_Activated_Save; // Trace is too huge, reactivating after during pixel decoding
1335     #endif //MEDIAINFO_TRACE
1336     Element_End0();
1337 }
1338 
1339 //---------------------------------------------------------------------------
SliceHeader(states & States)1340 bool File_Ffv1::SliceHeader(states &States)
1341 {
1342     Element_Begin1("SliceHeader");
1343 
1344     memset(States, 128, states_size);
1345 
1346     int32u slice_x, slice_y, slice_width_minus1, slice_height_minus1;
1347     Get_RU (States, slice_x,                                "slice_x");
1348     if (slice_x >= num_h_slices)
1349     {
1350         Param_Error("FFV1-SLICE-slice_xywh:1");
1351         Element_End0();
1352         return false;
1353     }
1354 
1355     Get_RU (States, slice_y,                                "slice_y");
1356     if (slice_y >= num_h_slices)
1357     {
1358         Param_Error("FFV1-SLICE-slice_xywh:1");
1359         Element_End0();
1360         return false;
1361     }
1362 
1363     Get_RU (States, slice_width_minus1,                     "slice_width_minus1");
1364     int32u slice_x2 = slice_x + slice_width_minus1 + 1; //right boundary
1365     if (slice_x2 > num_h_slices)
1366     {
1367         Param_Error("FFV1-SLICE-slice_xywh:1");
1368         Element_End0();
1369         return false;
1370     }
1371 
1372     Get_RU (States, slice_height_minus1,                    "slice_height_minus1");
1373     int32u slice_y2 = slice_y + slice_height_minus1 + 1; //bottom boundary
1374     if (slice_y2 > num_v_slices)
1375     {
1376         Param_Error("FFV1-SLICE-slice_xywh:1");
1377         Element_End0();
1378         return false;
1379     }
1380 
1381     current_slice = &slices[slice_x + slice_y * num_h_slices];
1382     current_slice->slice_x = slice_x;
1383     current_slice->slice_y = slice_y;
1384     current_slice->slice_w = slice_x2;
1385     current_slice->slice_h = slice_y2;
1386 
1387     //Computing boundaries, being careful about how are computed boundaries when there is not an integral number for Width  / num_h_slices or Height / num_v_slices (the last slice has more pixels)
1388     current_slice->x = slice_x  * Width  / num_h_slices;
1389     current_slice->y = slice_y  * Height / num_v_slices;
1390     current_slice->w = slice_x2 * Width  / num_h_slices - current_slice->x;
1391     current_slice->h = slice_y2 * Height / num_v_slices - current_slice->y;
1392 
1393 
1394     for (int8u i = 0; i < quant_table_index_count; i++)
1395     {
1396         Get_RU (States, quant_table_index[i],               "quant_table_index");
1397         if (quant_table_index[i]>=quant_table_count)
1398         {
1399             Param_Error("FFV1-SLICE-quant_table_index:1");
1400             Element_End0();
1401             return false;
1402         }
1403     }
1404     Get_RU (States, picture_structure,                      "picture_structure");
1405     if (picture_structure>3)
1406         Param_Error("FFV1-SLICE-picture_structure:1");
1407     Get_RU (States, sample_aspect_ratio_num,                "sar_num");
1408     Get_RU (States, sample_aspect_ratio_den,                "sar_den");
1409     if ((sample_aspect_ratio_num && !sample_aspect_ratio_den)) // || (!sample_aspect_ratio_num && sample_aspect_ratio_den)) // Second part is deactivated because FFmpeg creates such file when SAR is unknown
1410         Param_Error("FFV1-SLICE-sar_den:1");
1411     if (version > 3)
1412     {
1413         //TODO
1414     }
1415 
1416     RC->AssignStateTransitions(state_transitions_table);
1417 
1418     Element_End0();
1419     return true;
1420 }
1421 
1422 //---------------------------------------------------------------------------
plane(int32u pos)1423 void File_Ffv1::plane(int32u pos)
1424 {
1425     #if MEDIAINFO_TRACE_FFV1CONTENT
1426         Element_Begin1("Plane");
1427     #endif //MEDIAINFO_TRACE_FFV1CONTENT
1428 
1429     if (bits_per_raw_sample <= 8)
1430         bits_max = 8;
1431     else
1432         bits_max = bits_per_raw_sample;
1433     bits_mask1 = ((1 << bits_max) - 1);
1434     bits_mask2 = 1 << (bits_max - 1);
1435     bits_mask3 = bits_mask2 - 1;
1436 
1437     pixel_t *sample[2];
1438     sample[0] = current_slice->sample_buffer + 3;
1439     sample[1] = sample[0] + current_slice->w + 6;
1440 
1441     memset(current_slice->sample_buffer, 0, 2 * (current_slice->w + 6) * sizeof(*current_slice->sample_buffer));
1442 
1443     current_slice->run_index = 0;
1444 
1445     for (size_t y = 0; y < current_slice->h; y++)
1446     {
1447         #if MEDIAINFO_TRACE_FFV1CONTENT
1448             Element_Begin1("Line");
1449             Element_Info1(y);
1450         #endif //MEDIAINFO_TRACE_FFV1CONTENT
1451 
1452         swap(sample[0], sample[1]);
1453 
1454         sample[1][-1] = sample[0][0];
1455         sample[0][current_slice->w]  = sample[0][current_slice->w - 1];
1456 
1457         line(pos, sample);
1458 
1459         #if MEDIAINFO_TRACE_FFV1CONTENT
1460             Element_End0();
1461         #endif //MEDIAINFO_TRACE_FFV1CONTENT
1462     }
1463 
1464     #if MEDIAINFO_TRACE_FFV1CONTENT
1465         Element_End0();
1466     #endif //MEDIAINFO_TRACE_FFV1CONTENT
1467 }
1468 
1469 //---------------------------------------------------------------------------
rgb()1470 void File_Ffv1::rgb()
1471 {
1472     #if MEDIAINFO_TRACE_FFV1CONTENT
1473         Element_Begin1("rgb");
1474     #endif //MEDIAINFO_TRACE_FFV1CONTENT
1475 
1476     bits_max = bits_per_raw_sample + 1;
1477     bits_mask1 = (1 << bits_max) - 1;
1478     bits_mask2 = 1 << (bits_max - 1);
1479     bits_mask3 = bits_mask2-1;
1480 
1481     size_t c_max = alpha_plane ? 4 : 3;
1482 
1483     pixel_t *sample[4][2];
1484 
1485     current_slice->run_index = 0;
1486 
1487     for (size_t x = 0; x < c_max; x++) {
1488         sample[x][0] = current_slice->sample_buffer +  x * 2      * (current_slice->w + 6) + 3;
1489         sample[x][1] = sample[x][0] + current_slice->w + 6;
1490     }
1491     memset(current_slice->sample_buffer, 0, 8 * (current_slice->w + 6) * sizeof(*current_slice->sample_buffer));
1492 
1493     for (size_t y = 0; y < current_slice->h; y++)
1494     {
1495         #if MEDIAINFO_TRACE_FFV1CONTENT
1496             Element_Begin1("Line");
1497             Element_Info1(y);
1498         #endif //MEDIAINFO_TRACE_FFV1CONTENT
1499 
1500         for (size_t c = 0; c < c_max; c++)
1501         {
1502             // Copy for next lines: 4.3 context
1503             swap(sample[c][0], sample[c][1]);
1504 
1505             sample[c][1][-1]= sample[c][0][0  ];
1506             sample[c][0][current_slice->w]= sample[c][0][current_slice->w - 1];
1507 
1508             line((c + 1) / 2, sample[c]);
1509         }
1510 
1511         #if MEDIAINFO_TRACE_FFV1CONTENT
1512             Element_End0();
1513         #endif //MEDIAINFO_TRACE_FFV1CONTENT
1514     }
1515 
1516     #if MEDIAINFO_TRACE_FFV1CONTENT
1517         Element_End0();
1518     #endif //MEDIAINFO_TRACE_FFV1CONTENT
1519 }
1520 
1521 //---------------------------------------------------------------------------
get_median_number(int32s one,int32s two,int32s three)1522 static inline int32s get_median_number(int32s one, int32s two, int32s three)
1523 {
1524     if (one > two)
1525     {
1526         // one > two > three
1527         if (two > three)
1528             return two;
1529 
1530         // three > one > two
1531         if (three > one)
1532             return one;
1533         // one > three > two
1534         return three;
1535     }
1536 
1537     // three > two > one
1538     if (three > two)
1539         return two;
1540 
1541     // two > one && two > three
1542 
1543     // two > three > one
1544     if (three > one)
1545         return three;
1546     return one;
1547 }
1548 
1549 //---------------------------------------------------------------------------
predict(pixel_t * current,pixel_t * current_top,bool is_overflow_16bit)1550 static inline int32s predict(pixel_t *current, pixel_t *current_top, bool is_overflow_16bit)
1551 {
1552     int32s LeftTop, Top, Left;
1553     if (is_overflow_16bit)
1554     {
1555         LeftTop = (int16s)current_top[-1];
1556         Top = (int16s)current_top[0];
1557         Left = (int16s)current[-1];
1558     }
1559     else
1560     {
1561         LeftTop = current_top[-1];
1562         Top = current_top[0];
1563         Left = current[-1];
1564     }
1565 
1566     return get_median_number(Left, Left + Top - LeftTop, Top);
1567 }
1568 
1569 //---------------------------------------------------------------------------
get_context_3(pixel_t quant_table[MAX_CONTEXT_INPUTS][256],pixel_t * src,pixel_t * last)1570 static inline int get_context_3(pixel_t quant_table[MAX_CONTEXT_INPUTS][256], pixel_t *src, pixel_t *last)
1571 {
1572     const int LT = last[-1];
1573     const int T  = last[0];
1574     const int RT = last[1];
1575     const int L  = src[-1];
1576 
1577     return quant_table[0][(L - LT) & 0xFF]
1578         + quant_table[1][(LT - T) & 0xFF]
1579         + quant_table[2][(T - RT) & 0xFF];
1580 }
get_context_5(pixel_t quant_table[MAX_CONTEXT_INPUTS][256],pixel_t * src,pixel_t * last)1581 static inline int get_context_5(pixel_t quant_table[MAX_CONTEXT_INPUTS][256], pixel_t *src, pixel_t *last)
1582 {
1583     const int LT = last[-1];
1584     const int T  = last[0];
1585     const int RT = last[1];
1586     const int L  = src[-1];
1587     const int TT = src[0];
1588     const int LL = src[-2];
1589     return quant_table[0][(L - LT) & 0xFF]
1590         + quant_table[1][(LT - T) & 0xFF]
1591         + quant_table[2][(T - RT) & 0xFF]
1592         + quant_table[3][(LL - L) & 0xFF]
1593         + quant_table[4][(TT - T) & 0xFF];
1594 }
1595 
1596 //---------------------------------------------------------------------------
pixel_RC(int32s context)1597 int32s File_Ffv1::pixel_RC(int32s context)
1598 {
1599     int32s u;
1600 
1601     Get_RS(Context_RC[context], u, "symbol");
1602     return u;
1603 }
1604 
1605 
1606 //---------------------------------------------------------------------------
pixel_GR(int32s context)1607 int32s File_Ffv1::pixel_GR(int32s context)
1608 {
1609 #if MEDIAINFO_TRACE_FFV1CONTENT
1610     int32s u;
1611 
1612     // New symbol, go to "run mode"
1613     if (context == 0 && current_slice->run_mode == RUN_MODE_STOP)
1614         current_slice->run_mode = RUN_MODE_PROCESSING;
1615 
1616     // If not running, get the symbol
1617     if (current_slice->run_mode == RUN_MODE_STOP)
1618     {
1619         u = get_symbol_with_bias_correlation(&Context_GR[context]);
1620         #if MEDIAINFO_TRACE
1621         Param("symbol", u);
1622         #endif //MEDIAINFO_TRACE
1623         return u;
1624     }
1625 
1626     if (current_slice->run_segment_length == 0 && current_slice->run_mode == RUN_MODE_PROCESSING) // Same symbol length
1627     {
1628         bool hits;
1629         Get_SB (hits,                                           "hits/miss");
1630         //if (bsf.GetB()) // "hits"
1631         if (hits) // "hits"
1632         {
1633             current_slice->run_segment_length = run[current_slice->run_index];
1634             if (x + current_slice->run_segment_length <= current_slice->w) //Do not go further as the end of line
1635                 ++current_slice->run_index;
1636         }
1637         else // "miss"
1638         {
1639             //current_slice->run_segment_length = bsf.Get4(log2_run[current_slice->run_index]);
1640             int32u run_segment_length;
1641             Get_S4 (log2_run[current_slice->run_index], run_segment_length,  "run_segment_length");
1642             current_slice->run_segment_length=(int32s)run_segment_length;
1643             if (current_slice->run_index)
1644                 --current_slice->run_index;
1645             current_slice->run_mode = RUN_MODE_INTERRUPTED;
1646         }
1647     }
1648 
1649     current_slice->run_segment_length--;
1650     if (current_slice->run_segment_length < 0) // we passed the length of same symbol, time to get the new symbol
1651     {
1652         u = get_symbol_with_bias_correlation(&Context_GR[context]);
1653         #if MEDIAINFO_TRACE
1654         Param("symbol", u);
1655         #endif //MEDIAINFO_TRACE
1656         if (u >= 0) // GR(u - 1, ...)
1657             u++;
1658 
1659         // Time for the new symbol length run
1660         current_slice->run_mode_init();
1661         current_slice->run_segment_length = 0;
1662     } else // same symbol as previous pixel, no difference, waiting
1663         u = 0;
1664     return u;
1665 #else //MEDIAINFO_TRACE_FFV1CONTENT
1666     if (current_slice->run_mode == RUN_MODE_STOP)
1667     {
1668         if (context)
1669             return get_symbol_with_bias_correlation(&Context_GR[context]); // If not running, get the symbol
1670 
1671         current_slice->run_mode = RUN_MODE_PROCESSING; // New symbol, go to "run mode"
1672     }
1673 
1674     if (current_slice->run_segment_length == 0 && current_slice->run_mode == RUN_MODE_PROCESSING) // Same symbol length
1675     {
1676         if (BS->GetB()) // "hits"
1677         {
1678             current_slice->run_segment_length = run[current_slice->run_index];
1679             if (x + current_slice->run_segment_length <= current_slice->w) //Do not go further as the end of line
1680                 ++current_slice->run_index;
1681             if (--current_slice->run_segment_length >= 0)
1682                 return 0;
1683         }
1684         else // "miss"
1685         {
1686             current_slice->run_mode = RUN_MODE_INTERRUPTED;
1687 
1688             if (current_slice->run_index)
1689             {
1690                 int8u count = log2_run[current_slice->run_index--];
1691                 if (count)
1692                 {
1693                     current_slice->run_segment_length = ((int32s)BS->Get4(count)) - 1;
1694                     if (current_slice->run_segment_length >= 0)
1695                         return 0;
1696                 }
1697                 else
1698                     current_slice->run_segment_length = -1;
1699             }
1700             else
1701                 current_slice->run_segment_length = -1;
1702         }
1703     }
1704     else if (--current_slice->run_segment_length >= 0)
1705         return 0;
1706 
1707     // Time for the new symbol length run
1708     current_slice->run_mode_init();
1709 
1710     int32s u = get_symbol_with_bias_correlation(&Context_GR[context]);
1711     if (u >= 0) // GR(u - 1, ...)
1712         u++;
1713     return u;
1714 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1715 }
1716 
1717 //---------------------------------------------------------------------------
line(int pos,pixel_t * sample[2])1718 void File_Ffv1::line(int pos, pixel_t *sample[2])
1719 {
1720     // TODO: slice_coding_mode (version 4)
1721 
1722     quant_table_struct& quant_table = quant_tables[quant_table_index[pos]];
1723     bool Is5 = quant_table[3][127] ? true : false;
1724     pixel_t* s0c = sample[0];
1725     pixel_t* s0e = s0c + current_slice->w;
1726     pixel_t* s1c = sample[1];
1727 
1728     if (coder_type)
1729     {
1730         Context_RC = current_slice->plane_states[pos];
1731 
1732         while (s0c<s0e)
1733         {
1734             int32s context = Is5 ? get_context_5(quant_table, s1c, s0c) : get_context_3(quant_table, s1c, s0c);
1735 
1736             int32s Value = predict(s1c, s0c, is_overflow_16bit);
1737             #if MEDIAINFO_TRACE_FFV1CONTENT
1738                 if (context >= 0)
1739                     Value += pixel_RC(context);
1740                 else
1741                     Value -= pixel_RC(-context);
1742             #else //MEDIAINFO_TRACE_FFV1CONTENT
1743                 if (context >= 0)
1744                     Value += RC->get_symbol_s(Context_RC[context]);
1745                 else
1746                     Value -= RC->get_symbol_s(Context_RC[-context]);
1747             #endif //MEDIAINFO_TRACE_FFV1CONTENT;
1748             *s1c = Value & bits_mask1;
1749 
1750             s0c++;
1751             s1c++;
1752         }
1753     }
1754     else
1755     {
1756         current_slice->run_mode_init();
1757 
1758         Context_GR = current_slice->contexts[pos];
1759         x = 0;
1760 
1761         while (s0c < s0e)
1762         {
1763             int32s context = Is5 ? get_context_5(quant_table, s1c, s0c) : get_context_3(quant_table, s1c, s0c);
1764 
1765             *s1c = (predict(s1c, s0c, is_overflow_16bit) + (context >= 0 ? pixel_GR(context) : -pixel_GR(-context))) & bits_mask1;
1766 
1767             s0c++;
1768             s1c++;
1769             x++;
1770         }
1771     }
1772 }
1773 
1774 //---------------------------------------------------------------------------
QuantizationTable(size_t i)1775 bool File_Ffv1::QuantizationTable(size_t i)
1776 {
1777     Element_Begin1("QuantizationTableSet");
1778 
1779     FFV1::pixel_t scale = 1;
1780 
1781     for (size_t j = 0; j < 5; j++)
1782     {
1783         if (!QuantizationTablePerContext(i, j, scale))
1784         {
1785             Element_End0();
1786             return false;
1787         }
1788     }
1789     context_count[i] = (scale + 1) / 2;
1790 
1791     Element_End0();
1792     return true;
1793 }
1794 
1795 //---------------------------------------------------------------------------
QuantizationTablePerContext(size_t i,size_t j,FFV1::pixel_t & scale)1796 bool File_Ffv1::QuantizationTablePerContext(size_t i, size_t j, FFV1::pixel_t &scale)
1797 {
1798     Element_Begin1("QuantizationTable");
1799 
1800     int8u States[states_size];
1801     memset(States, 128, sizeof(States));
1802 
1803     FFV1::pixel_t v = 0;
1804     for (size_t k=0; k < 128;)
1805     {
1806         int32u len_minus1;
1807         Get_RU (States, len_minus1,                             "len_minus1");
1808 
1809         if (k+len_minus1 >= 128)
1810         {
1811             Param_Error("FFV1-HEADER-QuantizationTable-len:1");
1812             Element_End0();
1813             return false;
1814         }
1815 
1816         for (int32u a=0; a<=len_minus1; a++)
1817         {
1818             quant_tables[i][j][k] = scale * v;
1819             k++;
1820         }
1821 
1822         v++;
1823     }
1824 
1825     for (int k = 1; k < 128; k++)
1826         quant_tables[i][j][256 - k] = -quant_tables[i][j][k];
1827     quant_tables[i][j][128] = -quant_tables[i][j][127];
1828 
1829     scale *= 2 * v - 1;
1830     if (scale > 32768U)
1831     {
1832         Element_Error("FFV1-HEADER-QuantizationTable-scale:1");
1833         Element_End0();
1834         return false;
1835     }
1836 
1837     Element_End0();
1838     return true;
1839 }
1840 
1841 //***************************************************************************
1842 // Helpers
1843 //***************************************************************************
1844 
1845 //---------------------------------------------------------------------------
golomb_rice_decode(int k)1846 int32s File_Ffv1::golomb_rice_decode(int k)
1847 {
1848 #if MEDIAINFO_TRACE_FFV1CONTENT
1849     int32u q = 0;
1850     int32u v;
1851 
1852     //while (bsf.Remain() > 0 && q < PREFIX_MAX && !bsf.GetB())
1853     while (Data_BS_Remain() > 0 && q < PREFIX_MAX)
1854     {
1855         bool Temp;
1856         Get_SB(Temp,                                            "golomb_rice_prefix_0");
1857         if (Temp)
1858             break;
1859 
1860         ++q;
1861     }
1862 
1863     if (q == PREFIX_MAX) // ESC
1864     {
1865         //v = bsf.Get4(bits_max) + 11;
1866         Get_S4(bits_max, v,                                     "escaped_value_minus_11");
1867         v+=11;
1868     }
1869     else
1870     {
1871         //int32u remain = bsf.Get8(k); // Read k bits
1872         int32u remain;
1873         Get_S4(k, remain,                                       "golomb_rice_remain");
1874         int32u mul = q << k; // q * pow(2, k)
1875 
1876         v = mul | remain;
1877     }
1878 
1879     // unsigned to signed
1880     int32s code = (v >> 1) ^ -(v & 1);
1881     return code;
1882 #else //MEDIAINFO_TRACE_FFV1CONTENT
1883     int8u q = 0;
1884     while (BS->Remain() && !BS->GetB())
1885         if (++q >= PREFIX_MAX)
1886         {
1887             int32s v = 11 + BS->Get4(bits_max);
1888 
1889             // unsigned to signed
1890             return (v >> 1) ^ -(v & 1);
1891         }
1892 
1893     int32s v = (q << k) | BS->Get4(k);
1894 
1895     // unsigned to signed
1896     return (v >> 1) ^ -(v & 1);
1897 #endif //MEDIAINFO_TRACE_FFV1CONTENT
1898 }
1899 
1900 //---------------------------------------------------------------------------
get_symbol_with_bias_correlation(Slice::ContextPtr context)1901 int32s File_Ffv1::get_symbol_with_bias_correlation(Slice::ContextPtr context)
1902 {
1903     int k = 0;
1904     // Step 8: compute the Golomb parameter k
1905     for (k = 0; (context->N << k) < context->A; ++k);
1906 
1907     // Step 10: Decode Golomb code (using limitation PREFIX_MAX == 12)
1908     int32s code = golomb_rice_decode(k);
1909 
1910     // Step 9: Mapping
1911     int32s M = 2 * context->B + context->N;
1912     code = code ^ (M >> 31);
1913 
1914     // Step 11
1915     context->B += code;
1916     context->A += code >= 0 ? code : -code;
1917 
1918     code += context->C;
1919 
1920     context->update_correlation_value_and_shift();
1921 
1922     // Step 7 (TODO better way)
1923     bool neg = code & bits_mask2; // check if the number is negative
1924     code = code & bits_mask3; // Keep only the n bits
1925     if (neg)
1926         code = - 1 - (~code & bits_mask3); // 0xFFFFFFFF - positive value on n bits
1927 
1928     return code;
1929 }
1930 
1931 //---------------------------------------------------------------------------
copy_plane_states_to_slice(int8u plane_count)1932 void File_Ffv1::copy_plane_states_to_slice(int8u plane_count)
1933 {
1934     if (!coder_type)
1935         return;
1936 
1937     for (size_t i = 0; i < plane_count; i++)
1938     {
1939         int32u idx = quant_table_index[i];
1940 
1941         if (current_slice->plane_states[i] && current_slice->plane_states_maxsizes[i] < context_count[idx] + 1)
1942         {
1943             for (size_t j = 0; current_slice->plane_states[i][j]; ++j)
1944                 delete[] current_slice->plane_states[i][j];
1945 
1946             delete[] current_slice->plane_states[i];
1947             current_slice->plane_states[i] = NULL;
1948         }
1949 
1950         if (!current_slice->plane_states[i])
1951         {
1952             current_slice->plane_states[i] = new int8u*[context_count[idx] + 1];
1953             current_slice->plane_states_maxsizes[i] = context_count[idx] + 1;
1954             memset(current_slice->plane_states[i], 0, (context_count[idx] + 1) * sizeof(int8u*));
1955         }
1956 
1957         for (size_t j = 0; j < context_count[idx]; j++)
1958         {
1959             if (!current_slice->plane_states[i][j])
1960                 current_slice->plane_states[i][j] = new int8u [states_size];
1961             for (size_t k = 0; k < states_size; k++)
1962             {
1963                 current_slice->plane_states[i][j][k] = plane_states[idx][j][k];
1964             }
1965         }
1966     }
1967 }
1968 
1969 //---------------------------------------------------------------------------
plane_states_clean(states_context_plane states[MAX_QUANT_TABLES])1970 void File_Ffv1::plane_states_clean(states_context_plane states[MAX_QUANT_TABLES])
1971 {
1972     if (!coder_type)
1973         return;
1974 
1975     for (size_t i = 0; i < MAX_QUANT_TABLES && states[i]; ++i)
1976     {
1977         for (size_t j = 0; states[i][j]; ++j)
1978             delete[] states[i][j];
1979 
1980         delete[] states[i];
1981         states[i] = NULL;
1982     }
1983 }
1984 
1985 } //NameSpace
1986 
1987 #endif //MEDIAINFO_FFV1_YES
1988