merge decoder part from RICE_EXT_BRANCH: blocking strategy bit, new rice2 ecm, frame...
authorJosh Coalson <jcoalson@users.sourceforce.net>
Sat, 16 Jun 2007 00:50:28 +0000 (00:50 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Sat, 16 Jun 2007 00:50:28 +0000 (00:50 +0000)
include/FLAC/format.h
src/libFLAC/format.c
src/libFLAC/stream_decoder.c
src/libFLAC/stream_encoder_framing.c

index 9e744cd..414603e 100644 (file)
@@ -191,9 +191,13 @@ extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */
 
 /** An enumeration of the available entropy coding methods. */
 typedef enum {
 
 /** An enumeration of the available entropy coding methods. */
 typedef enum {
-       FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0
+       FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0,
        /**< Residual is coded by partitioning into contexts, each with it's own
        /**< Residual is coded by partitioning into contexts, each with it's own
-        * Rice parameter. */
+        * 4-bit Rice parameter. */
+
+       FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1
+       /**< Residual is coded by partitioning into contexts, each with it's own
+        * 5-bit Rice parameter. */
 } FLAC__EntropyCodingMethodType;
 
 /** Maps a FLAC__EntropyCodingMethodType to a C string.
 } FLAC__EntropyCodingMethodType;
 
 /** Maps a FLAC__EntropyCodingMethodType to a C string.
@@ -212,7 +216,9 @@ typedef struct {
        /**< The Rice parameters for each context. */
 
        unsigned *raw_bits;
        /**< The Rice parameters for each context. */
 
        unsigned *raw_bits;
-       /**< Widths for escape-coded partitions. */
+       /**< Widths for escape-coded partitions.  Will be non-zero for escaped
+        * partitions and zero for unescaped partitions.
+        */
 
        unsigned capacity_by_order;
        /**< The capacity of the \a parameters and \a raw_bits arrays
 
        unsigned capacity_by_order;
        /**< The capacity of the \a parameters and \a raw_bits arrays
@@ -235,10 +241,13 @@ typedef struct {
 
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */
 
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */
 
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
 /**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */
 
 extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
 /**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
+extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER;
+/**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
 
 /** Header for the entropy coding method.  (c.f. <A HREF="../format.html#residual">format specification</A>)
  */
 
 /** Header for the entropy coding method.  (c.f. <A HREF="../format.html#residual">format specification</A>)
  */
@@ -342,7 +351,14 @@ typedef struct {
        unsigned wasted_bits;
 } FLAC__Subframe;
 
        unsigned wasted_bits;
 } FLAC__Subframe;
 
-extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; /**< == 1 (bit) */
+/** == 1 (bit)
+ *
+ * This used to be a zero-padding bit (hence the name
+ * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit.  It still has a
+ * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1
+ * to mean something else.
+ */
+extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN;
 extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */
 extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */
 
 extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */
 extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */
 
@@ -408,7 +424,9 @@ typedef struct {
        /**< The sample resolution. */
 
        FLAC__FrameNumberType number_type;
        /**< The sample resolution. */
 
        FLAC__FrameNumberType number_type;
-       /**< The numbering scheme used for the frame. */
+       /**< The numbering scheme used for the frame.  As a convenience, the
+        * decoder will always convert a frame number to a sample number because
+        * the rules are complex. */
 
        union {
                FLAC__uint32 frame_number;
 
        union {
                FLAC__uint32 frame_number;
@@ -426,7 +444,8 @@ typedef struct {
 
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */
 
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */
-extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 2 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */
+extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */
 extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */
index de911ac..22ee4b6 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <stdio.h>
 #include <stdlib.h> /* for qsort() */
 
 #include <stdio.h>
 #include <stdlib.h> /* for qsort() */
+#include <string.h> /* for memset() */
 #include "FLAC/assert.h"
 #include "FLAC/format.h"
 #include "private/format.h"
 #include "FLAC/assert.h"
 #include "FLAC/format.h"
 #include "private/format.h"
@@ -123,7 +124,8 @@ FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
 
 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
 
 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
-FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 2; /* bits */
+FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
+FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
@@ -136,12 +138,15 @@ FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
+FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
 
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
 
 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
+FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
 
 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
 
 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
-       "PARTITIONED_RICE"
+       "PARTITIONED_RICE",
+       "PARTITIONED_RICE2"
 };
 
 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
 };
 
 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
@@ -576,6 +581,7 @@ FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_s
                        return false;
                if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
                        return false;
                        return false;
                if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
                        return false;
+               memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
                object->capacity_by_order = max_partition_order;
        }
 
                object->capacity_by_order = max_partition_order;
        }
 
index 48636ff..5870231 100644 (file)
@@ -121,7 +121,7 @@ static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned
 static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
 static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
 static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
 static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
 static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode);
 static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode);
-static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual);
+static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended);
 static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
 static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
 #if FLAC__HAS_OGG
 static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder);
 static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data);
 #if FLAC__HAS_OGG
@@ -174,8 +174,7 @@ typedef struct FLAC__StreamDecoderPrivate {
        FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
        FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
        unsigned output_capacity, output_channels;
        FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
        FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS];
        unsigned output_capacity, output_channels;
-       FLAC__uint32 last_frame_number;
-       FLAC__uint32 last_block_size;
+       FLAC__uint32 fixed_block_size, next_fixed_block_size;
        FLAC__uint64 samples_decoded;
        FLAC__bool has_stream_info, has_seek_table;
        FLAC__StreamMetadata stream_info;
        FLAC__uint64 samples_decoded;
        FLAC__bool has_stream_info, has_seek_table;
        FLAC__StreamMetadata stream_info;
@@ -460,8 +459,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
        decoder->private_->metadata_callback = metadata_callback;
        decoder->private_->error_callback = error_callback;
        decoder->private_->client_data = client_data;
        decoder->private_->metadata_callback = metadata_callback;
        decoder->private_->error_callback = error_callback;
        decoder->private_->client_data = client_data;
-       decoder->private_->last_frame_number = 0;
-       decoder->private_->last_block_size = 0;
+       decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
        decoder->private_->samples_decoded = 0;
        decoder->private_->has_stream_info = false;
        decoder->private_->cached = false;
        decoder->private_->samples_decoded = 0;
        decoder->private_->has_stream_info = false;
        decoder->private_->cached = false;
@@ -969,8 +967,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
                decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
                return false;
        }
                decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
                return false;
        }
-       decoder->private_->last_frame_number = 0;
-       decoder->private_->last_block_size = 0;
        decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
 
        return true;
        decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
 
        return true;
@@ -1016,6 +1012,11 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
                decoder->private_->has_seek_table = false;
        }
        decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
                decoder->private_->has_seek_table = false;
        }
        decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
+       /*
+        * This goes in reset() and not flush() because according to the spec, a
+        * fixed-blocksize stream must stay that way through the whole stream.
+        */
+       decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0;
 
        /* We initialize the FLAC__MD5Context even though we may never use it.  This
         * is because md5 checking may be turned on to start and then turned off if
 
        /* We initialize the FLAC__MD5Context even though we may never use it.  This
         * is because md5 checking may be turned on to start and then turned off if
@@ -2100,6 +2101,10 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL
 
        *got_a_frame = true;
 
 
        *got_a_frame = true;
 
+       /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */
+       if(decoder->private_->next_fixed_block_size)
+               decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size;
+
        /* put the latest values into the public section of the decoder instance */
        decoder->protected_->channels = decoder->private_->frame.header.channels;
        decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
        /* put the latest values into the public section of the decoder instance */
        decoder->protected_->channels = decoder->private_->frame.header.channels;
        decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment;
@@ -2128,8 +2133,6 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
        FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
        unsigned raw_header_len;
        FLAC__bool is_unparseable = false;
        FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
        unsigned raw_header_len;
        FLAC__bool is_unparseable = false;
-       const FLAC__bool is_known_variable_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize);
-       const FLAC__bool is_known_fixed_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize);
 
        FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
 
 
        FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
 
@@ -2138,12 +2141,9 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
        raw_header[1] = decoder->private_->header_warmup[1];
        raw_header_len = 2;
 
        raw_header[1] = decoder->private_->header_warmup[1];
        raw_header_len = 2;
 
-       /*
-        * check to make sure that the reserved bits are 0
-        */
-       if(raw_header[1] & 0x03) { /* MAGIC NUMBER */
+       /* check to make sure that reserved bit is 0 */
+       if(raw_header[1] & 0x02) /* MAGIC NUMBER */
                is_unparseable = true;
                is_unparseable = true;
-       }
 
        /*
         * Note that along the way as we read the header, we look for a sync
 
        /*
         * Note that along the way as we read the header, we look for a sync
@@ -2183,10 +2183,7 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
 
        switch(x = raw_header[2] >> 4) {
                case 0:
 
        switch(x = raw_header[2] >> 4) {
                case 0:
-                       if(is_known_fixed_blocksize_stream)
-                               decoder->private_->frame.header.blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize;
-                       else
-                               is_unparseable = true;
+                       is_unparseable = true;
                        break;
                case 1:
                        decoder->private_->frame.header.blocksize = 192;
                        break;
                case 1:
                        decoder->private_->frame.header.blocksize = 192;
@@ -2224,9 +2221,13 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
                                is_unparseable = true;
                        break;
                case 1:
                                is_unparseable = true;
                        break;
                case 1:
+                       decoder->private_->frame.header.sample_rate = 88200;
+                       break;
                case 2:
                case 2:
+                       decoder->private_->frame.header.sample_rate = 176400;
+                       break;
                case 3:
                case 3:
-                       is_unparseable = true;
+                       decoder->private_->frame.header.sample_rate = 192000;
                        break;
                case 4:
                        decoder->private_->frame.header.sample_rate = 8000;
                        break;
                case 4:
                        decoder->private_->frame.header.sample_rate = 8000;
@@ -2319,42 +2320,29 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
                        break;
        }
 
                        break;
        }
 
-       if(raw_header[3] & 0x01) { /* this should be a zero padding bit */
-               send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
-               decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-               return true;
-       }
+       /* check to make sure that reserved bit is 0 */
+       if(raw_header[3] & 0x01) /* MAGIC NUMBER */
+               is_unparseable = true;
 
 
-       /*
-        * Now we get to the regrettable consequences of not knowing for sure
-        * whether we got a frame number or a sample number.  There are no
-        * encoders that do variable-blocksize encoding so unless we know from
-        * the STREAMINFO that it is variable-blocksize we will assume it is
-        * fixed-blocksize.  The trouble comes when we have no STREAMINFO; again
-        * we will guess that is fixed-blocksize.  Where this can go wrong: 1) a
-        * variable-blocksize stream with no STREAMINFO; 2) a fixed-blocksize
-        * stream that was edited such that one or more frames before or
-        * including this one do not have the same number of samples as the
-        * STREAMINFO's min and max blocksize.
-        */
-       if(is_known_variable_blocksize_stream) {
-               if(blocksize_hint) {
-                       if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len))
-                               return false; /* read_callback_ sets the state for us */
-                       if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
-                               decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
-                               decoder->private_->cached = true;
-                               send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
-                               decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
-                               return true;
-                       }
-                       decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
-                       decoder->private_->frame.header.number.sample_number = xx;
+       /* read the frame's starting sample number (or frame number as the case may be) */
+       if(
+               raw_header[1] & 0x01 ||
+               /*@@@ this clause is a concession to the old way of doing variable blocksize; the only known implementation is flake and can probably be removed without inconveniencing anyone */
+               (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize)
+       ) { /* variable blocksize */
+               if(!FLAC__bitreader_read_utf8_uint64(decoder->private_->input, &xx, raw_header, &raw_header_len))
+                       return false; /* read_callback_ sets the state for us */
+               if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */
+                       decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
+                       decoder->private_->cached = true;
+                       send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER);
+                       decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+                       return true;
                }
                }
-               else
-                       is_unparseable = true;
+               decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
+               decoder->private_->frame.header.number.sample_number = xx;
        }
        }
-       else {
+       else { /* fixed blocksize */
                if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len))
                        return false; /* read_callback_ sets the state for us */
                if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
                if(!FLAC__bitreader_read_utf8_uint32(decoder->private_->input, &x, raw_header, &raw_header_len))
                        return false; /* read_callback_ sets the state for us */
                if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
@@ -2364,23 +2352,8 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
                        decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
                        return true;
                }
                        decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
                        return true;
                }
-               decoder->private_->last_frame_number = x;
-               decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
-               if(decoder->private_->has_stream_info) {
-                       FLAC__ASSERT(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize);
-                       decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x;
-                       decoder->private_->last_block_size = decoder->private_->frame.header.blocksize;
-               }
-               else if(blocksize_hint) {
-                       if(decoder->private_->last_block_size)
-                               decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->last_block_size * (FLAC__uint64)x;
-                       else
-                               is_unparseable = true;
-               }
-               else {
-                       decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x;
-                       decoder->private_->last_block_size = decoder->private_->frame.header.blocksize;
-               }
+               decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER;
+               decoder->private_->frame.header.number.frame_number = x;
        }
 
        if(blocksize_hint) {
        }
 
        if(blocksize_hint) {
@@ -2427,6 +2400,31 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder)
                return true;
        }
 
                return true;
        }
 
+       /* calculate the sample number from the frame number if needed */
+       decoder->private_->next_fixed_block_size = 0;
+       if(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) {
+               x = decoder->private_->frame.header.number.frame_number;
+               decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER;
+               if(decoder->private_->fixed_block_size)
+                       decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->fixed_block_size * (FLAC__uint64)x;
+               else if(decoder->private_->has_stream_info) {
+                       if(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize) {
+                               decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x;
+                               decoder->private_->next_fixed_block_size = decoder->private_->stream_info.data.stream_info.max_blocksize;
+                       }
+                       else
+                               is_unparseable = true;
+               }
+               else if(x == 0) {
+                       decoder->private_->frame.header.number.sample_number = 0;
+                       decoder->private_->next_fixed_block_size = decoder->private_->frame.header.blocksize;
+               }
+               else {
+                       /* can only get here if the stream has invalid frame numbering and no STREAMINFO, so assume it's not the last (possibly short) frame */
+                       decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x;
+               }
+       }
+
        if(is_unparseable) {
                send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
                decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
        if(is_unparseable) {
                send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM);
                decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
@@ -2554,6 +2552,7 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel,
        subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
        subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+               case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
                        if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state for us */
                        subframe->entropy_coding_method.data.partitioned_rice.order = u32;
                        if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state for us */
                        subframe->entropy_coding_method.data.partitioned_rice.order = u32;
@@ -2568,7 +2567,8 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel,
        /* read residual */
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
        /* read residual */
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
-                       if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel]))
+               case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
+                       if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
                                return false;
                        break;
                default:
                                return false;
                        break;
                default:
@@ -2631,6 +2631,7 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un
        subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
        subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32;
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+               case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
                        if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state for us */
                        subframe->entropy_coding_method.data.partitioned_rice.order = u32;
                        if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
                                return false; /* read_callback_ sets the state for us */
                        subframe->entropy_coding_method.data.partitioned_rice.order = u32;
@@ -2645,7 +2646,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un
        /* read residual */
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
        /* read residual */
        switch(subframe->entropy_coding_method.type) {
                case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
-                       if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel]))
+               case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
+                       if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel], /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2))
                                return false;
                        break;
                default:
                                return false;
                        break;
                default:
@@ -2697,13 +2699,15 @@ FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channe
        return true;
 }
 
        return true;
 }
 
-FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual)
+FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended)
 {
        FLAC__uint32 rice_parameter;
        int i;
        unsigned partition, sample, u;
        const unsigned partitions = 1u << partition_order;
        const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order;
 {
        FLAC__uint32 rice_parameter;
        int i;
        unsigned partition, sample, u;
        const unsigned partitions = 1u << partition_order;
        const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order;
+       const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
+       const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
 
        /* sanity checks */
        if(partition_order == 0) {
 
        /* sanity checks */
        if(partition_order == 0) {
@@ -2728,10 +2732,11 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
 
        sample = 0;
        for(partition = 0; partition < partitions; partition++) {
 
        sample = 0;
        for(partition = 0; partition < partitions; partition++) {
-               if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
+               if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, plen))
                        return false; /* read_callback_ sets the state for us */
                partitioned_rice_contents->parameters[partition] = rice_parameter;
                        return false; /* read_callback_ sets the state for us */
                partitioned_rice_contents->parameters[partition] = rice_parameter;
-               if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
+               if(rice_parameter < pesc) {
+                       partitioned_rice_contents->raw_bits[partition] = 0;
                        u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
                        if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
                                return false; /* read_callback_ sets the state for us */
                        u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
                        if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter))
                                return false; /* read_callback_ sets the state for us */
@@ -2978,7 +2983,6 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
        /* we are just guessing here */
        if(max_framesize > 0)
                approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1;
        /* we are just guessing here */
        if(max_framesize > 0)
                approx_bytes_per_frame = (max_framesize + min_framesize) / 2 + 1;
-
        /*
         * Check if it's a known fixed-blocksize stream.  Note that though
         * the spec doesn't allow zeroes in the STREAMINFO block, we may
        /*
         * Check if it's a known fixed-blocksize stream.  Note that though
         * the spec doesn't allow zeroes in the STREAMINFO block, we may
@@ -3001,9 +3005,9 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
        lower_bound = first_frame_offset;
        lower_bound_sample = 0;
        upper_bound = stream_length;
        lower_bound = first_frame_offset;
        lower_bound_sample = 0;
        upper_bound = stream_length;
-       upper_bound_sample = total_samples > 0 ? total_samples : target_sample;
-       if(upper_bound_sample == 0)
-               upper_bound_sample = 1;
+       upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/;
+
+       /*@@@@@@ add step to validate seek table before using?  encoding to pipe leaves some flac files with incomplete seektables which screw us up */
 
        /*
         * Now we refine the bounds if we have a seektable with
 
        /*
         * Now we refine the bounds if we have a seektable with
@@ -3032,6 +3036,19 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
                }
        }
 
                }
        }
 
+       FLAC__ASSERT(upper_bound_sample >= lower_bound_sample);
+       /* there are 2 insidious ways that the following equality occurs, which
+        * we need to fix:
+        *  1) total_samples is 0 (unknown) and target_sample is 0
+        *  2) total_samples is 0 (unknown) and target_sample happens to be
+        *     exactly equal to the last seek point in the seek table; this
+        *     means there is no seek point above it, and upper_bound_samples
+        *     remains equal to the estimate (of target_samples) we made above
+        * in either case it does not hurt to move upper_bound_sample up by 1
+        */
+       if(upper_bound_sample == lower_bound_sample)
+               upper_bound_sample++;
+
        decoder->private_->target_sample = target_sample;
        while(1) {
                /* check if the bounds are still ok */
        decoder->private_->target_sample = target_sample;
        while(1) {
                /* check if the bounds are still ok */
@@ -3083,21 +3100,23 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
                if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
                        break;
 #endif
                if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM)
                        break;
 #endif
-               if(!decoder->private_->is_seeking) {
+               if(!decoder->private_->is_seeking)
                        break;
                        break;
-               }
+
+               FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
                this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
 
                this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
 
-               if (!decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) {
+               if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) {
                        if (pos == (FLAC__int64)lower_bound) {
                        if (pos == (FLAC__int64)lower_bound) {
+                               /* can't move back any more than the first frame, something is fatally wrong */
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
                                return false;
                        }
                        /* our last move backwards wasn't big enough, try again */
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
                                return false;
                        }
                        /* our last move backwards wasn't big enough, try again */
-                       approx_bytes_per_frame *= 2;
+                       approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16;
                        continue;       
                }
                        continue;       
                }
-               /* allow one seek over upper bound, required for streams with unknown total_samples */
+               /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */
                first_seek = false;
                
                /* make sure we are not seeking in corrupted stream */
                first_seek = false;
                
                /* make sure we are not seeking in corrupted stream */
@@ -3106,20 +3125,17 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
                        return false;
                }
 
                        return false;
                }
 
-               FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
-
                /* we need to narrow the search */
                if(target_sample < this_frame_sample) {
                        upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
                /* we need to narrow the search */
                if(target_sample < this_frame_sample) {
                        upper_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
+/*@@@@@@ what will decode position be if at end of stream? */
                        if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) {
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
                                return false;
                        }
                        approx_bytes_per_frame = (unsigned)(2 * (upper_bound - pos) / 3 + 16);
                }
                        if(!FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) {
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
                                return false;
                        }
                        approx_bytes_per_frame = (unsigned)(2 * (upper_bound - pos) / 3 + 16);
                }
-               else {
-                       /* target_sample >= this_frame_sample + this frame's blocksize */
-
+               else { /* target_sample >= this_frame_sample + this frame's blocksize */
                        lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
                        if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) {
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
                        lower_bound_sample = this_frame_sample + decoder->private_->last_frame.header.blocksize;
                        if(!FLAC__stream_decoder_get_decode_position(decoder, &lower_bound)) {
                                decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR;
index 8b9558b..6873dfc 100644 (file)
@@ -229,6 +229,9 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit
        if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
                return false;
 
        if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
                return false;
 
+       if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN))
+               return false;
+
        FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
        /* when this assertion holds true, any legal blocksize can be expressed in the frame header */
        FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u);
        FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
        /* when this assertion holds true, any legal blocksize can be expressed in the frame header */
        FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u);