1 /* test_libFLAC - Unit tester for libFLAC
2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*
20 * These are not tests, just utility functions used by the metadata tests
21 */
22
23 #if HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include "FLAC/metadata.h"
28 #include "test_libs_common/metadata_utils.h"
29 #include <stdio.h>
30 #include <stdlib.h> /* for malloc() */
31 #include <string.h> /* for memcmp() */
32
mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo * block,const FLAC__StreamMetadata_StreamInfo * blockcopy)33 FLAC__bool mutils__compare_block_data_streaminfo(const FLAC__StreamMetadata_StreamInfo *block, const FLAC__StreamMetadata_StreamInfo *blockcopy)
34 {
35 if(blockcopy->min_blocksize != block->min_blocksize) {
36 printf("FAILED, min_blocksize mismatch, expected %u, got %u\n", block->min_blocksize, blockcopy->min_blocksize);
37 return false;
38 }
39 if(blockcopy->max_blocksize != block->max_blocksize) {
40 printf("FAILED, max_blocksize mismatch, expected %u, got %u\n", block->max_blocksize, blockcopy->max_blocksize);
41 return false;
42 }
43 if(blockcopy->min_framesize != block->min_framesize) {
44 printf("FAILED, min_framesize mismatch, expected %u, got %u\n", block->min_framesize, blockcopy->min_framesize);
45 return false;
46 }
47 if(blockcopy->max_framesize != block->max_framesize) {
48 printf("FAILED, max_framesize mismatch, expected %u, got %u\n", block->max_framesize, blockcopy->max_framesize);
49 return false;
50 }
51 if(blockcopy->sample_rate != block->sample_rate) {
52 printf("FAILED, sample_rate mismatch, expected %u, got %u\n", block->sample_rate, blockcopy->sample_rate);
53 return false;
54 }
55 if(blockcopy->channels != block->channels) {
56 printf("FAILED, channels mismatch, expected %u, got %u\n", block->channels, blockcopy->channels);
57 return false;
58 }
59 if(blockcopy->bits_per_sample != block->bits_per_sample) {
60 printf("FAILED, bits_per_sample mismatch, expected %u, got %u\n", block->bits_per_sample, blockcopy->bits_per_sample);
61 return false;
62 }
63 if(blockcopy->total_samples != block->total_samples) {
64 #ifdef _MSC_VER
65 printf("FAILED, total_samples mismatch, expected %I64u, got %I64u\n", block->total_samples, blockcopy->total_samples);
66 #else
67 printf("FAILED, total_samples mismatch, expected %llu, got %llu\n", (unsigned long long)block->total_samples, (unsigned long long)blockcopy->total_samples);
68 #endif
69 return false;
70 }
71 if(0 != memcmp(blockcopy->md5sum, block->md5sum, sizeof(block->md5sum))) {
72 printf("FAILED, md5sum mismatch, expected %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X, got %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
73 (unsigned)block->md5sum[0],
74 (unsigned)block->md5sum[1],
75 (unsigned)block->md5sum[2],
76 (unsigned)block->md5sum[3],
77 (unsigned)block->md5sum[4],
78 (unsigned)block->md5sum[5],
79 (unsigned)block->md5sum[6],
80 (unsigned)block->md5sum[7],
81 (unsigned)block->md5sum[8],
82 (unsigned)block->md5sum[9],
83 (unsigned)block->md5sum[10],
84 (unsigned)block->md5sum[11],
85 (unsigned)block->md5sum[12],
86 (unsigned)block->md5sum[13],
87 (unsigned)block->md5sum[14],
88 (unsigned)block->md5sum[15],
89 (unsigned)blockcopy->md5sum[0],
90 (unsigned)blockcopy->md5sum[1],
91 (unsigned)blockcopy->md5sum[2],
92 (unsigned)blockcopy->md5sum[3],
93 (unsigned)blockcopy->md5sum[4],
94 (unsigned)blockcopy->md5sum[5],
95 (unsigned)blockcopy->md5sum[6],
96 (unsigned)blockcopy->md5sum[7],
97 (unsigned)blockcopy->md5sum[8],
98 (unsigned)blockcopy->md5sum[9],
99 (unsigned)blockcopy->md5sum[10],
100 (unsigned)blockcopy->md5sum[11],
101 (unsigned)blockcopy->md5sum[12],
102 (unsigned)blockcopy->md5sum[13],
103 (unsigned)blockcopy->md5sum[14],
104 (unsigned)blockcopy->md5sum[15]
105 );
106 return false;
107 }
108 return true;
109 }
110
mutils__compare_block_data_padding(const FLAC__StreamMetadata_Padding * block,const FLAC__StreamMetadata_Padding * blockcopy,unsigned block_length)111 FLAC__bool mutils__compare_block_data_padding(const FLAC__StreamMetadata_Padding *block, const FLAC__StreamMetadata_Padding *blockcopy, unsigned block_length)
112 {
113 /* we don't compare the padding guts */
114 (void)block, (void)blockcopy, (void)block_length;
115 return true;
116 }
117
mutils__compare_block_data_application(const FLAC__StreamMetadata_Application * block,const FLAC__StreamMetadata_Application * blockcopy,unsigned block_length)118 FLAC__bool mutils__compare_block_data_application(const FLAC__StreamMetadata_Application *block, const FLAC__StreamMetadata_Application *blockcopy, unsigned block_length)
119 {
120 if(block_length < sizeof(block->id)) {
121 printf("FAILED, bad block length = %u\n", block_length);
122 return false;
123 }
124 if(0 != memcmp(blockcopy->id, block->id, sizeof(block->id))) {
125 printf("FAILED, id mismatch, expected %02X%02X%02X%02X, got %02X%02X%02X%02X\n",
126 (unsigned)block->id[0],
127 (unsigned)block->id[1],
128 (unsigned)block->id[2],
129 (unsigned)block->id[3],
130 (unsigned)blockcopy->id[0],
131 (unsigned)blockcopy->id[1],
132 (unsigned)blockcopy->id[2],
133 (unsigned)blockcopy->id[3]
134 );
135 return false;
136 }
137 if(0 == block->data || 0 == blockcopy->data) {
138 if(block->data != blockcopy->data) {
139 printf("FAILED, data mismatch (%s's data pointer is null)\n", 0==block->data?"original":"copy");
140 return false;
141 }
142 else if(block_length - sizeof(block->id) > 0) {
143 printf("FAILED, data pointer is null but block length is not 0\n");
144 return false;
145 }
146 }
147 else {
148 if(block_length - sizeof(block->id) == 0) {
149 printf("FAILED, data pointer is not null but block length is 0\n");
150 return false;
151 }
152 else if(0 != memcmp(blockcopy->data, block->data, block_length - sizeof(block->id))) {
153 printf("FAILED, data mismatch\n");
154 return false;
155 }
156 }
157 return true;
158 }
159
mutils__compare_block_data_seektable(const FLAC__StreamMetadata_SeekTable * block,const FLAC__StreamMetadata_SeekTable * blockcopy)160 FLAC__bool mutils__compare_block_data_seektable(const FLAC__StreamMetadata_SeekTable *block, const FLAC__StreamMetadata_SeekTable *blockcopy)
161 {
162 unsigned i;
163 if(blockcopy->num_points != block->num_points) {
164 printf("FAILED, num_points mismatch, expected %u, got %u\n", block->num_points, blockcopy->num_points);
165 return false;
166 }
167 for(i = 0; i < block->num_points; i++) {
168 if(blockcopy->points[i].sample_number != block->points[i].sample_number) {
169 #ifdef _MSC_VER
170 printf("FAILED, points[%u].sample_number mismatch, expected %I64u, got %I64u\n", i, block->points[i].sample_number, blockcopy->points[i].sample_number);
171 #else
172 printf("FAILED, points[%u].sample_number mismatch, expected %llu, got %llu\n", i, (unsigned long long)block->points[i].sample_number, (unsigned long long)blockcopy->points[i].sample_number);
173 #endif
174 return false;
175 }
176 if(blockcopy->points[i].stream_offset != block->points[i].stream_offset) {
177 #ifdef _MSC_VER
178 printf("FAILED, points[%u].stream_offset mismatch, expected %I64u, got %I64u\n", i, block->points[i].stream_offset, blockcopy->points[i].stream_offset);
179 #else
180 printf("FAILED, points[%u].stream_offset mismatch, expected %llu, got %llu\n", i, (unsigned long long)block->points[i].stream_offset, (unsigned long long)blockcopy->points[i].stream_offset);
181 #endif
182 return false;
183 }
184 if(blockcopy->points[i].frame_samples != block->points[i].frame_samples) {
185 printf("FAILED, points[%u].frame_samples mismatch, expected %u, got %u\n", i, block->points[i].frame_samples, blockcopy->points[i].frame_samples);
186 return false;
187 }
188 }
189 return true;
190 }
191
mutils__compare_block_data_vorbiscomment(const FLAC__StreamMetadata_VorbisComment * block,const FLAC__StreamMetadata_VorbisComment * blockcopy)192 FLAC__bool mutils__compare_block_data_vorbiscomment(const FLAC__StreamMetadata_VorbisComment *block, const FLAC__StreamMetadata_VorbisComment *blockcopy)
193 {
194 unsigned i;
195 if(blockcopy->vendor_string.length != block->vendor_string.length) {
196 printf("FAILED, vendor_string.length mismatch, expected %u, got %u\n", block->vendor_string.length, blockcopy->vendor_string.length);
197 return false;
198 }
199 if(0 == block->vendor_string.entry || 0 == blockcopy->vendor_string.entry) {
200 if(block->vendor_string.entry != blockcopy->vendor_string.entry) {
201 printf("FAILED, vendor_string.entry mismatch\n");
202 return false;
203 }
204 }
205 else if(0 != memcmp(blockcopy->vendor_string.entry, block->vendor_string.entry, block->vendor_string.length)) {
206 printf("FAILED, vendor_string.entry mismatch\n");
207 return false;
208 }
209 if(blockcopy->num_comments != block->num_comments) {
210 printf("FAILED, num_comments mismatch, expected %u, got %u\n", block->num_comments, blockcopy->num_comments);
211 return false;
212 }
213 for(i = 0; i < block->num_comments; i++) {
214 if(blockcopy->comments[i].length != block->comments[i].length) {
215 printf("FAILED, comments[%u].length mismatch, expected %u, got %u\n", i, block->comments[i].length, blockcopy->comments[i].length);
216 return false;
217 }
218 if(0 == block->comments[i].entry || 0 == blockcopy->comments[i].entry) {
219 if(block->comments[i].entry != blockcopy->comments[i].entry) {
220 printf("FAILED, comments[%u].entry mismatch\n", i);
221 return false;
222 }
223 }
224 else {
225 if(0 != memcmp(blockcopy->comments[i].entry, block->comments[i].entry, block->comments[i].length)) {
226 printf("FAILED, comments[%u].entry mismatch\n", i);
227 return false;
228 }
229 }
230 }
231 return true;
232 }
233
mutils__compare_block_data_cuesheet(const FLAC__StreamMetadata_CueSheet * block,const FLAC__StreamMetadata_CueSheet * blockcopy)234 FLAC__bool mutils__compare_block_data_cuesheet(const FLAC__StreamMetadata_CueSheet *block, const FLAC__StreamMetadata_CueSheet *blockcopy)
235 {
236 unsigned i, j;
237
238 if(0 != strcmp(blockcopy->media_catalog_number, block->media_catalog_number)) {
239 printf("FAILED, media_catalog_number mismatch, expected %s, got %s\n", block->media_catalog_number, blockcopy->media_catalog_number);
240 return false;
241 }
242 if(blockcopy->lead_in != block->lead_in) {
243 #ifdef _MSC_VER
244 printf("FAILED, lead_in mismatch, expected %I64u, got %I64u\n", block->lead_in, blockcopy->lead_in);
245 #else
246 printf("FAILED, lead_in mismatch, expected %llu, got %llu\n", (unsigned long long)block->lead_in, (unsigned long long)blockcopy->lead_in);
247 #endif
248 return false;
249 }
250 if(blockcopy->is_cd != block->is_cd) {
251 printf("FAILED, is_cd mismatch, expected %u, got %u\n", (unsigned)block->is_cd, (unsigned)blockcopy->is_cd);
252 return false;
253 }
254 if(blockcopy->num_tracks != block->num_tracks) {
255 printf("FAILED, num_tracks mismatch, expected %u, got %u\n", block->num_tracks, blockcopy->num_tracks);
256 return false;
257 }
258 for(i = 0; i < block->num_tracks; i++) {
259 if(blockcopy->tracks[i].offset != block->tracks[i].offset) {
260 #ifdef _MSC_VER
261 printf("FAILED, tracks[%u].offset mismatch, expected %I64u, got %I64u\n", i, block->tracks[i].offset, blockcopy->tracks[i].offset);
262 #else
263 printf("FAILED, tracks[%u].offset mismatch, expected %llu, got %llu\n", i, (unsigned long long)block->tracks[i].offset, (unsigned long long)blockcopy->tracks[i].offset);
264 #endif
265 return false;
266 }
267 if(blockcopy->tracks[i].number != block->tracks[i].number) {
268 printf("FAILED, tracks[%u].number mismatch, expected %u, got %u\n", i, (unsigned)block->tracks[i].number, (unsigned)blockcopy->tracks[i].number);
269 return false;
270 }
271 if(blockcopy->tracks[i].num_indices != block->tracks[i].num_indices) {
272 printf("FAILED, tracks[%u].num_indices mismatch, expected %u, got %u\n", i, (unsigned)block->tracks[i].num_indices, (unsigned)blockcopy->tracks[i].num_indices);
273 return false;
274 }
275 /* num_indices == 0 means lead-out track so only the track offset and number are valid */
276 if(block->tracks[i].num_indices > 0) {
277 if(0 != strcmp(blockcopy->tracks[i].isrc, block->tracks[i].isrc)) {
278 printf("FAILED, tracks[%u].isrc mismatch, expected %s, got %s\n", i, block->tracks[i].isrc, blockcopy->tracks[i].isrc);
279 return false;
280 }
281 if(blockcopy->tracks[i].type != block->tracks[i].type) {
282 printf("FAILED, tracks[%u].type mismatch, expected %u, got %u\n", i, (unsigned)block->tracks[i].type, (unsigned)blockcopy->tracks[i].type);
283 return false;
284 }
285 if(blockcopy->tracks[i].pre_emphasis != block->tracks[i].pre_emphasis) {
286 printf("FAILED, tracks[%u].pre_emphasis mismatch, expected %u, got %u\n", i, (unsigned)block->tracks[i].pre_emphasis, (unsigned)blockcopy->tracks[i].pre_emphasis);
287 return false;
288 }
289 if(0 == block->tracks[i].indices || 0 == blockcopy->tracks[i].indices) {
290 if(block->tracks[i].indices != blockcopy->tracks[i].indices) {
291 printf("FAILED, tracks[%u].indices mismatch\n", i);
292 return false;
293 }
294 }
295 else {
296 for(j = 0; j < block->tracks[i].num_indices; j++) {
297 if(blockcopy->tracks[i].indices[j].offset != block->tracks[i].indices[j].offset) {
298 #ifdef _MSC_VER
299 printf("FAILED, tracks[%u].indices[%u].offset mismatch, expected %I64u, got %I64u\n", i, j, block->tracks[i].indices[j].offset, blockcopy->tracks[i].indices[j].offset);
300 #else
301 printf("FAILED, tracks[%u].indices[%u].offset mismatch, expected %llu, got %llu\n", i, j, (unsigned long long)block->tracks[i].indices[j].offset, (unsigned long long)blockcopy->tracks[i].indices[j].offset);
302 #endif
303 return false;
304 }
305 if(blockcopy->tracks[i].indices[j].number != block->tracks[i].indices[j].number) {
306 printf("FAILED, tracks[%u].indices[%u].number mismatch, expected %u, got %u\n", i, j, (unsigned)block->tracks[i].indices[j].number, (unsigned)blockcopy->tracks[i].indices[j].number);
307 return false;
308 }
309 }
310 }
311 }
312 }
313 return true;
314 }
315
mutils__compare_block_data_picture(const FLAC__StreamMetadata_Picture * block,const FLAC__StreamMetadata_Picture * blockcopy)316 FLAC__bool mutils__compare_block_data_picture(const FLAC__StreamMetadata_Picture *block, const FLAC__StreamMetadata_Picture *blockcopy)
317 {
318 size_t len, lencopy;
319 if(blockcopy->type != block->type) {
320 printf("FAILED, type mismatch, expected %u, got %u\n", (unsigned)block->type, (unsigned)blockcopy->type);
321 return false;
322 }
323 len = strlen(block->mime_type);
324 lencopy = strlen(blockcopy->mime_type);
325 if(lencopy != len) {
326 printf("FAILED, mime_type length mismatch, expected %u, got %u\n", (unsigned)len, (unsigned)lencopy);
327 return false;
328 }
329 if(strcmp(blockcopy->mime_type, block->mime_type)) {
330 printf("FAILED, mime_type mismatch, expected %s, got %s\n", block->mime_type, blockcopy->mime_type);
331 return false;
332 }
333 len = strlen((const char *)block->description);
334 lencopy = strlen((const char *)blockcopy->description);
335 if(lencopy != len) {
336 printf("FAILED, description length mismatch, expected %u, got %u\n", (unsigned)len, (unsigned)lencopy);
337 return false;
338 }
339 if(strcmp((const char *)blockcopy->description, (const char *)block->description)) {
340 printf("FAILED, description mismatch, expected %s, got %s\n", block->description, blockcopy->description);
341 return false;
342 }
343 if(blockcopy->width != block->width) {
344 printf("FAILED, width mismatch, expected %u, got %u\n", block->width, blockcopy->width);
345 return false;
346 }
347 if(blockcopy->height != block->height) {
348 printf("FAILED, height mismatch, expected %u, got %u\n", block->height, blockcopy->height);
349 return false;
350 }
351 if(blockcopy->depth != block->depth) {
352 printf("FAILED, depth mismatch, expected %u, got %u\n", block->depth, blockcopy->depth);
353 return false;
354 }
355 if(blockcopy->colors != block->colors) {
356 printf("FAILED, colors mismatch, expected %u, got %u\n", block->colors, blockcopy->colors);
357 return false;
358 }
359 if(blockcopy->data_length != block->data_length) {
360 printf("FAILED, data_length mismatch, expected %u, got %u\n", block->data_length, blockcopy->data_length);
361 return false;
362 }
363 if(memcmp(blockcopy->data, block->data, block->data_length)) {
364 printf("FAILED, data mismatch\n");
365 return false;
366 }
367 return true;
368 }
369
mutils__compare_block_data_unknown(const FLAC__StreamMetadata_Unknown * block,const FLAC__StreamMetadata_Unknown * blockcopy,unsigned block_length)370 FLAC__bool mutils__compare_block_data_unknown(const FLAC__StreamMetadata_Unknown *block, const FLAC__StreamMetadata_Unknown *blockcopy, unsigned block_length)
371 {
372 if(0 == block->data || 0 == blockcopy->data) {
373 if(block->data != blockcopy->data) {
374 printf("FAILED, data mismatch (%s's data pointer is null)\n", 0==block->data?"original":"copy");
375 return false;
376 }
377 else if(block_length > 0) {
378 printf("FAILED, data pointer is null but block length is not 0\n");
379 return false;
380 }
381 }
382 else {
383 if(block_length == 0) {
384 printf("FAILED, data pointer is not null but block length is 0\n");
385 return false;
386 }
387 else if(0 != memcmp(blockcopy->data, block->data, block_length)) {
388 printf("FAILED, data mismatch\n");
389 return false;
390 }
391 }
392 return true;
393 }
394
mutils__compare_block(const FLAC__StreamMetadata * block,const FLAC__StreamMetadata * blockcopy)395 FLAC__bool mutils__compare_block(const FLAC__StreamMetadata *block, const FLAC__StreamMetadata *blockcopy)
396 {
397 if(blockcopy->type != block->type) {
398 printf("FAILED, type mismatch, expected %s, got %s\n", FLAC__MetadataTypeString[block->type], FLAC__MetadataTypeString[blockcopy->type]);
399 return false;
400 }
401 if(blockcopy->is_last != block->is_last) {
402 printf("FAILED, is_last mismatch, expected %u, got %u\n", (unsigned)block->is_last, (unsigned)blockcopy->is_last);
403 return false;
404 }
405 if(blockcopy->length != block->length) {
406 printf("FAILED, length mismatch, expected %u, got %u\n", block->length, blockcopy->length);
407 return false;
408 }
409 switch(block->type) {
410 case FLAC__METADATA_TYPE_STREAMINFO:
411 return mutils__compare_block_data_streaminfo(&block->data.stream_info, &blockcopy->data.stream_info);
412 case FLAC__METADATA_TYPE_PADDING:
413 return mutils__compare_block_data_padding(&block->data.padding, &blockcopy->data.padding, block->length);
414 case FLAC__METADATA_TYPE_APPLICATION:
415 return mutils__compare_block_data_application(&block->data.application, &blockcopy->data.application, block->length);
416 case FLAC__METADATA_TYPE_SEEKTABLE:
417 return mutils__compare_block_data_seektable(&block->data.seek_table, &blockcopy->data.seek_table);
418 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
419 return mutils__compare_block_data_vorbiscomment(&block->data.vorbis_comment, &blockcopy->data.vorbis_comment);
420 case FLAC__METADATA_TYPE_CUESHEET:
421 return mutils__compare_block_data_cuesheet(&block->data.cue_sheet, &blockcopy->data.cue_sheet);
422 case FLAC__METADATA_TYPE_PICTURE:
423 return mutils__compare_block_data_picture(&block->data.picture, &blockcopy->data.picture);
424 default:
425 return mutils__compare_block_data_unknown(&block->data.unknown, &blockcopy->data.unknown, block->length);
426 }
427 }
428
malloc_or_die_(size_t size)429 static void *malloc_or_die_(size_t size)
430 {
431 void *x = malloc(size);
432 if(0 == x) {
433 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
434 exit(1);
435 }
436 return x;
437 }
438
calloc_or_die_(size_t n,size_t size)439 static void *calloc_or_die_(size_t n, size_t size)
440 {
441 void *x = calloc(n, size);
442 if(0 == x) {
443 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)n * (unsigned)size);
444 exit(1);
445 }
446 return x;
447 }
448
strdup_or_die_(const char * s)449 static char *strdup_or_die_(const char *s)
450 {
451 char *x = strdup(s);
452 if(0 == x) {
453 fprintf(stderr, "ERROR: out of memory copying string \"%s\"\n", s);
454 exit(1);
455 }
456 return x;
457 }
458
mutils__init_metadata_blocks(FLAC__StreamMetadata * streaminfo,FLAC__StreamMetadata * padding,FLAC__StreamMetadata * seektable,FLAC__StreamMetadata * application1,FLAC__StreamMetadata * application2,FLAC__StreamMetadata * vorbiscomment,FLAC__StreamMetadata * cuesheet,FLAC__StreamMetadata * picture,FLAC__StreamMetadata * unknown)459 void mutils__init_metadata_blocks(
460 FLAC__StreamMetadata *streaminfo,
461 FLAC__StreamMetadata *padding,
462 FLAC__StreamMetadata *seektable,
463 FLAC__StreamMetadata *application1,
464 FLAC__StreamMetadata *application2,
465 FLAC__StreamMetadata *vorbiscomment,
466 FLAC__StreamMetadata *cuesheet,
467 FLAC__StreamMetadata *picture,
468 FLAC__StreamMetadata *unknown
469 )
470 {
471 /*
472 most of the actual numbers and data in the blocks don't matter,
473 we just want to make sure the decoder parses them correctly
474
475 remember, the metadata interface gets tested after the decoders,
476 so we do all the metadata manipulation here without it.
477 */
478
479 /* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
480 streaminfo->is_last = false;
481 streaminfo->type = FLAC__METADATA_TYPE_STREAMINFO;
482 streaminfo->length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
483 streaminfo->data.stream_info.min_blocksize = 576;
484 streaminfo->data.stream_info.max_blocksize = 576;
485 streaminfo->data.stream_info.min_framesize = 0;
486 streaminfo->data.stream_info.max_framesize = 0;
487 streaminfo->data.stream_info.sample_rate = 44100;
488 streaminfo->data.stream_info.channels = 1;
489 streaminfo->data.stream_info.bits_per_sample = 8;
490 streaminfo->data.stream_info.total_samples = 0;
491 memset(streaminfo->data.stream_info.md5sum, 0, 16);
492
493 padding->is_last = false;
494 padding->type = FLAC__METADATA_TYPE_PADDING;
495 padding->length = 1234;
496
497 seektable->is_last = false;
498 seektable->type = FLAC__METADATA_TYPE_SEEKTABLE;
499 seektable->data.seek_table.num_points = 2;
500 seektable->length = seektable->data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
501 seektable->data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
502 seektable->data.seek_table.points[0].sample_number = 0;
503 seektable->data.seek_table.points[0].stream_offset = 0;
504 seektable->data.seek_table.points[0].frame_samples = streaminfo->data.stream_info.min_blocksize;
505 seektable->data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
506 seektable->data.seek_table.points[1].stream_offset = 1000;
507 seektable->data.seek_table.points[1].frame_samples = streaminfo->data.stream_info.min_blocksize;
508
509 application1->is_last = false;
510 application1->type = FLAC__METADATA_TYPE_APPLICATION;
511 application1->length = 8;
512 memcpy(application1->data.application.id, "\xfe\xdc\xba\x98", 4);
513 application1->data.application.data = (FLAC__byte*)malloc_or_die_(4);
514 memcpy(application1->data.application.data, "\xf0\xe1\xd2\xc3", 4);
515
516 application2->is_last = false;
517 application2->type = FLAC__METADATA_TYPE_APPLICATION;
518 application2->length = 4;
519 memcpy(application2->data.application.id, "\x76\x54\x32\x10", 4);
520 application2->data.application.data = 0;
521
522 {
523 const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
524 vorbiscomment->is_last = false;
525 vorbiscomment->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
526 vorbiscomment->length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
527 vorbiscomment->data.vorbis_comment.vendor_string.length = vendor_string_length;
528 vorbiscomment->data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
529 memcpy(vorbiscomment->data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
530 vorbiscomment->data.vorbis_comment.num_comments = 2;
531 vorbiscomment->data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
532 vorbiscomment->data.vorbis_comment.comments[0].length = 5;
533 vorbiscomment->data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5+1);
534 memcpy(vorbiscomment->data.vorbis_comment.comments[0].entry, "ab=cd", 5+1);
535 vorbiscomment->data.vorbis_comment.comments[1].length = 0;
536 vorbiscomment->data.vorbis_comment.comments[1].entry = 0;
537 }
538
539 cuesheet->is_last = false;
540 cuesheet->type = FLAC__METADATA_TYPE_CUESHEET;
541 cuesheet->length =
542 /* cuesheet guts */
543 (
544 FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN +
545 FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN +
546 FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN +
547 FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN +
548 FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
549 ) / 8 +
550 /* 2 tracks */
551 3 * (
552 FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN +
553 FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN +
554 FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN +
555 FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN +
556 FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN +
557 FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN +
558 FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN
559 ) / 8 +
560 /* 3 index points */
561 3 * (
562 FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN +
563 FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN +
564 FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN
565 ) / 8
566 ;
567 memset(cuesheet->data.cue_sheet.media_catalog_number, 0, sizeof(cuesheet->data.cue_sheet.media_catalog_number));
568 cuesheet->data.cue_sheet.media_catalog_number[0] = 'j';
569 cuesheet->data.cue_sheet.media_catalog_number[1] = 'C';
570 cuesheet->data.cue_sheet.lead_in = 2 * 44100;
571 cuesheet->data.cue_sheet.is_cd = true;
572 cuesheet->data.cue_sheet.num_tracks = 3;
573 cuesheet->data.cue_sheet.tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc_or_die_(cuesheet->data.cue_sheet.num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
574 cuesheet->data.cue_sheet.tracks[0].offset = 0;
575 cuesheet->data.cue_sheet.tracks[0].number = 1;
576 memcpy(cuesheet->data.cue_sheet.tracks[0].isrc, "ACBDE1234567", sizeof(cuesheet->data.cue_sheet.tracks[0].isrc));
577 cuesheet->data.cue_sheet.tracks[0].type = 0;
578 cuesheet->data.cue_sheet.tracks[0].pre_emphasis = 1;
579 cuesheet->data.cue_sheet.tracks[0].num_indices = 2;
580 cuesheet->data.cue_sheet.tracks[0].indices = (FLAC__StreamMetadata_CueSheet_Index*)malloc_or_die_(cuesheet->data.cue_sheet.tracks[0].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
581 cuesheet->data.cue_sheet.tracks[0].indices[0].offset = 0;
582 cuesheet->data.cue_sheet.tracks[0].indices[0].number = 0;
583 cuesheet->data.cue_sheet.tracks[0].indices[1].offset = 123 * 588;
584 cuesheet->data.cue_sheet.tracks[0].indices[1].number = 1;
585 cuesheet->data.cue_sheet.tracks[1].offset = 1234 * 588;
586 cuesheet->data.cue_sheet.tracks[1].number = 2;
587 memcpy(cuesheet->data.cue_sheet.tracks[1].isrc, "ACBDE7654321", sizeof(cuesheet->data.cue_sheet.tracks[1].isrc));
588 cuesheet->data.cue_sheet.tracks[1].type = 1;
589 cuesheet->data.cue_sheet.tracks[1].pre_emphasis = 0;
590 cuesheet->data.cue_sheet.tracks[1].num_indices = 1;
591 cuesheet->data.cue_sheet.tracks[1].indices = (FLAC__StreamMetadata_CueSheet_Index*)malloc_or_die_(cuesheet->data.cue_sheet.tracks[1].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
592 cuesheet->data.cue_sheet.tracks[1].indices[0].offset = 0;
593 cuesheet->data.cue_sheet.tracks[1].indices[0].number = 1;
594 cuesheet->data.cue_sheet.tracks[2].offset = 12345 * 588;
595 cuesheet->data.cue_sheet.tracks[2].number = 170;
596 cuesheet->data.cue_sheet.tracks[2].num_indices = 0;
597
598 picture->is_last = false;
599 picture->type = FLAC__METADATA_TYPE_PICTURE;
600 picture->length =
601 (
602 FLAC__STREAM_METADATA_PICTURE_TYPE_LEN +
603 FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN + /* will add the length for the string later */
604 FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN + /* will add the length for the string later */
605 FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN +
606 FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN +
607 FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN +
608 FLAC__STREAM_METADATA_PICTURE_COLORS_LEN +
609 FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN /* will add the length for the data later */
610 ) / 8
611 ;
612 picture->data.picture.type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
613 picture->data.picture.mime_type = strdup_or_die_("image/jpeg");
614 picture->length += strlen(picture->data.picture.mime_type);
615 picture->data.picture.description = (FLAC__byte*)strdup_or_die_("desc");
616 picture->length += strlen((const char *)picture->data.picture.description);
617 picture->data.picture.width = 300;
618 picture->data.picture.height = 300;
619 picture->data.picture.depth = 24;
620 picture->data.picture.colors = 0;
621 picture->data.picture.data = (FLAC__byte*)strdup_or_die_("SOMEJPEGDATA");
622 picture->data.picture.data_length = strlen((const char *)picture->data.picture.data);
623 picture->length += picture->data.picture.data_length;
624
625 unknown->is_last = true;
626 unknown->type = 126;
627 unknown->length = 8;
628 unknown->data.unknown.data = (FLAC__byte*)malloc_or_die_(unknown->length);
629 memcpy(unknown->data.unknown.data, "\xfe\xdc\xba\x98\xf0\xe1\xd2\xc3", unknown->length);
630 }
631
mutils__free_metadata_blocks(FLAC__StreamMetadata * streaminfo,FLAC__StreamMetadata * padding,FLAC__StreamMetadata * seektable,FLAC__StreamMetadata * application1,FLAC__StreamMetadata * application2,FLAC__StreamMetadata * vorbiscomment,FLAC__StreamMetadata * cuesheet,FLAC__StreamMetadata * picture,FLAC__StreamMetadata * unknown)632 void mutils__free_metadata_blocks(
633 FLAC__StreamMetadata *streaminfo,
634 FLAC__StreamMetadata *padding,
635 FLAC__StreamMetadata *seektable,
636 FLAC__StreamMetadata *application1,
637 FLAC__StreamMetadata *application2,
638 FLAC__StreamMetadata *vorbiscomment,
639 FLAC__StreamMetadata *cuesheet,
640 FLAC__StreamMetadata *picture,
641 FLAC__StreamMetadata *unknown
642 )
643 {
644 (void)streaminfo, (void)padding, (void)application2;
645 free(seektable->data.seek_table.points);
646 free(application1->data.application.data);
647 free(vorbiscomment->data.vorbis_comment.vendor_string.entry);
648 free(vorbiscomment->data.vorbis_comment.comments[0].entry);
649 free(vorbiscomment->data.vorbis_comment.comments);
650 free(cuesheet->data.cue_sheet.tracks[0].indices);
651 free(cuesheet->data.cue_sheet.tracks[1].indices);
652 free(cuesheet->data.cue_sheet.tracks);
653 free(picture->data.picture.mime_type);
654 free(picture->data.picture.description);
655 free(picture->data.picture.data);
656 free(unknown->data.unknown.data);
657 }
658