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