• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/minidlna/flac-1.2.1/src/test_libs_common/
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
33FLAC__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
111FLAC__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
118FLAC__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
160FLAC__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
192FLAC__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
234FLAC__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
316FLAC__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
370FLAC__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
395FLAC__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
429static 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
439static 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
449static 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
459void 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
632void 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