The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.

Dependencies:   GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom

Fork of GR-PEACH_Audio_Playback_Sample by Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers format.c Source File

format.c

00001 /* libFLAC - Free Lossless Audio Codec library
00002  * Copyright (C) 2000-2009  Josh Coalson
00003  * Copyright (C) 2011-2014  Xiph.Org Foundation
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  * notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above copyright
00013  * notice, this list of conditions and the following disclaimer in the
00014  * documentation and/or other materials provided with the distribution.
00015  *
00016  * - Neither the name of the Xiph.org Foundation nor the names of its
00017  * contributors may be used to endorse or promote products derived from
00018  * this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00023  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
00024  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #  include <config.h>
00035 #endif
00036 
00037 #include <stdio.h>
00038 #include <stdlib.h> /* for qsort() */
00039 #include <string.h> /* for memset() */
00040 #include "FLAC/assert.h"
00041 #include "FLAC/format.h"
00042 #include "share/compat.h"
00043 #include "private/format.h"
00044 #include "private/macros.h"
00045 
00046 #if(1) /* mbed */
00047 #define VERSION "1.3.1"
00048 #endif /* end mbed */
00049 
00050 /* VERSION should come from configure */
00051 FLAC_API const char *FLAC__VERSION_STRING = VERSION;
00052 
00053 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125";
00054 
00055 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
00056 FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
00057 FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
00058 
00059 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
00060 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
00061 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
00062 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
00063 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
00064 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
00065 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
00066 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
00067 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
00068 
00069 FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
00070 
00071 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
00072 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
00073 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
00074 
00075 FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
00076 
00077 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
00078 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
00079 
00080 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
00081 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
00082 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
00083 
00084 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
00085 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
00086 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
00087 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
00088 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
00089 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
00090 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
00091 
00092 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
00093 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
00094 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
00095 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
00096 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
00097 
00098 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
00099 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
00100 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
00101 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
00102 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
00103 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
00104 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
00105 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
00106 
00107 FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
00108 FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
00109 FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
00110 
00111 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
00112 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
00113 FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
00114 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
00115 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
00116 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
00117 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
00118 FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
00119 FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
00120 FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
00121 
00122 FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
00123 
00124 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
00125 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
00126 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
00127 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
00128 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
00129 
00130 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
00131 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
00132 
00133 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
00134     "PARTITIONED_RICE",
00135     "PARTITIONED_RICE2"
00136 };
00137 
00138 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
00139 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
00140 
00141 FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
00142 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
00143 FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
00144 
00145 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
00146 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
00147 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
00148 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
00149 
00150 FLAC_API const char * const FLAC__SubframeTypeString[] = {
00151     "CONSTANT",
00152     "VERBATIM",
00153     "FIXED",
00154     "LPC"
00155 };
00156 
00157 FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
00158     "INDEPENDENT",
00159     "LEFT_SIDE",
00160     "RIGHT_SIDE",
00161     "MID_SIDE"
00162 };
00163 
00164 FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
00165     "FRAME_NUMBER_TYPE_FRAME_NUMBER",
00166     "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
00167 };
00168 
00169 FLAC_API const char * const FLAC__MetadataTypeString[] = {
00170     "STREAMINFO",
00171     "PADDING",
00172     "APPLICATION",
00173     "SEEKTABLE",
00174     "VORBIS_COMMENT",
00175     "CUESHEET",
00176     "PICTURE"
00177 };
00178 
00179 FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
00180     "Other",
00181     "32x32 pixels 'file icon' (PNG only)",
00182     "Other file icon",
00183     "Cover (front)",
00184     "Cover (back)",
00185     "Leaflet page",
00186     "Media (e.g. label side of CD)",
00187     "Lead artist/lead performer/soloist",
00188     "Artist/performer",
00189     "Conductor",
00190     "Band/Orchestra",
00191     "Composer",
00192     "Lyricist/text writer",
00193     "Recording Location",
00194     "During recording",
00195     "During performance",
00196     "Movie/video screen capture",
00197     "A bright coloured fish",
00198     "Illustration",
00199     "Band/artist logotype",
00200     "Publisher/Studio logotype"
00201 };
00202 
00203 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
00204 {
00205     if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
00206         return false;
00207     }
00208     else
00209         return true;
00210 }
00211 
00212 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate)
00213 {
00214     if(blocksize > 16384)
00215         return false;
00216     else if(sample_rate <= 48000 && blocksize > 4608)
00217         return false;
00218     else
00219         return true;
00220 }
00221 
00222 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
00223 {
00224     if(
00225         !FLAC__format_sample_rate_is_valid(sample_rate) ||
00226         (
00227             sample_rate >= (1u << 16) &&
00228             !(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
00229         )
00230     ) {
00231         return false;
00232     }
00233     else
00234         return true;
00235 }
00236 
00237 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
00238 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
00239 {
00240     unsigned i;
00241     FLAC__uint64 prev_sample_number = 0;
00242     FLAC__bool got_prev = false;
00243 
00244     FLAC__ASSERT(0 != seek_table);
00245 
00246     for(i = 0; i < seek_table->num_points; i++) {
00247         if(got_prev) {
00248             if(
00249                 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
00250                 seek_table->points[i].sample_number <= prev_sample_number
00251             )
00252                 return false;
00253         }
00254         prev_sample_number = seek_table->points[i].sample_number;
00255         got_prev = true;
00256     }
00257 
00258     return true;
00259 }
00260 
00261 /* used as the sort predicate for qsort() */
00262 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
00263 {
00264     /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
00265     if(l->sample_number == r->sample_number)
00266         return 0;
00267     else if(l->sample_number < r->sample_number)
00268         return -1;
00269     else
00270         return 1;
00271 }
00272 
00273 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
00274 FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
00275 {
00276     unsigned i, j;
00277     FLAC__bool first;
00278 
00279     FLAC__ASSERT(0 != seek_table);
00280 
00281     /* sort the seekpoints */
00282     qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
00283 
00284     /* uniquify the seekpoints */
00285     first = true;
00286     for(i = j = 0; i < seek_table->num_points; i++) {
00287         if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
00288             if(!first) {
00289                 if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
00290                     continue;
00291             }
00292         }
00293         first = false;
00294         seek_table->points[j++] = seek_table->points[i];
00295     }
00296 
00297     for(i = j; i < seek_table->num_points; i++) {
00298         seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
00299         seek_table->points[i].stream_offset = 0;
00300         seek_table->points[i].frame_samples = 0;
00301     }
00302 
00303     return j;
00304 }
00305 
00306 /*
00307  * also disallows non-shortest-form encodings, c.f.
00308  *   http://www.unicode.org/versions/corrigendum1.html
00309  * and a more clear explanation at the end of this section:
00310  *   http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
00311  */
00312 static unsigned utf8len_(const FLAC__byte *utf8)
00313 {
00314     FLAC__ASSERT(0 != utf8);
00315     if ((utf8[0] & 0x80) == 0) {
00316         return 1;
00317     }
00318     else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
00319         if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
00320             return 0;
00321         return 2;
00322     }
00323     else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
00324         if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
00325             return 0;
00326         /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
00327         if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
00328             return 0;
00329         if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
00330             return 0;
00331         return 3;
00332     }
00333     else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
00334         if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
00335             return 0;
00336         return 4;
00337     }
00338     else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
00339         if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
00340             return 0;
00341         return 5;
00342     }
00343     else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) {
00344         if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
00345             return 0;
00346         return 6;
00347     }
00348     else {
00349         return 0;
00350     }
00351 }
00352 
00353 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
00354 {
00355     char c;
00356     for(c = *name; c; c = *(++name))
00357         if(c < 0x20 || c == 0x3d || c > 0x7d)
00358             return false;
00359     return true;
00360 }
00361 
00362 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
00363 {
00364     if(length == (unsigned)(-1)) {
00365         while(*value) {
00366             unsigned n = utf8len_(value);
00367             if(n == 0)
00368                 return false;
00369             value += n;
00370         }
00371     }
00372     else {
00373         const FLAC__byte *end = value + length;
00374         while(value < end) {
00375             unsigned n = utf8len_(value);
00376             if(n == 0)
00377                 return false;
00378             value += n;
00379         }
00380         if(value != end)
00381             return false;
00382     }
00383     return true;
00384 }
00385 
00386 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length)
00387 {
00388     const FLAC__byte *s, *end;
00389 
00390     for(s = entry, end = s + length; s < end && *s != '='; s++) {
00391         if(*s < 0x20 || *s > 0x7D)
00392             return false;
00393     }
00394     if(s == end)
00395         return false;
00396 
00397     s++; /* skip '=' */
00398 
00399     while(s < end) {
00400         unsigned n = utf8len_(s);
00401         if(n == 0)
00402             return false;
00403         s += n;
00404     }
00405     if(s != end)
00406         return false;
00407 
00408     return true;
00409 }
00410 
00411 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
00412 FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
00413 {
00414     unsigned i, j;
00415 
00416     if(check_cd_da_subset) {
00417         if(cue_sheet->lead_in < 2 * 44100) {
00418             if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
00419             return false;
00420         }
00421         if(cue_sheet->lead_in % 588 != 0) {
00422             if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
00423             return false;
00424         }
00425     }
00426 
00427     if(cue_sheet->num_tracks == 0) {
00428         if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
00429         return false;
00430     }
00431 
00432     if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
00433         if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
00434         return false;
00435     }
00436 
00437     for(i = 0; i < cue_sheet->num_tracks; i++) {
00438         if(cue_sheet->tracks[i].number == 0) {
00439             if(violation) *violation = "cue sheet may not have a track number 0";
00440             return false;
00441         }
00442 
00443         if(check_cd_da_subset) {
00444             if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
00445                 if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
00446                 return false;
00447             }
00448         }
00449 
00450         if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
00451             if(violation) {
00452                 if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
00453                     *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
00454                 else
00455                     *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
00456             }
00457             return false;
00458         }
00459 
00460         if(i < cue_sheet->num_tracks - 1) {
00461             if(cue_sheet->tracks[i].num_indices == 0) {
00462                 if(violation) *violation = "cue sheet track must have at least one index point";
00463                 return false;
00464             }
00465 
00466             if(cue_sheet->tracks[i].indices[0].number > 1) {
00467                 if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
00468                 return false;
00469             }
00470         }
00471 
00472         for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
00473             if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
00474                 if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
00475                 return false;
00476             }
00477 
00478             if(j > 0) {
00479                 if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
00480                     if(violation) *violation = "cue sheet track index numbers must increase by 1";
00481                     return false;
00482                 }
00483             }
00484         }
00485     }
00486 
00487     return true;
00488 }
00489 
00490 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
00491 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
00492 {
00493     char *p;
00494     FLAC__byte *b;
00495 
00496     for(p = picture->mime_type; *p; p++) {
00497         if(*p < 0x20 || *p > 0x7e) {
00498             if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
00499             return false;
00500         }
00501     }
00502 
00503     for(b = picture->description; *b; ) {
00504         unsigned n = utf8len_(b);
00505         if(n == 0) {
00506             if(violation) *violation = "description string must be valid UTF-8";
00507             return false;
00508         }
00509         b += n;
00510     }
00511 
00512     return true;
00513 }
00514 
00515 /*
00516  * These routines are private to libFLAC
00517  */
00518 unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
00519 {
00520     return
00521         FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
00522             FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
00523             blocksize,
00524             predictor_order
00525         );
00526 }
00527 
00528 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
00529 {
00530     unsigned max_rice_partition_order = 0;
00531     while(!(blocksize & 1)) {
00532         max_rice_partition_order++;
00533         blocksize >>= 1;
00534     }
00535     return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
00536 }
00537 
00538 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
00539 {
00540     unsigned max_rice_partition_order = limit;
00541 
00542     while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
00543         max_rice_partition_order--;
00544 
00545     FLAC__ASSERT(
00546         (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
00547         (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
00548     );
00549 
00550     return max_rice_partition_order;
00551 }
00552 
00553 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
00554 {
00555     FLAC__ASSERT(0 != object);
00556 
00557     object->parameters = 0;
00558     object->raw_bits = 0;
00559     object->capacity_by_order = 0;
00560 }
00561 
00562 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
00563 {
00564     FLAC__ASSERT(0 != object);
00565 
00566     if(0 != object->parameters)
00567         free(object->parameters);
00568     if(0 != object->raw_bits)
00569         free(object->raw_bits);
00570     FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
00571 }
00572 
00573 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
00574 {
00575     FLAC__ASSERT(0 != object);
00576 
00577     FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
00578 
00579     if(object->capacity_by_order < max_partition_order) {
00580         if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
00581             return false;
00582         if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
00583             return false;
00584         memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
00585         object->capacity_by_order = max_partition_order;
00586     }
00587 
00588     return true;
00589 }