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_FLAC_YES)
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Audio/File_Flac.h"
25 #include "MediaInfo/Tag/File_VorbisCom.h"
26 #include "ThirdParty/base64/base64.h"
27 //---------------------------------------------------------------------------
28 
29 namespace MediaInfoLib
30 {
31 
32 //***************************************************************************
33 // Infos
34 //***************************************************************************
35 
36 //---------------------------------------------------------------------------
37 extern const char* Id3v2_PictureType(int8u Type); //In Tag/File_Id3v2.cpp
38 extern std::string ExtensibleWave_ChannelMask (int32u ChannelMask); //In Multiple/File_Riff_Elements.cpp
39 extern std::string ExtensibleWave_ChannelMask2 (int32u ChannelMask); //In Multiple/File_Riff_Elements.cpp
40 extern std::string ExtensibleWave_ChannelMask_ChannelLayout(int32u ChannelMask); //In Multiple/File_Riff_Elements.cpp
41 
42 //***************************************************************************
43 // Constructor/Destructor
44 //***************************************************************************
45 
46 //---------------------------------------------------------------------------
File_Flac()47 File_Flac::File_Flac()
48 :File__Analyze(), File__Tags_Helper()
49 {
50     //File__Tags_Helper
51     Base=this;
52 
53     //In
54     VorbisHeader=false;
55 
56     //Temp
57     Last_metadata_block=false;
58 }
59 
60 //***************************************************************************
61 // Buffer - File header
62 //***************************************************************************
63 
64 //---------------------------------------------------------------------------
FileHeader_Begin()65 bool File_Flac::FileHeader_Begin()
66 {
67     if (!File__Tags_Helper::FileHeader_Begin())
68         return false;
69 
70     //Element_Size
71     if (Buffer_Size<Buffer_Offset+4+(VorbisHeader?9:0))
72         return false; //Must wait for more data
73 
74     if (CC4(Buffer+Buffer_Offset+(VorbisHeader?9:0))!=0x664C6143) //"fLaC"
75     {
76         File__Tags_Helper::Finish("Flac");
77         return false;
78     }
79 
80     //All should be OK...
81     return true;
82 }
83 
84 //---------------------------------------------------------------------------
FileHeader_Parse()85 void File_Flac::FileHeader_Parse()
86 {
87     //Parsing
88     if (VorbisHeader)
89     {
90         Skip_B1(                                                "Signature");
91         Skip_Local(4,                                           "Signature");
92         Skip_B1(                                                "Major version");
93         Skip_B1(                                                "Minor version");
94         Skip_B2(                                                "Number of header");
95     }
96     Skip_C4(                                                    "Signature");
97 }
98 
99 //***************************************************************************
100 // Buffer - Per element
101 //***************************************************************************
102 
103 //---------------------------------------------------------------------------
Header_Parse()104 void File_Flac::Header_Parse()
105 {
106     //Parsing
107     int32u Length;
108     int8u BLOCK_TYPE;
109     BS_Begin();
110     Get_SB (   Last_metadata_block,                             "Last-metadata-block");
111     Get_S1 (7, BLOCK_TYPE,                                      "BLOCK_TYPE");
112     BS_End();
113     Get_B3 (Length,                                             "Length");
114 
115     //Filling
116     Header_Fill_Code(BLOCK_TYPE, Ztring().From_CC1(BLOCK_TYPE));
117     Header_Fill_Size(Element_Offset+Length);
118 }
119 
120 //---------------------------------------------------------------------------
Data_Parse()121 void File_Flac::Data_Parse()
122 {
123     #define CASE_INFO(_NAME) \
124         case Flac::_NAME : Element_Info1(#_NAME); _NAME(); break;
125 
126     //Parsing
127     switch ((int16u)Element_Code)
128     {
129         CASE_INFO(STREAMINFO);
130         CASE_INFO(PADDING);
131         CASE_INFO(APPLICATION);
132         CASE_INFO(SEEKTABLE);
133         CASE_INFO(VORBIS_COMMENT);
134         CASE_INFO(CUESHEET);
135         CASE_INFO(PICTURE);
136         default : Skip_XX(Element_Size,                         "Data");
137     }
138 
139     if (Last_metadata_block)
140     {
141         if (!IsSub)
142             Fill(Stream_Audio, 0, Audio_StreamSize, File_Size-(File_Offset+Buffer_Offset+Element_Size));
143 
144     if (Retrieve(Stream_Audio, 0, Audio_ChannelPositions).empty() && Retrieve(Stream_Audio, 0, Audio_ChannelPositions_String2).empty())
145     {
146         int32u t = 0;
147         int32s c = Retrieve(Stream_Audio, 0, Audio_Channel_s_).To_int32s();
148         if (c==1) t=4;
149         else if (c==2) t=3;
150         else if (c==3) t=7;
151         else if (c==4) t=1539;
152         else if (c==5) t=1543;
153         else if (c==6) t=1551;
154         else if (c==7) t=1807;
155         else if (c==8) t=1599;
156         if (t) {
157             Fill(Stream_Audio, 0, Audio_ChannelPositions, ExtensibleWave_ChannelMask(t));
158             Fill(Stream_Audio, 0, Audio_ChannelPositions_String2, ExtensibleWave_ChannelMask2(t));
159             Fill(Stream_Audio, 0, Audio_ChannelLayout, ExtensibleWave_ChannelMask_ChannelLayout(t));
160         }
161     }
162 
163         //No more need data
164         File__Tags_Helper::Finish("Flac");
165     }
166 }
167 
168 //***************************************************************************
169 // Elements
170 //***************************************************************************
171 
172 //---------------------------------------------------------------------------
STREAMINFO()173 void File_Flac::STREAMINFO()
174 {
175     //Parsing
176     int64u Samples;
177     int32u FrameSize_Min, FrameSize_Max, SampleRate;
178     int8u  Channels, BitPerSample;
179     Skip_B2(                                                    "BlockSize_Min"); //The minimum block size (in samples) used in the stream.
180     Skip_B2(                                                    "BlockSize_Max"); //The maximum block size (in samples) used in the stream. (Minimum blocksize == maximum blocksize) implies a fixed-blocksize stream.
181     Get_B3 (    FrameSize_Min,                                  "FrameSize_Min"); //The minimum frame size (in bytes) used in the stream. May be 0 to imply the value is not known.
182     Get_B3 (    FrameSize_Max,                                  "FrameSize_Max"); //The maximum frame size (in bytes) used in the stream. May be 0 to imply the value is not known.
183     BS_Begin();
184     Get_S3 (20, SampleRate,                                     "SampleRate"); //Sample rate in Hz. Though 20 bits are available, the maximum sample rate is limited by the structure of frame headers to 1048570Hz. Also, a value of 0 is invalid.
185     Get_S1 ( 3, Channels,                                       "Channels"); Param_Info2(Channels+1, " channels"); //(number of channels)-1. FLAC supports from 1 to 8 channels
186     Get_S1 ( 5, BitPerSample,                                   "BitPerSample"); Param_Info2(BitPerSample+1, " bits"); //(bits per sample)-1. FLAC supports from 4 to 32 bits per sample. Currently the reference encoder and decoders only support up to 24 bits per sample.
187     Get_S5 (36, Samples,                                        "Samples");
188     BS_End();
189     Skip_B16(                                                   "MD5 signature of the unencoded audio data");
190 
191     FILLING_BEGIN();
192         if (SampleRate==0)
193             return;
194         File__Tags_Helper::Accept("FLAC");
195 
196         File__Tags_Helper::Streams_Fill();
197 
198         File__Tags_Helper::Stream_Prepare(Stream_Audio);
199         Fill(Stream_Audio, 0, Audio_Format, "FLAC");
200         Fill(Stream_Audio, 0, Audio_Codec, "FLAC");
201         if (FrameSize_Min==FrameSize_Max && FrameSize_Min!=0 ) // 0 means it is unknown
202             Fill(Stream_Audio, 0, Audio_BitRate_Mode, "CBR");
203          else
204             Fill(Stream_Audio, 0, Audio_BitRate_Mode, "VBR");
205         Fill(Stream_Audio, 0, Audio_SamplingRate, SampleRate);
206         Fill(Stream_Audio, 0, Audio_Channel_s_, Channels+1);
207         Fill(Stream_Audio, 0, Audio_BitDepth, BitPerSample+1);
208         if (!IsSub)
209             Fill(Stream_Audio, 0, Audio_Duration, Samples*1000/SampleRate);
210     FILLING_END();
211 }
212 
213 //---------------------------------------------------------------------------
APPLICATION()214 void File_Flac::APPLICATION()
215 {
216     //Parsing
217     Skip_C4(                                                    "Application");
218     if (Element_Size>4)
219         Skip_XX(Element_Size-4,                                 "(Application specific)");
220 }
221 
222 //---------------------------------------------------------------------------
VORBIS_COMMENT()223 void File_Flac::VORBIS_COMMENT()
224 {
225     //Parsing
226     #if defined(MEDIAINFO_VORBISCOM_YES)
227         File_VorbisCom VorbisCom;
228         VorbisCom.StreamKind_Specific=Stream_Audio;
229         Open_Buffer_Init(&VorbisCom);
230         Open_Buffer_Continue(&VorbisCom);
231         File__Analyze::Finish(&VorbisCom);
232 
233         //Specific case: bit depth
234         if (!VorbisCom.Retrieve(Stream_Audio, 0, Audio_BitDepth).empty() && VorbisCom.Retrieve(Stream_Audio, 0, Audio_BitDepth).To_int64u()<Retrieve(Stream_Audio, 0, Audio_BitDepth).To_int64u())
235         {
236             //Bit depth information from tags is the real value, the one from Flac is the count of bits stored
237             Fill(Stream_Audio, 0, Audio_BitDepth_Stored, Retrieve(Stream_Audio, 0, Audio_BitDepth));
238             Fill(Stream_Audio, 0, Audio_BitDepth, VorbisCom.Retrieve(Stream_Audio, 0, Audio_BitDepth), true);
239             VorbisCom.Clear(Stream_Audio, 0, Audio_BitDepth);
240         }
241 
242         Merge(VorbisCom, Stream_General,  0, 0);
243         Merge(VorbisCom, Stream_Audio,    0, 0);
244         Merge(VorbisCom, Stream_Menu,     0, 0);
245     #else
246         Skip_XX(Element_Offset,                                 "Data");
247     #endif
248 }
249 
250 //---------------------------------------------------------------------------
PICTURE()251 void File_Flac::PICTURE()
252 {
253     //Parsing
254     int32u PictureType, MimeType_Size, Description_Size, Data_Size;
255     Ztring MimeType, Description;
256     Get_B4 (PictureType,                                        "Picture type"); Element_Info1(Id3v2_PictureType((int8u)PictureType));
257     Get_B4 (MimeType_Size,                                      "MIME type size");
258     Get_UTF8(MimeType_Size, MimeType,                           "MIME type");
259     Get_B4 (Description_Size,                                   "Description size");
260     Get_UTF8(Description_Size, Description,                     "Description");
261     Skip_B4(                                                    "Width");
262     Skip_B4(                                                    "Height");
263     Skip_B4(                                                    "Color depth");
264     Skip_B4(                                                    "Number of colors used");
265     Get_B4 (Data_Size,                                          "Data size");
266     if (Element_Offset+Data_Size>Element_Size)
267         return; //There is a problem
268 
269     //Filling
270     Fill(Stream_General, 0, General_Cover, "Yes");
271     Fill(Stream_General, 0, General_Cover_Description, Description);
272     Fill(Stream_General, 0, General_Cover_Type, Id3v2_PictureType((int8u)PictureType));
273     Fill(Stream_General, 0, General_Cover_Mime, MimeType);
274     #if MEDIAINFO_ADVANCED
275         if (MediaInfoLib::Config.Flags1_Get(Flags_Cover_Data_base64))
276         {
277             std::string Data_Raw((const char*)(Buffer+(size_t)(Buffer_Offset+Element_Offset)), Data_Size);
278             std::string Data_Base64(Base64::encode(Data_Raw));
279             Fill(Stream_General, 0, General_Cover_Data, Data_Base64);
280         }
281     #endif //MEDIAINFO_ADVANCED
282 
283     Skip_XX(Data_Size,                                          "Data");
284     if (Element_Offset<Element_Size)
285         Skip_XX(Element_Size-Element_Offset,                    "?");
286 }
287 
288 } //NameSpace
289 
290 #endif //MEDIAINFO_FLAC_YES
291 
292 
293