bump libtool version numbers
[flac.git] / src / test_libs_common / metadata_utils.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }