1 /*
2    mkvmerge -- utility for splicing together matroska files
3    from component media subtypes
4 
5    Distributed under the GPL v2
6    see the file COPYING for details
7    or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8 
9    FLAC helper functions
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #include "config.h"
15 
16 #if defined(HAVE_FLAC_FORMAT_H)
17 
18 #include "common/common_pch.h"
19 
20 #include <FLAC/stream_decoder.h>
21 #include <cstdarg>
22 
23 #include "common/bit_reader.h"
24 #include "common/flac.h"
25 #include "common/mm_io_x.h"
26 
27 namespace mtx::flac {
28 
29 static FLAC__StreamDecoderReadStatus
flac_read_cb(const FLAC__StreamDecoder *,FLAC__byte buffer[],size_t * bytes,void * client_data)30 flac_read_cb(const FLAC__StreamDecoder *,
31              FLAC__byte buffer[],
32              size_t *bytes,
33              void *client_data) {
34   return reinterpret_cast<decoder_c *>(client_data)->flac_read_cb(buffer, bytes);
35 }
36 
37 static FLAC__StreamDecoderWriteStatus
flac_write_cb(const FLAC__StreamDecoder *,const FLAC__Frame * frame,const FLAC__int32 * const data[],void * client_data)38 flac_write_cb(const FLAC__StreamDecoder *,
39               const FLAC__Frame *frame,
40               const FLAC__int32 * const data[],
41               void *client_data) {
42   return reinterpret_cast<decoder_c *>(client_data)->flac_write_cb(frame, data);
43 }
44 
45 static void
flac_metadata_cb(const FLAC__StreamDecoder *,const FLAC__StreamMetadata * metadata,void * client_data)46 flac_metadata_cb(const FLAC__StreamDecoder *,
47                  const FLAC__StreamMetadata *metadata,
48                  void *client_data) {
49   reinterpret_cast<decoder_c *>(client_data)->flac_metadata_cb(metadata);
50 }
51 
52 static void
flac_error_cb(const FLAC__StreamDecoder *,FLAC__StreamDecoderErrorStatus status,void * client_data)53 flac_error_cb(const FLAC__StreamDecoder *,
54               FLAC__StreamDecoderErrorStatus status,
55               void *client_data) {
56   reinterpret_cast<decoder_c *>(client_data)->flac_error_cb(status);
57 }
58 
59 static FLAC__StreamDecoderSeekStatus
flac_seek_cb(const FLAC__StreamDecoder *,FLAC__uint64 absolute_byte_offset,void * client_data)60 flac_seek_cb(const FLAC__StreamDecoder *,
61              FLAC__uint64 absolute_byte_offset,
62              void *client_data) {
63   return reinterpret_cast<decoder_c *>(client_data)->flac_seek_cb(absolute_byte_offset);
64 }
65 
66 static FLAC__StreamDecoderTellStatus
flac_tell_cb(const FLAC__StreamDecoder *,FLAC__uint64 * absolute_byte_offset,void * client_data)67 flac_tell_cb(const FLAC__StreamDecoder *,
68              FLAC__uint64 *absolute_byte_offset,
69              void *client_data) {
70   return reinterpret_cast<decoder_c *>(client_data)->flac_tell_cb(*absolute_byte_offset);
71 }
72 
73 static FLAC__StreamDecoderLengthStatus
flac_length_cb(const FLAC__StreamDecoder *,FLAC__uint64 * stream_length,void * client_data)74 flac_length_cb(const FLAC__StreamDecoder *,
75                FLAC__uint64 *stream_length,
76                void *client_data) {
77   return reinterpret_cast<decoder_c *>(client_data)->flac_length_cb(*stream_length);
78 }
79 
80 static FLAC__bool
flac_eof_cb(const FLAC__StreamDecoder *,void * client_data)81 flac_eof_cb(const FLAC__StreamDecoder *,
82             void *client_data) {
83   return reinterpret_cast<decoder_c *>(client_data)->flac_eof_cb();
84 }
85 
86 // ----------------------------------------------------------------------
87 
88 void
flac_metadata_cb(const FLAC__StreamMetadata *)89 decoder_c::flac_metadata_cb(const FLAC__StreamMetadata *) {
90 }
91 
92 void
flac_error_cb(FLAC__StreamDecoderErrorStatus)93 decoder_c::flac_error_cb(FLAC__StreamDecoderErrorStatus) {
94 }
95 
96 FLAC__StreamDecoderSeekStatus
flac_seek_cb(uint64_t)97 decoder_c::flac_seek_cb(uint64_t) {
98   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
99 }
100 
101 FLAC__StreamDecoderTellStatus
flac_tell_cb(uint64_t &)102 decoder_c::flac_tell_cb(uint64_t &) {
103   return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
104 }
105 
106 FLAC__StreamDecoderLengthStatus
flac_length_cb(uint64_t &)107 decoder_c::flac_length_cb(uint64_t &) {
108   return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
109 }
110 
111 FLAC__bool
flac_eof_cb()112 decoder_c::flac_eof_cb() {
113   return false;
114 }
115 
116 FLAC__StreamDecoderReadStatus
flac_read_cb(FLAC__byte[],size_t *)117 decoder_c::flac_read_cb(FLAC__byte [],
118                         size_t *) {
119   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
120 }
121 
122 FLAC__StreamDecoderWriteStatus
flac_write_cb(FLAC__Frame const *,FLAC__int32 const * const[])123 decoder_c::flac_write_cb(FLAC__Frame const *,
124                          FLAC__int32 const * const[]) {
125   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
126 }
127 
128 void
init_flac_decoder()129 decoder_c::init_flac_decoder() {
130   m_flac_decoder.reset(FLAC__stream_decoder_new());
131   if (!m_flac_decoder)
132     mxerror(Y("flac_decoder: FLAC__stream_decoder_new() failed.\n"));
133 
134   if (!FLAC__stream_decoder_set_metadata_respond_all(m_flac_decoder.get()))
135     mxerror(Y("flac_decoder: Could not set metadata_respond_all.\n"));
136 
137   if (FLAC__stream_decoder_init_stream(m_flac_decoder.get(), mtx::flac::flac_read_cb, mtx::flac::flac_seek_cb, mtx::flac::flac_tell_cb, mtx::flac::flac_length_cb, mtx::flac::flac_eof_cb,
138                                        mtx::flac::flac_write_cb, mtx::flac::flac_metadata_cb, mtx::flac::flac_error_cb, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
139     mxerror(Y("flac_decoder: Could not initialize the FLAC decoder.\n"));
140 }
141 
142 // ----------------------------------------------------------------------
143 
144 static bool
skip_utf8(mtx::bits::reader_c & bits,int size)145 skip_utf8(mtx::bits::reader_c &bits,
146           int size) {
147 
148   uint32_t value = bits.get_bits(8);
149 
150   int num;
151   if (!(value & 0x80))          /* 0xxxxxxx */
152     num = 0;
153   else if ((value & 0xC0) && !(value & 0x20)) /* 110xxxxx */
154     num = 1;
155   else if ((value & 0xE0) && !(value & 0x10)) /* 1110xxxx */
156     num = 2;
157   else if ((value & 0xF0) && !(value & 0x08)) /* 11110xxx */
158     num = 3;
159   else if ((value & 0xF8) && !(value & 0x04)) /* 111110xx */
160     num = 4;
161   else if ((value & 0xFC) && !(value & 0x02)) /* 1111110x */
162     num = 5;
163   else if ((size == 64) && (value & 0xFE) && !(value & 0x01)) /* 11111110 */
164     num = 6;
165   else
166     return false;
167 
168   bits.skip_bits(num * 8);
169 
170   return true;
171 }
172 
173 // See http://flac.sourceforge.net/format.html#frame_header
174 static int
get_num_samples_internal(unsigned char const * mem,int size,FLAC__StreamMetadata_StreamInfo const & stream_info)175 get_num_samples_internal(unsigned char const *mem,
176                          int size,
177                          FLAC__StreamMetadata_StreamInfo const &stream_info) {
178   mtx::bits::reader_c bits(mem, size);
179 
180   // Sync word: 11 1111 1111 1110
181   if (bits.peek_bits(14) != 0x3ffe)
182     return -1;
183 
184   bits.skip_bits(14);
185 
186   // Reserved
187   bits.skip_bits(2);
188 
189   // Block size
190   uint32_t value       = bits.get_bits(4);
191   int free_sample_size = 0;
192   int samples          = 0;
193 
194   if (0 == value)
195     samples = stream_info.min_blocksize;
196   else if (1 == value)
197     samples = 192;
198   else if ((2 <= value) && (5 >= value))
199     samples = 576 << (value - 2);
200   else if (8 <= value)
201     samples = 256 << (value - 8);
202   else
203     free_sample_size = value;
204 
205   // Sample rate
206   bits.skip_bits(4);
207 
208   // Channel assignment
209   bits.skip_bits(4);
210 
211   // Sample size (3 bits) and zero bit padding (1 bit)
212   bits.skip_bits(4);
213 
214   if (stream_info.min_blocksize != stream_info.max_blocksize) {
215     if (!skip_utf8(bits, 64))
216       return -1;
217 
218   } else if (!skip_utf8(bits, 32))
219       return -1;
220 
221   if ((6 == free_sample_size) || (7 == free_sample_size)) {
222     samples = bits.get_bits(8);
223     if (7 == free_sample_size) {
224       samples <<= 8;
225       samples  |= bits.get_bits(8);
226     }
227     samples++;
228   }
229 
230   // CRC
231   bits.skip_bits(8);
232 
233   return samples;
234 }
235 
236 int
get_num_samples(unsigned char const * mem,int size,FLAC__StreamMetadata_StreamInfo const & stream_info)237 get_num_samples(unsigned char const *mem,
238                 int size,
239                 FLAC__StreamMetadata_StreamInfo const &stream_info) {
240   try {
241     return get_num_samples_internal(mem, size, stream_info);
242   } catch(...) {
243     return -1;
244   }
245 }
246 
247 struct header_extractor_t {
248   unsigned char const *mem;
249   unsigned int size;
250   unsigned int nread;
251 
252   FLAC__StreamMetadata_StreamInfo stream_info;
253   bool stream_info_found;
254 };
255 
256 static FLAC__StreamDecoderReadStatus
read_cb(FLAC__StreamDecoder const *,FLAC__byte buffer[],size_t * bytes,void * client_data)257 read_cb(FLAC__StreamDecoder const *,
258         FLAC__byte buffer[],
259         size_t *bytes,
260         void *client_data) {
261   auto fhe = (header_extractor_t *)client_data;
262 
263   if (fhe->nread == fhe->size)
264     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
265 
266   size_t num_bytes = *bytes > (fhe->size - fhe->nread) ? (fhe->size - fhe->nread) : *bytes;
267   memcpy(buffer, &fhe->mem[fhe->nread], num_bytes);
268   fhe->nread += num_bytes;
269   *bytes      = num_bytes;
270 
271   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
272 }
273 
274 static void
metadata_cb(FLAC__StreamDecoder const *,FLAC__StreamMetadata const * metadata,void * client_data)275 metadata_cb(FLAC__StreamDecoder const *,
276             FLAC__StreamMetadata const *metadata,
277             void *client_data) {
278   auto fhe = (header_extractor_t *)client_data;
279   if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
280     memcpy(&fhe->stream_info, &metadata->data.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo));
281     fhe->stream_info_found = true;
282   }
283 }
284 
285 static FLAC__StreamDecoderWriteStatus
write_cb(FLAC__StreamDecoder const *,FLAC__Frame const *,FLAC__int32 const * const[],void *)286 write_cb(FLAC__StreamDecoder const *,
287          FLAC__Frame const *,
288          FLAC__int32 const * const [],
289          void *) {
290   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
291 }
292 
293 static void
error_cb(FLAC__StreamDecoder const *,FLAC__StreamDecoderErrorStatus,void *)294 error_cb(FLAC__StreamDecoder const *,
295          FLAC__StreamDecoderErrorStatus,
296          void *) {
297 }
298 
299 int
decode_headers(unsigned char const * mem,int size,int num_elements,...)300 decode_headers(unsigned char const *mem,
301                int size,
302                int num_elements,
303                ...) {
304   header_extractor_t fhe;
305   FLAC__StreamDecoder *decoder;
306   int result, i;
307   va_list ap;
308 
309   if (!mem || (0 >= size))
310     return -1;
311 
312   memset(&fhe, 0, sizeof(header_extractor_t));
313   fhe.mem  = mem;
314   fhe.size = size;
315 
316   decoder  = FLAC__stream_decoder_new();
317 
318   if (!decoder)
319     mxerror("flac_decode_headers: FLAC__stream_decoder_new() failed.\n");
320   if (!FLAC__stream_decoder_set_metadata_respond_all(decoder))
321     mxerror("flac_decode_headers: Could not set metadata_respond_all.\n");
322   if (FLAC__stream_decoder_init_stream(decoder, read_cb, nullptr, nullptr, nullptr, nullptr, write_cb, metadata_cb, error_cb, &fhe) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
323     mxerror("flac_decode_headers: Could not initialize the FLAC decoder.\n");
324 
325   FLAC__stream_decoder_process_until_end_of_stream(decoder);
326 
327   result = 0;
328   if (fhe.stream_info_found)
329     result |= HEADER_STREAM_INFO;
330 
331   va_start(ap, num_elements);
332   for (i = 0; i < num_elements; ++i) {
333     int type;
334 
335     type = va_arg(ap, int);
336     if (type != HEADER_STREAM_INFO)
337       continue;
338 
339     FLAC__StreamMetadata_StreamInfo *stream_info;
340 
341     stream_info = va_arg(ap, FLAC__StreamMetadata_StreamInfo *);
342     if (result & HEADER_STREAM_INFO)
343       memcpy(stream_info, &fhe.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo));
344 
345     break;
346   }
347   va_end(ap);
348 
349   FLAC__stream_decoder_delete(decoder);
350 
351   return result;
352 }
353 
354 std::string
file_base_name_for_picture_type(unsigned int type)355 file_base_name_for_picture_type(unsigned int type) {
356   return type == FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER                ? "other"
357        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD   ? "icon"
358        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON            ? "other icon"
359        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER          ? "cover"
360        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER           ? "cover (back)"
361        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE         ? "leaflet page"
362        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA                ? "media"
363        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST          ? "lead artist - lead performer - soloist"
364        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST               ? "artist - performer"
365        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR            ? "conductor"
366        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_BAND                 ? "band - orchestra"
367        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER             ? "composer"
368        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST             ? "lyricist - text writer"
369        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION   ? "recording location"
370        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING     ? "during recording"
371        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE   ? "during performance"
372        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE ? "movie - video screen capture"
373        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_FISH                 ? "a bright coloured fish"
374        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION         ? "illustration"
375        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE        ? "band - artist logotype"
376        : type == FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE   ? "publisher - Studio logotype"
377        :                                                                   "unknown";
378 }
379 
380 }                              // namespace mtx::flac
381 
382 #endif
383