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

Note

For a sample program of without LCD Board, please refer to GR-PEACH_Audio_Playback_Sample.

Introduction

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.

1. Overview of the Sample Code

1.1 Software Block Diagram

Figure 1.1 shows the software block diagram.

/media/uploads/1050186/lcd_figure1_1.png

1.2 Pin Definitions

Table 1.1 shows the pins used in this sample code.

/media/uploads/1050186/lcd_table1_1.png

2. Sample Code Operating Environment

In order to operate this sample code, GR-PEACH, Audio Camera Shield and 7.1 inch LCD Shield must be needed. For details on Audio Camera Shield and 7.1 inch LCD Shield, please refer to the following links, respectively:

In this section, it is described that how board is configured and to control audio playback via command line and touch screen.

2.1 Operating Environment

Figure 2.1 shows the overview of the operating environment for this sample code.

/media/uploads/1050186/lcd_figure2_1.png

Figure 2.2 and 2.3 show how to configure GR-PEACH, Audio Camera Shield and 7.1 inch LCD shield when using USB0 and USB1, respectively.

/media/uploads/1050186/lcd_figure2_2.png /media/uploads/1050186/lcd_figure2_3.png

Table 2.1 lists the overview of Graphical User Interface (GUI) of this sample code.

/media/uploads/1050186/lcd_table2_1.png

2.2 List of User Operations

Table 2.2 shows the relationship among Audio Playback, Command Line and Onboard Switch.

/media/uploads/1050186/lcd_table2_2.png

3. Function Outline

Table 3.1, 3.2 and 3.3 shows the overview of functions implemented in this sample code.

/media/uploads/1050186/lcd_table3_1.png /media/uploads/1050186/lcd_table3_2.png /media/uploads/1050186/lcd_table3_3.png /media/uploads/1050186/lcd_figure3_1.png

3.1 Playback Control

This sample program supports the operation "play", "pause", "stop", "play next song" and "play previous song".

3.2 Trick Play Control

In order to enable/disable Repeat Mode, user need to type "repeat" on command line or click the corresponding icon shown in Table 2.2. By derault, Repeat Mode is enabled. When Repeat Mode is enabled, the first song is played back after the playback of the last song is finished. Otherwise, the playback is shopped when finishing to play back the last song.

3.3 How to see Song Information

The information of the song being played back can be seen by typing playinfo on command line. Table 3.4 lists the items user can see on the terminal.

/media/uploads/dkato/audioplayback_table3_4.png

3.4 How to analyze the folder structure in USB stick

In this sample code, the folder structure in USB stick is analyzed in the breadth-first order. Table 3.5 shows how the files in USB stick are numbered.

/media/uploads/dkato/audioplayback_table3_5.png

4.Others

4.1 Serial Communication Setting

With respect to the default serial communication related setting on mbed, please refer to the follwing link:
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication
Please set up the terminal software you would like to use on your PC in consideration of the above. For example, 9600 should be specified for the baud rate on the terminal in order to control this sample via command line.

4.2 Necessary modification when using GCC ARM Embedded

If you would like to use GCC ARM Embedded, you must revise the following linker script incorporated in mbed OS 5 package as follows:

  • Linker Script to be modified
    $(PROJECT_ROOT)/mbed-os/targets/TARGET_RENESAS/TARGET_RZ_A1H/device/TOOLCHAIN_GCC_ARM/RZA1H.ld

    Please note that $(PROJECT_ROOT) in the above denotes the root directory of this sample code

  • Before Modification

RZA1H.ld

/* Linker script for mbed RZ_A1H */

/* Linker script to configure memory regions. */
MEMORY
{
  ROM   (rx)  : ORIGIN = 0x00000000, LENGTH = 0x02000000
  BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000 
  SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000 
  L_TTB (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00004000 
  RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00700000
  RAM_NC (rwx) : ORIGIN = 0x20900000, LENGTH = 0x00100000
}
(snip)
  • After Modification

RZA1H.ld

/* Linker script for mbed RZ_A1H */

/* Linker script to configure memory regions. */
MEMORY
{
  ROM   (rx)  : ORIGIN = 0x00000000, LENGTH = 0x02000000
  BOOT_LOADER (rx) : ORIGIN = 0x18000000, LENGTH = 0x00004000 
  SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000 
  L_TTB (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00004000 
  RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00180000
  RAM_NC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x00680000
}
(snip)
Committer:
Osamu Nakamura
Date:
Tue Apr 11 12:42:10 2017 +0900
Revision:
6:a957aaa284f0
Parent:
0:ee40da884cfc
Update R-BSP from rev. cbb9d60c8748 to fb9eda52224e so that this program can be compiled with IAR toolchain.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:ee40da884cfc 1 /* libFLAC - Free Lossless Audio Codec library
dkato 0:ee40da884cfc 2 * Copyright (C) 2000-2009 Josh Coalson
dkato 0:ee40da884cfc 3 * Copyright (C) 2011-2014 Xiph.Org Foundation
dkato 0:ee40da884cfc 4 *
dkato 0:ee40da884cfc 5 * Redistribution and use in source and binary forms, with or without
dkato 0:ee40da884cfc 6 * modification, are permitted provided that the following conditions
dkato 0:ee40da884cfc 7 * are met:
dkato 0:ee40da884cfc 8 *
dkato 0:ee40da884cfc 9 * - Redistributions of source code must retain the above copyright
dkato 0:ee40da884cfc 10 * notice, this list of conditions and the following disclaimer.
dkato 0:ee40da884cfc 11 *
dkato 0:ee40da884cfc 12 * - Redistributions in binary form must reproduce the above copyright
dkato 0:ee40da884cfc 13 * notice, this list of conditions and the following disclaimer in the
dkato 0:ee40da884cfc 14 * documentation and/or other materials provided with the distribution.
dkato 0:ee40da884cfc 15 *
dkato 0:ee40da884cfc 16 * - Neither the name of the Xiph.org Foundation nor the names of its
dkato 0:ee40da884cfc 17 * contributors may be used to endorse or promote products derived from
dkato 0:ee40da884cfc 18 * this software without specific prior written permission.
dkato 0:ee40da884cfc 19 *
dkato 0:ee40da884cfc 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dkato 0:ee40da884cfc 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dkato 0:ee40da884cfc 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dkato 0:ee40da884cfc 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
dkato 0:ee40da884cfc 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dkato 0:ee40da884cfc 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
dkato 0:ee40da884cfc 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
dkato 0:ee40da884cfc 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
dkato 0:ee40da884cfc 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
dkato 0:ee40da884cfc 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
dkato 0:ee40da884cfc 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dkato 0:ee40da884cfc 31 */
dkato 0:ee40da884cfc 32
dkato 0:ee40da884cfc 33 #ifdef HAVE_CONFIG_H
dkato 0:ee40da884cfc 34 # include <config.h>
dkato 0:ee40da884cfc 35 #endif
dkato 0:ee40da884cfc 36
dkato 0:ee40da884cfc 37 #include <stdlib.h>
dkato 0:ee40da884cfc 38 #include <string.h>
dkato 0:ee40da884cfc 39 #include "private/bitmath.h"
dkato 0:ee40da884cfc 40 #include "private/bitreader.h"
dkato 0:ee40da884cfc 41 #include "private/crc.h"
dkato 0:ee40da884cfc 42 #include "private/macros.h"
dkato 0:ee40da884cfc 43 #include "FLAC/assert.h"
dkato 0:ee40da884cfc 44 #include "share/compat.h"
dkato 0:ee40da884cfc 45 #include "share/endswap.h"
dkato 0:ee40da884cfc 46
dkato 0:ee40da884cfc 47 /* Things should be fastest when this matches the machine word size */
dkato 0:ee40da884cfc 48 /* WATCHOUT: if you change this you must also change the following #defines down to FLAC__clz_uint32 below to match */
dkato 0:ee40da884cfc 49 /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */
dkato 0:ee40da884cfc 50 /* also, some sections currently only have fast versions for 4 or 8 bytes per word */
dkato 0:ee40da884cfc 51 #define FLAC__BYTES_PER_WORD 4 /* sizeof uint32_t */
dkato 0:ee40da884cfc 52 #define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD)
dkato 0:ee40da884cfc 53 #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff)
dkato 0:ee40da884cfc 54 /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */
dkato 0:ee40da884cfc 55 #if WORDS_BIGENDIAN
dkato 0:ee40da884cfc 56 #define SWAP_BE_WORD_TO_HOST(x) (x)
dkato 0:ee40da884cfc 57 #else
dkato 0:ee40da884cfc 58 #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x)
dkato 0:ee40da884cfc 59 #endif
dkato 0:ee40da884cfc 60
dkato 0:ee40da884cfc 61 /*
dkato 0:ee40da884cfc 62 * This should be at least twice as large as the largest number of words
dkato 0:ee40da884cfc 63 * required to represent any 'number' (in any encoding) you are going to
dkato 0:ee40da884cfc 64 * read. With FLAC this is on the order of maybe a few hundred bits.
dkato 0:ee40da884cfc 65 * If the buffer is smaller than that, the decoder won't be able to read
dkato 0:ee40da884cfc 66 * in a whole number that is in a variable length encoding (e.g. Rice).
dkato 0:ee40da884cfc 67 * But to be practical it should be at least 1K bytes.
dkato 0:ee40da884cfc 68 *
dkato 0:ee40da884cfc 69 * Increase this number to decrease the number of read callbacks, at the
dkato 0:ee40da884cfc 70 * expense of using more memory. Or decrease for the reverse effect,
dkato 0:ee40da884cfc 71 * keeping in mind the limit from the first paragraph. The optimal size
dkato 0:ee40da884cfc 72 * also depends on the CPU cache size and other factors; some twiddling
dkato 0:ee40da884cfc 73 * may be necessary to squeeze out the best performance.
dkato 0:ee40da884cfc 74 */
dkato 0:ee40da884cfc 75 static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */
dkato 0:ee40da884cfc 76
dkato 0:ee40da884cfc 77 struct FLAC__BitReader {
dkato 0:ee40da884cfc 78 /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */
dkato 0:ee40da884cfc 79 /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */
dkato 0:ee40da884cfc 80 uint32_t *buffer;
dkato 0:ee40da884cfc 81 unsigned capacity; /* in words */
dkato 0:ee40da884cfc 82 unsigned words; /* # of completed words in buffer */
dkato 0:ee40da884cfc 83 unsigned bytes; /* # of bytes in incomplete word at buffer[words] */
dkato 0:ee40da884cfc 84 unsigned consumed_words; /* #words ... */
dkato 0:ee40da884cfc 85 unsigned consumed_bits; /* ... + (#bits of head word) already consumed from the front of buffer */
dkato 0:ee40da884cfc 86 unsigned read_crc16; /* the running frame CRC */
dkato 0:ee40da884cfc 87 unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
dkato 0:ee40da884cfc 88 FLAC__BitReaderReadCallback read_callback;
dkato 0:ee40da884cfc 89 void *client_data;
dkato 0:ee40da884cfc 90 };
dkato 0:ee40da884cfc 91
dkato 0:ee40da884cfc 92 static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word)
dkato 0:ee40da884cfc 93 {
dkato 0:ee40da884cfc 94 register unsigned crc = br->read_crc16;
dkato 0:ee40da884cfc 95 #if FLAC__BYTES_PER_WORD == 4
dkato 0:ee40da884cfc 96 switch(br->crc16_align) {
dkato 0:ee40da884cfc 97 case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 24), crc);
dkato 0:ee40da884cfc 98 case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc);
dkato 0:ee40da884cfc 99 case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc);
dkato 0:ee40da884cfc 100 case 24: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc);
dkato 0:ee40da884cfc 101 }
dkato 0:ee40da884cfc 102 #elif FLAC__BYTES_PER_WORD == 8
dkato 0:ee40da884cfc 103 switch(br->crc16_align) {
dkato 0:ee40da884cfc 104 case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 56), crc);
dkato 0:ee40da884cfc 105 case 8: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 48) & 0xff), crc);
dkato 0:ee40da884cfc 106 case 16: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 40) & 0xff), crc);
dkato 0:ee40da884cfc 107 case 24: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 32) & 0xff), crc);
dkato 0:ee40da884cfc 108 case 32: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 24) & 0xff), crc);
dkato 0:ee40da884cfc 109 case 40: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 16) & 0xff), crc);
dkato 0:ee40da884cfc 110 case 48: crc = FLAC__CRC16_UPDATE((unsigned)((word >> 8) & 0xff), crc);
dkato 0:ee40da884cfc 111 case 56: br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)(word & 0xff), crc);
dkato 0:ee40da884cfc 112 }
dkato 0:ee40da884cfc 113 #else
dkato 0:ee40da884cfc 114 for( ; br->crc16_align < FLAC__BITS_PER_WORD; br->crc16_align += 8)
dkato 0:ee40da884cfc 115 crc = FLAC__CRC16_UPDATE((unsigned)((word >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), crc);
dkato 0:ee40da884cfc 116 br->read_crc16 = crc;
dkato 0:ee40da884cfc 117 #endif
dkato 0:ee40da884cfc 118 br->crc16_align = 0;
dkato 0:ee40da884cfc 119 }
dkato 0:ee40da884cfc 120
dkato 0:ee40da884cfc 121 static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
dkato 0:ee40da884cfc 122 {
dkato 0:ee40da884cfc 123 unsigned start, end;
dkato 0:ee40da884cfc 124 size_t bytes;
dkato 0:ee40da884cfc 125 FLAC__byte *target;
dkato 0:ee40da884cfc 126
dkato 0:ee40da884cfc 127 /* first shift the unconsumed buffer data toward the front as much as possible */
dkato 0:ee40da884cfc 128 if(br->consumed_words > 0) {
dkato 0:ee40da884cfc 129 start = br->consumed_words;
dkato 0:ee40da884cfc 130 end = br->words + (br->bytes? 1:0);
dkato 0:ee40da884cfc 131 memmove(br->buffer, br->buffer+start, FLAC__BYTES_PER_WORD * (end - start));
dkato 0:ee40da884cfc 132
dkato 0:ee40da884cfc 133 br->words -= start;
dkato 0:ee40da884cfc 134 br->consumed_words = 0;
dkato 0:ee40da884cfc 135 }
dkato 0:ee40da884cfc 136
dkato 0:ee40da884cfc 137 /*
dkato 0:ee40da884cfc 138 * set the target for reading, taking into account word alignment and endianness
dkato 0:ee40da884cfc 139 */
dkato 0:ee40da884cfc 140 bytes = (br->capacity - br->words) * FLAC__BYTES_PER_WORD - br->bytes;
dkato 0:ee40da884cfc 141 if(bytes == 0)
dkato 0:ee40da884cfc 142 return false; /* no space left, buffer is too small; see note for FLAC__BITREADER_DEFAULT_CAPACITY */
dkato 0:ee40da884cfc 143 target = ((FLAC__byte*)(br->buffer+br->words)) + br->bytes;
dkato 0:ee40da884cfc 144
dkato 0:ee40da884cfc 145 /* before reading, if the existing reader looks like this (say uint32_t is 32 bits wide)
dkato 0:ee40da884cfc 146 * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1 (partial tail word is left-justified)
dkato 0:ee40da884cfc 147 * buffer[BE]: 11 22 33 44 55 ?? ?? ?? (shown layed out as bytes sequentially in memory)
dkato 0:ee40da884cfc 148 * buffer[LE]: 44 33 22 11 ?? ?? ?? 55 (?? being don't-care)
dkato 0:ee40da884cfc 149 * ^^-------target, bytes=3
dkato 0:ee40da884cfc 150 * on LE machines, have to byteswap the odd tail word so nothing is
dkato 0:ee40da884cfc 151 * overwritten:
dkato 0:ee40da884cfc 152 */
dkato 0:ee40da884cfc 153 #if WORDS_BIGENDIAN
dkato 0:ee40da884cfc 154 #else
dkato 0:ee40da884cfc 155 if(br->bytes)
dkato 0:ee40da884cfc 156 br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]);
dkato 0:ee40da884cfc 157 #endif
dkato 0:ee40da884cfc 158
dkato 0:ee40da884cfc 159 /* now it looks like:
dkato 0:ee40da884cfc 160 * bitstream : 11 22 33 44 55 br->words=1 br->bytes=1
dkato 0:ee40da884cfc 161 * buffer[BE]: 11 22 33 44 55 ?? ?? ??
dkato 0:ee40da884cfc 162 * buffer[LE]: 44 33 22 11 55 ?? ?? ??
dkato 0:ee40da884cfc 163 * ^^-------target, bytes=3
dkato 0:ee40da884cfc 164 */
dkato 0:ee40da884cfc 165
dkato 0:ee40da884cfc 166 /* read in the data; note that the callback may return a smaller number of bytes */
dkato 0:ee40da884cfc 167 if(!br->read_callback(target, &bytes, br->client_data))
dkato 0:ee40da884cfc 168 return false;
dkato 0:ee40da884cfc 169
dkato 0:ee40da884cfc 170 /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client:
dkato 0:ee40da884cfc 171 * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
dkato 0:ee40da884cfc 172 * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
dkato 0:ee40da884cfc 173 * buffer[LE]: 44 33 22 11 55 66 77 88 99 AA BB CC DD EE FF ??
dkato 0:ee40da884cfc 174 * now have to byteswap on LE machines:
dkato 0:ee40da884cfc 175 */
dkato 0:ee40da884cfc 176 #if WORDS_BIGENDIAN
dkato 0:ee40da884cfc 177 #else
dkato 0:ee40da884cfc 178 end = (br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes + (FLAC__BYTES_PER_WORD-1)) / FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 179 for(start = br->words; start < end; start++)
dkato 0:ee40da884cfc 180 br->buffer[start] = SWAP_BE_WORD_TO_HOST(br->buffer[start]);
dkato 0:ee40da884cfc 181 #endif
dkato 0:ee40da884cfc 182
dkato 0:ee40da884cfc 183 /* now it looks like:
dkato 0:ee40da884cfc 184 * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
dkato 0:ee40da884cfc 185 * buffer[BE]: 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF ??
dkato 0:ee40da884cfc 186 * buffer[LE]: 44 33 22 11 88 77 66 55 CC BB AA 99 ?? FF EE DD
dkato 0:ee40da884cfc 187 * finally we'll update the reader values:
dkato 0:ee40da884cfc 188 */
dkato 0:ee40da884cfc 189 end = br->words*FLAC__BYTES_PER_WORD + br->bytes + bytes;
dkato 0:ee40da884cfc 190 br->words = end / FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 191 br->bytes = end % FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 192
dkato 0:ee40da884cfc 193 return true;
dkato 0:ee40da884cfc 194 }
dkato 0:ee40da884cfc 195
dkato 0:ee40da884cfc 196 /***********************************************************************
dkato 0:ee40da884cfc 197 *
dkato 0:ee40da884cfc 198 * Class constructor/destructor
dkato 0:ee40da884cfc 199 *
dkato 0:ee40da884cfc 200 ***********************************************************************/
dkato 0:ee40da884cfc 201
dkato 0:ee40da884cfc 202 FLAC__BitReader *FLAC__bitreader_new(void)
dkato 0:ee40da884cfc 203 {
dkato 0:ee40da884cfc 204 FLAC__BitReader *br = calloc(1, sizeof(FLAC__BitReader));
dkato 0:ee40da884cfc 205
dkato 0:ee40da884cfc 206 /* calloc() implies:
dkato 0:ee40da884cfc 207 memset(br, 0, sizeof(FLAC__BitReader));
dkato 0:ee40da884cfc 208 br->buffer = 0;
dkato 0:ee40da884cfc 209 br->capacity = 0;
dkato 0:ee40da884cfc 210 br->words = br->bytes = 0;
dkato 0:ee40da884cfc 211 br->consumed_words = br->consumed_bits = 0;
dkato 0:ee40da884cfc 212 br->read_callback = 0;
dkato 0:ee40da884cfc 213 br->client_data = 0;
dkato 0:ee40da884cfc 214 */
dkato 0:ee40da884cfc 215 return br;
dkato 0:ee40da884cfc 216 }
dkato 0:ee40da884cfc 217
dkato 0:ee40da884cfc 218 void FLAC__bitreader_delete(FLAC__BitReader *br)
dkato 0:ee40da884cfc 219 {
dkato 0:ee40da884cfc 220 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 221
dkato 0:ee40da884cfc 222 FLAC__bitreader_free(br);
dkato 0:ee40da884cfc 223 free(br);
dkato 0:ee40da884cfc 224 }
dkato 0:ee40da884cfc 225
dkato 0:ee40da884cfc 226 /***********************************************************************
dkato 0:ee40da884cfc 227 *
dkato 0:ee40da884cfc 228 * Public class methods
dkato 0:ee40da884cfc 229 *
dkato 0:ee40da884cfc 230 ***********************************************************************/
dkato 0:ee40da884cfc 231
dkato 0:ee40da884cfc 232 FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd)
dkato 0:ee40da884cfc 233 {
dkato 0:ee40da884cfc 234 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 235
dkato 0:ee40da884cfc 236 br->words = br->bytes = 0;
dkato 0:ee40da884cfc 237 br->consumed_words = br->consumed_bits = 0;
dkato 0:ee40da884cfc 238 br->capacity = FLAC__BITREADER_DEFAULT_CAPACITY;
dkato 0:ee40da884cfc 239 br->buffer = malloc(sizeof(uint32_t) * br->capacity);
dkato 0:ee40da884cfc 240 if(br->buffer == 0)
dkato 0:ee40da884cfc 241 return false;
dkato 0:ee40da884cfc 242 br->read_callback = rcb;
dkato 0:ee40da884cfc 243 br->client_data = cd;
dkato 0:ee40da884cfc 244
dkato 0:ee40da884cfc 245 return true;
dkato 0:ee40da884cfc 246 }
dkato 0:ee40da884cfc 247
dkato 0:ee40da884cfc 248 void FLAC__bitreader_free(FLAC__BitReader *br)
dkato 0:ee40da884cfc 249 {
dkato 0:ee40da884cfc 250 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 251
dkato 0:ee40da884cfc 252 if(0 != br->buffer)
dkato 0:ee40da884cfc 253 free(br->buffer);
dkato 0:ee40da884cfc 254 br->buffer = 0;
dkato 0:ee40da884cfc 255 br->capacity = 0;
dkato 0:ee40da884cfc 256 br->words = br->bytes = 0;
dkato 0:ee40da884cfc 257 br->consumed_words = br->consumed_bits = 0;
dkato 0:ee40da884cfc 258 br->read_callback = 0;
dkato 0:ee40da884cfc 259 br->client_data = 0;
dkato 0:ee40da884cfc 260 }
dkato 0:ee40da884cfc 261
dkato 0:ee40da884cfc 262 FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br)
dkato 0:ee40da884cfc 263 {
dkato 0:ee40da884cfc 264 br->words = br->bytes = 0;
dkato 0:ee40da884cfc 265 br->consumed_words = br->consumed_bits = 0;
dkato 0:ee40da884cfc 266 return true;
dkato 0:ee40da884cfc 267 }
dkato 0:ee40da884cfc 268
dkato 0:ee40da884cfc 269 void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out)
dkato 0:ee40da884cfc 270 {
dkato 0:ee40da884cfc 271 unsigned i, j;
dkato 0:ee40da884cfc 272 if(br == 0) {
dkato 0:ee40da884cfc 273 fprintf(out, "bitreader is NULL\n");
dkato 0:ee40da884cfc 274 }
dkato 0:ee40da884cfc 275 else {
dkato 0:ee40da884cfc 276 fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits);
dkato 0:ee40da884cfc 277
dkato 0:ee40da884cfc 278 for(i = 0; i < br->words; i++) {
dkato 0:ee40da884cfc 279 fprintf(out, "%08X: ", i);
dkato 0:ee40da884cfc 280 for(j = 0; j < FLAC__BITS_PER_WORD; j++)
dkato 0:ee40da884cfc 281 if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits))
dkato 0:ee40da884cfc 282 fprintf(out, ".");
dkato 0:ee40da884cfc 283 else
dkato 0:ee40da884cfc 284 fprintf(out, "%01u", br->buffer[i] & (1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0);
dkato 0:ee40da884cfc 285 fprintf(out, "\n");
dkato 0:ee40da884cfc 286 }
dkato 0:ee40da884cfc 287 if(br->bytes > 0) {
dkato 0:ee40da884cfc 288 fprintf(out, "%08X: ", i);
dkato 0:ee40da884cfc 289 for(j = 0; j < br->bytes*8; j++)
dkato 0:ee40da884cfc 290 if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits))
dkato 0:ee40da884cfc 291 fprintf(out, ".");
dkato 0:ee40da884cfc 292 else
dkato 0:ee40da884cfc 293 fprintf(out, "%01u", br->buffer[i] & (1 << (br->bytes*8-j-1)) ? 1:0);
dkato 0:ee40da884cfc 294 fprintf(out, "\n");
dkato 0:ee40da884cfc 295 }
dkato 0:ee40da884cfc 296 }
dkato 0:ee40da884cfc 297 }
dkato 0:ee40da884cfc 298
dkato 0:ee40da884cfc 299 void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed)
dkato 0:ee40da884cfc 300 {
dkato 0:ee40da884cfc 301 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 302 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 303 FLAC__ASSERT((br->consumed_bits & 7) == 0);
dkato 0:ee40da884cfc 304
dkato 0:ee40da884cfc 305 br->read_crc16 = (unsigned)seed;
dkato 0:ee40da884cfc 306 br->crc16_align = br->consumed_bits;
dkato 0:ee40da884cfc 307 }
dkato 0:ee40da884cfc 308
dkato 0:ee40da884cfc 309 FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br)
dkato 0:ee40da884cfc 310 {
dkato 0:ee40da884cfc 311 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 312 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 313 FLAC__ASSERT((br->consumed_bits & 7) == 0);
dkato 0:ee40da884cfc 314 FLAC__ASSERT(br->crc16_align <= br->consumed_bits);
dkato 0:ee40da884cfc 315
dkato 0:ee40da884cfc 316 /* CRC any tail bytes in a partially-consumed word */
dkato 0:ee40da884cfc 317 if(br->consumed_bits) {
dkato 0:ee40da884cfc 318 const uint32_t tail = br->buffer[br->consumed_words];
dkato 0:ee40da884cfc 319 for( ; br->crc16_align < br->consumed_bits; br->crc16_align += 8)
dkato 0:ee40da884cfc 320 br->read_crc16 = FLAC__CRC16_UPDATE((unsigned)((tail >> (FLAC__BITS_PER_WORD-8-br->crc16_align)) & 0xff), br->read_crc16);
dkato 0:ee40da884cfc 321 }
dkato 0:ee40da884cfc 322 return br->read_crc16;
dkato 0:ee40da884cfc 323 }
dkato 0:ee40da884cfc 324
dkato 0:ee40da884cfc 325 inline FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br)
dkato 0:ee40da884cfc 326 {
dkato 0:ee40da884cfc 327 return ((br->consumed_bits & 7) == 0);
dkato 0:ee40da884cfc 328 }
dkato 0:ee40da884cfc 329
dkato 0:ee40da884cfc 330 inline unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br)
dkato 0:ee40da884cfc 331 {
dkato 0:ee40da884cfc 332 return 8 - (br->consumed_bits & 7);
dkato 0:ee40da884cfc 333 }
dkato 0:ee40da884cfc 334
dkato 0:ee40da884cfc 335 inline unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br)
dkato 0:ee40da884cfc 336 {
dkato 0:ee40da884cfc 337 return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits;
dkato 0:ee40da884cfc 338 }
dkato 0:ee40da884cfc 339
dkato 0:ee40da884cfc 340 FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits)
dkato 0:ee40da884cfc 341 {
dkato 0:ee40da884cfc 342 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 343 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 344
dkato 0:ee40da884cfc 345 FLAC__ASSERT(bits <= 32);
dkato 0:ee40da884cfc 346 FLAC__ASSERT((br->capacity*FLAC__BITS_PER_WORD) * 2 >= bits);
dkato 0:ee40da884cfc 347 FLAC__ASSERT(br->consumed_words <= br->words);
dkato 0:ee40da884cfc 348
dkato 0:ee40da884cfc 349 /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
dkato 0:ee40da884cfc 350 FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
dkato 0:ee40da884cfc 351
dkato 0:ee40da884cfc 352 if(bits == 0) { /* OPT: investigate if this can ever happen, maybe change to assertion */
dkato 0:ee40da884cfc 353 *val = 0;
dkato 0:ee40da884cfc 354 return true;
dkato 0:ee40da884cfc 355 }
dkato 0:ee40da884cfc 356
dkato 0:ee40da884cfc 357 while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) {
dkato 0:ee40da884cfc 358 if(!bitreader_read_from_client_(br))
dkato 0:ee40da884cfc 359 return false;
dkato 0:ee40da884cfc 360 }
dkato 0:ee40da884cfc 361 if(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */
dkato 0:ee40da884cfc 362 /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
dkato 0:ee40da884cfc 363 if(br->consumed_bits) {
dkato 0:ee40da884cfc 364 /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
dkato 0:ee40da884cfc 365 const unsigned n = FLAC__BITS_PER_WORD - br->consumed_bits;
dkato 0:ee40da884cfc 366 const uint32_t word = br->buffer[br->consumed_words];
dkato 0:ee40da884cfc 367 if(bits < n) {
dkato 0:ee40da884cfc 368 *val = (word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits);
dkato 0:ee40da884cfc 369 br->consumed_bits += bits;
dkato 0:ee40da884cfc 370 return true;
dkato 0:ee40da884cfc 371 }
dkato 0:ee40da884cfc 372 *val = word & (FLAC__WORD_ALL_ONES >> br->consumed_bits);
dkato 0:ee40da884cfc 373 bits -= n;
dkato 0:ee40da884cfc 374 crc16_update_word_(br, word);
dkato 0:ee40da884cfc 375 br->consumed_words++;
dkato 0:ee40da884cfc 376 br->consumed_bits = 0;
dkato 0:ee40da884cfc 377 if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */
dkato 0:ee40da884cfc 378 *val <<= bits;
dkato 0:ee40da884cfc 379 *val |= (br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits));
dkato 0:ee40da884cfc 380 br->consumed_bits = bits;
dkato 0:ee40da884cfc 381 }
dkato 0:ee40da884cfc 382 return true;
dkato 0:ee40da884cfc 383 }
dkato 0:ee40da884cfc 384 else {
dkato 0:ee40da884cfc 385 const uint32_t word = br->buffer[br->consumed_words];
dkato 0:ee40da884cfc 386 if(bits < FLAC__BITS_PER_WORD) {
dkato 0:ee40da884cfc 387 *val = word >> (FLAC__BITS_PER_WORD-bits);
dkato 0:ee40da884cfc 388 br->consumed_bits = bits;
dkato 0:ee40da884cfc 389 return true;
dkato 0:ee40da884cfc 390 }
dkato 0:ee40da884cfc 391 /* at this point 'bits' must be == FLAC__BITS_PER_WORD; because of previous assertions, it can't be larger */
dkato 0:ee40da884cfc 392 *val = word;
dkato 0:ee40da884cfc 393 crc16_update_word_(br, word);
dkato 0:ee40da884cfc 394 br->consumed_words++;
dkato 0:ee40da884cfc 395 return true;
dkato 0:ee40da884cfc 396 }
dkato 0:ee40da884cfc 397 }
dkato 0:ee40da884cfc 398 else {
dkato 0:ee40da884cfc 399 /* in this case we're starting our read at a partial tail word;
dkato 0:ee40da884cfc 400 * the reader has guaranteed that we have at least 'bits' bits
dkato 0:ee40da884cfc 401 * available to read, which makes this case simpler.
dkato 0:ee40da884cfc 402 */
dkato 0:ee40da884cfc 403 /* OPT: taking out the consumed_bits==0 "else" case below might make things faster if less code allows the compiler to inline this function */
dkato 0:ee40da884cfc 404 if(br->consumed_bits) {
dkato 0:ee40da884cfc 405 /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */
dkato 0:ee40da884cfc 406 FLAC__ASSERT(br->consumed_bits + bits <= br->bytes*8);
dkato 0:ee40da884cfc 407 *val = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (FLAC__BITS_PER_WORD-br->consumed_bits-bits);
dkato 0:ee40da884cfc 408 br->consumed_bits += bits;
dkato 0:ee40da884cfc 409 return true;
dkato 0:ee40da884cfc 410 }
dkato 0:ee40da884cfc 411 else {
dkato 0:ee40da884cfc 412 *val = br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits);
dkato 0:ee40da884cfc 413 br->consumed_bits += bits;
dkato 0:ee40da884cfc 414 return true;
dkato 0:ee40da884cfc 415 }
dkato 0:ee40da884cfc 416 }
dkato 0:ee40da884cfc 417 }
dkato 0:ee40da884cfc 418
dkato 0:ee40da884cfc 419 FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits)
dkato 0:ee40da884cfc 420 {
dkato 0:ee40da884cfc 421 /* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */
dkato 0:ee40da884cfc 422 if(!FLAC__bitreader_read_raw_uint32(br, (FLAC__uint32*)val, bits))
dkato 0:ee40da884cfc 423 return false;
dkato 0:ee40da884cfc 424 /* sign-extend: */
dkato 0:ee40da884cfc 425 *val <<= (32-bits);
dkato 0:ee40da884cfc 426 *val >>= (32-bits);
dkato 0:ee40da884cfc 427 return true;
dkato 0:ee40da884cfc 428 }
dkato 0:ee40da884cfc 429
dkato 0:ee40da884cfc 430 FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits)
dkato 0:ee40da884cfc 431 {
dkato 0:ee40da884cfc 432 FLAC__uint32 hi, lo;
dkato 0:ee40da884cfc 433
dkato 0:ee40da884cfc 434 if(bits > 32) {
dkato 0:ee40da884cfc 435 if(!FLAC__bitreader_read_raw_uint32(br, &hi, bits-32))
dkato 0:ee40da884cfc 436 return false;
dkato 0:ee40da884cfc 437 if(!FLAC__bitreader_read_raw_uint32(br, &lo, 32))
dkato 0:ee40da884cfc 438 return false;
dkato 0:ee40da884cfc 439 *val = hi;
dkato 0:ee40da884cfc 440 *val <<= 32;
dkato 0:ee40da884cfc 441 *val |= lo;
dkato 0:ee40da884cfc 442 }
dkato 0:ee40da884cfc 443 else {
dkato 0:ee40da884cfc 444 if(!FLAC__bitreader_read_raw_uint32(br, &lo, bits))
dkato 0:ee40da884cfc 445 return false;
dkato 0:ee40da884cfc 446 *val = lo;
dkato 0:ee40da884cfc 447 }
dkato 0:ee40da884cfc 448 return true;
dkato 0:ee40da884cfc 449 }
dkato 0:ee40da884cfc 450
dkato 0:ee40da884cfc 451 inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val)
dkato 0:ee40da884cfc 452 {
dkato 0:ee40da884cfc 453 FLAC__uint32 x8, x32 = 0;
dkato 0:ee40da884cfc 454
dkato 0:ee40da884cfc 455 /* this doesn't need to be that fast as currently it is only used for vorbis comments */
dkato 0:ee40da884cfc 456
dkato 0:ee40da884cfc 457 if(!FLAC__bitreader_read_raw_uint32(br, &x32, 8))
dkato 0:ee40da884cfc 458 return false;
dkato 0:ee40da884cfc 459
dkato 0:ee40da884cfc 460 if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
dkato 0:ee40da884cfc 461 return false;
dkato 0:ee40da884cfc 462 x32 |= (x8 << 8);
dkato 0:ee40da884cfc 463
dkato 0:ee40da884cfc 464 if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
dkato 0:ee40da884cfc 465 return false;
dkato 0:ee40da884cfc 466 x32 |= (x8 << 16);
dkato 0:ee40da884cfc 467
dkato 0:ee40da884cfc 468 if(!FLAC__bitreader_read_raw_uint32(br, &x8, 8))
dkato 0:ee40da884cfc 469 return false;
dkato 0:ee40da884cfc 470 x32 |= (x8 << 24);
dkato 0:ee40da884cfc 471
dkato 0:ee40da884cfc 472 *val = x32;
dkato 0:ee40da884cfc 473 return true;
dkato 0:ee40da884cfc 474 }
dkato 0:ee40da884cfc 475
dkato 0:ee40da884cfc 476 FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits)
dkato 0:ee40da884cfc 477 {
dkato 0:ee40da884cfc 478 /*
dkato 0:ee40da884cfc 479 * OPT: a faster implementation is possible but probably not that useful
dkato 0:ee40da884cfc 480 * since this is only called a couple of times in the metadata readers.
dkato 0:ee40da884cfc 481 */
dkato 0:ee40da884cfc 482 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 483 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 484
dkato 0:ee40da884cfc 485 if(bits > 0) {
dkato 0:ee40da884cfc 486 const unsigned n = br->consumed_bits & 7;
dkato 0:ee40da884cfc 487 unsigned m;
dkato 0:ee40da884cfc 488 FLAC__uint32 x;
dkato 0:ee40da884cfc 489
dkato 0:ee40da884cfc 490 if(n != 0) {
dkato 0:ee40da884cfc 491 m = flac_min(8-n, bits);
dkato 0:ee40da884cfc 492 if(!FLAC__bitreader_read_raw_uint32(br, &x, m))
dkato 0:ee40da884cfc 493 return false;
dkato 0:ee40da884cfc 494 bits -= m;
dkato 0:ee40da884cfc 495 }
dkato 0:ee40da884cfc 496 m = bits / 8;
dkato 0:ee40da884cfc 497 if(m > 0) {
dkato 0:ee40da884cfc 498 if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(br, m))
dkato 0:ee40da884cfc 499 return false;
dkato 0:ee40da884cfc 500 bits %= 8;
dkato 0:ee40da884cfc 501 }
dkato 0:ee40da884cfc 502 if(bits > 0) {
dkato 0:ee40da884cfc 503 if(!FLAC__bitreader_read_raw_uint32(br, &x, bits))
dkato 0:ee40da884cfc 504 return false;
dkato 0:ee40da884cfc 505 }
dkato 0:ee40da884cfc 506 }
dkato 0:ee40da884cfc 507
dkato 0:ee40da884cfc 508 return true;
dkato 0:ee40da884cfc 509 }
dkato 0:ee40da884cfc 510
dkato 0:ee40da884cfc 511 FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals)
dkato 0:ee40da884cfc 512 {
dkato 0:ee40da884cfc 513 FLAC__uint32 x;
dkato 0:ee40da884cfc 514
dkato 0:ee40da884cfc 515 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 516 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 517 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
dkato 0:ee40da884cfc 518
dkato 0:ee40da884cfc 519 /* step 1: skip over partial head word to get word aligned */
dkato 0:ee40da884cfc 520 while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
dkato 0:ee40da884cfc 521 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 522 return false;
dkato 0:ee40da884cfc 523 nvals--;
dkato 0:ee40da884cfc 524 }
dkato 0:ee40da884cfc 525 if(0 == nvals)
dkato 0:ee40da884cfc 526 return true;
dkato 0:ee40da884cfc 527 /* step 2: skip whole words in chunks */
dkato 0:ee40da884cfc 528 while(nvals >= FLAC__BYTES_PER_WORD) {
dkato 0:ee40da884cfc 529 if(br->consumed_words < br->words) {
dkato 0:ee40da884cfc 530 br->consumed_words++;
dkato 0:ee40da884cfc 531 nvals -= FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 532 }
dkato 0:ee40da884cfc 533 else if(!bitreader_read_from_client_(br))
dkato 0:ee40da884cfc 534 return false;
dkato 0:ee40da884cfc 535 }
dkato 0:ee40da884cfc 536 /* step 3: skip any remainder from partial tail bytes */
dkato 0:ee40da884cfc 537 while(nvals) {
dkato 0:ee40da884cfc 538 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 539 return false;
dkato 0:ee40da884cfc 540 nvals--;
dkato 0:ee40da884cfc 541 }
dkato 0:ee40da884cfc 542
dkato 0:ee40da884cfc 543 return true;
dkato 0:ee40da884cfc 544 }
dkato 0:ee40da884cfc 545
dkato 0:ee40da884cfc 546 FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals)
dkato 0:ee40da884cfc 547 {
dkato 0:ee40da884cfc 548 FLAC__uint32 x;
dkato 0:ee40da884cfc 549
dkato 0:ee40da884cfc 550 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 551 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 552 FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br));
dkato 0:ee40da884cfc 553
dkato 0:ee40da884cfc 554 /* step 1: read from partial head word to get word aligned */
dkato 0:ee40da884cfc 555 while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */
dkato 0:ee40da884cfc 556 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 557 return false;
dkato 0:ee40da884cfc 558 *val++ = (FLAC__byte)x;
dkato 0:ee40da884cfc 559 nvals--;
dkato 0:ee40da884cfc 560 }
dkato 0:ee40da884cfc 561 if(0 == nvals)
dkato 0:ee40da884cfc 562 return true;
dkato 0:ee40da884cfc 563 /* step 2: read whole words in chunks */
dkato 0:ee40da884cfc 564 while(nvals >= FLAC__BYTES_PER_WORD) {
dkato 0:ee40da884cfc 565 if(br->consumed_words < br->words) {
dkato 0:ee40da884cfc 566 const uint32_t word = br->buffer[br->consumed_words++];
dkato 0:ee40da884cfc 567 #if FLAC__BYTES_PER_WORD == 4
dkato 0:ee40da884cfc 568 val[0] = (FLAC__byte)(word >> 24);
dkato 0:ee40da884cfc 569 val[1] = (FLAC__byte)(word >> 16);
dkato 0:ee40da884cfc 570 val[2] = (FLAC__byte)(word >> 8);
dkato 0:ee40da884cfc 571 val[3] = (FLAC__byte)word;
dkato 0:ee40da884cfc 572 #elif FLAC__BYTES_PER_WORD == 8
dkato 0:ee40da884cfc 573 val[0] = (FLAC__byte)(word >> 56);
dkato 0:ee40da884cfc 574 val[1] = (FLAC__byte)(word >> 48);
dkato 0:ee40da884cfc 575 val[2] = (FLAC__byte)(word >> 40);
dkato 0:ee40da884cfc 576 val[3] = (FLAC__byte)(word >> 32);
dkato 0:ee40da884cfc 577 val[4] = (FLAC__byte)(word >> 24);
dkato 0:ee40da884cfc 578 val[5] = (FLAC__byte)(word >> 16);
dkato 0:ee40da884cfc 579 val[6] = (FLAC__byte)(word >> 8);
dkato 0:ee40da884cfc 580 val[7] = (FLAC__byte)word;
dkato 0:ee40da884cfc 581 #else
dkato 0:ee40da884cfc 582 for(x = 0; x < FLAC__BYTES_PER_WORD; x++)
dkato 0:ee40da884cfc 583 val[x] = (FLAC__byte)(word >> (8*(FLAC__BYTES_PER_WORD-x-1)));
dkato 0:ee40da884cfc 584 #endif
dkato 0:ee40da884cfc 585 val += FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 586 nvals -= FLAC__BYTES_PER_WORD;
dkato 0:ee40da884cfc 587 }
dkato 0:ee40da884cfc 588 else if(!bitreader_read_from_client_(br))
dkato 0:ee40da884cfc 589 return false;
dkato 0:ee40da884cfc 590 }
dkato 0:ee40da884cfc 591 /* step 3: read any remainder from partial tail bytes */
dkato 0:ee40da884cfc 592 while(nvals) {
dkato 0:ee40da884cfc 593 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 594 return false;
dkato 0:ee40da884cfc 595 *val++ = (FLAC__byte)x;
dkato 0:ee40da884cfc 596 nvals--;
dkato 0:ee40da884cfc 597 }
dkato 0:ee40da884cfc 598
dkato 0:ee40da884cfc 599 return true;
dkato 0:ee40da884cfc 600 }
dkato 0:ee40da884cfc 601
dkato 0:ee40da884cfc 602 FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val)
dkato 0:ee40da884cfc 603 #if 0 /* slow but readable version */
dkato 0:ee40da884cfc 604 {
dkato 0:ee40da884cfc 605 unsigned bit;
dkato 0:ee40da884cfc 606
dkato 0:ee40da884cfc 607 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 608 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 609
dkato 0:ee40da884cfc 610 *val = 0;
dkato 0:ee40da884cfc 611 while(1) {
dkato 0:ee40da884cfc 612 if(!FLAC__bitreader_read_bit(br, &bit))
dkato 0:ee40da884cfc 613 return false;
dkato 0:ee40da884cfc 614 if(bit)
dkato 0:ee40da884cfc 615 break;
dkato 0:ee40da884cfc 616 else
dkato 0:ee40da884cfc 617 *val++;
dkato 0:ee40da884cfc 618 }
dkato 0:ee40da884cfc 619 return true;
dkato 0:ee40da884cfc 620 }
dkato 0:ee40da884cfc 621 #else
dkato 0:ee40da884cfc 622 {
dkato 0:ee40da884cfc 623 unsigned i;
dkato 0:ee40da884cfc 624
dkato 0:ee40da884cfc 625 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 626 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 627
dkato 0:ee40da884cfc 628 *val = 0;
dkato 0:ee40da884cfc 629 while(1) {
dkato 0:ee40da884cfc 630 while(br->consumed_words < br->words) { /* if we've not consumed up to a partial tail word... */
dkato 0:ee40da884cfc 631 uint32_t b = br->buffer[br->consumed_words] << br->consumed_bits;
dkato 0:ee40da884cfc 632 if(b) {
dkato 0:ee40da884cfc 633 i = FLAC__clz_uint32(b);
dkato 0:ee40da884cfc 634 *val += i;
dkato 0:ee40da884cfc 635 i++;
dkato 0:ee40da884cfc 636 br->consumed_bits += i;
dkato 0:ee40da884cfc 637 if(br->consumed_bits >= FLAC__BITS_PER_WORD) { /* faster way of testing if(br->consumed_bits == FLAC__BITS_PER_WORD) */
dkato 0:ee40da884cfc 638 crc16_update_word_(br, br->buffer[br->consumed_words]);
dkato 0:ee40da884cfc 639 br->consumed_words++;
dkato 0:ee40da884cfc 640 br->consumed_bits = 0;
dkato 0:ee40da884cfc 641 }
dkato 0:ee40da884cfc 642 return true;
dkato 0:ee40da884cfc 643 }
dkato 0:ee40da884cfc 644 else {
dkato 0:ee40da884cfc 645 *val += FLAC__BITS_PER_WORD - br->consumed_bits;
dkato 0:ee40da884cfc 646 crc16_update_word_(br, br->buffer[br->consumed_words]);
dkato 0:ee40da884cfc 647 br->consumed_words++;
dkato 0:ee40da884cfc 648 br->consumed_bits = 0;
dkato 0:ee40da884cfc 649 /* didn't find stop bit yet, have to keep going... */
dkato 0:ee40da884cfc 650 }
dkato 0:ee40da884cfc 651 }
dkato 0:ee40da884cfc 652 /* at this point we've eaten up all the whole words; have to try
dkato 0:ee40da884cfc 653 * reading through any tail bytes before calling the read callback.
dkato 0:ee40da884cfc 654 * this is a repeat of the above logic adjusted for the fact we
dkato 0:ee40da884cfc 655 * don't have a whole word. note though if the client is feeding
dkato 0:ee40da884cfc 656 * us data a byte at a time (unlikely), br->consumed_bits may not
dkato 0:ee40da884cfc 657 * be zero.
dkato 0:ee40da884cfc 658 */
dkato 0:ee40da884cfc 659 if(br->bytes*8 > br->consumed_bits) {
dkato 0:ee40da884cfc 660 const unsigned end = br->bytes * 8;
dkato 0:ee40da884cfc 661 uint32_t b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits;
dkato 0:ee40da884cfc 662 if(b) {
dkato 0:ee40da884cfc 663 i = FLAC__clz_uint32(b);
dkato 0:ee40da884cfc 664 *val += i;
dkato 0:ee40da884cfc 665 i++;
dkato 0:ee40da884cfc 666 br->consumed_bits += i;
dkato 0:ee40da884cfc 667 FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD);
dkato 0:ee40da884cfc 668 return true;
dkato 0:ee40da884cfc 669 }
dkato 0:ee40da884cfc 670 else {
dkato 0:ee40da884cfc 671 *val += end - br->consumed_bits;
dkato 0:ee40da884cfc 672 br->consumed_bits = end;
dkato 0:ee40da884cfc 673 FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD);
dkato 0:ee40da884cfc 674 /* didn't find stop bit yet, have to keep going... */
dkato 0:ee40da884cfc 675 }
dkato 0:ee40da884cfc 676 }
dkato 0:ee40da884cfc 677 if(!bitreader_read_from_client_(br))
dkato 0:ee40da884cfc 678 return false;
dkato 0:ee40da884cfc 679 }
dkato 0:ee40da884cfc 680 }
dkato 0:ee40da884cfc 681 #endif
dkato 0:ee40da884cfc 682
dkato 0:ee40da884cfc 683 FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter)
dkato 0:ee40da884cfc 684 {
dkato 0:ee40da884cfc 685 FLAC__uint32 lsbs = 0, msbs = 0;
dkato 0:ee40da884cfc 686 unsigned uval;
dkato 0:ee40da884cfc 687
dkato 0:ee40da884cfc 688 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 689 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 690 FLAC__ASSERT(parameter <= 31);
dkato 0:ee40da884cfc 691
dkato 0:ee40da884cfc 692 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 693 if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
dkato 0:ee40da884cfc 694 return false;
dkato 0:ee40da884cfc 695
dkato 0:ee40da884cfc 696 /* read the binary LSBs */
dkato 0:ee40da884cfc 697 if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter))
dkato 0:ee40da884cfc 698 return false;
dkato 0:ee40da884cfc 699
dkato 0:ee40da884cfc 700 /* compose the value */
dkato 0:ee40da884cfc 701 uval = (msbs << parameter) | lsbs;
dkato 0:ee40da884cfc 702 if(uval & 1)
dkato 0:ee40da884cfc 703 *val = -((int)(uval >> 1)) - 1;
dkato 0:ee40da884cfc 704 else
dkato 0:ee40da884cfc 705 *val = (int)(uval >> 1);
dkato 0:ee40da884cfc 706
dkato 0:ee40da884cfc 707 return true;
dkato 0:ee40da884cfc 708 }
dkato 0:ee40da884cfc 709
dkato 0:ee40da884cfc 710 /* this is by far the most heavily used reader call. it ain't pretty but it's fast */
dkato 0:ee40da884cfc 711 FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter)
dkato 0:ee40da884cfc 712 {
dkato 0:ee40da884cfc 713 /* try and get br->consumed_words and br->consumed_bits into register;
dkato 0:ee40da884cfc 714 * must remember to flush them back to *br before calling other
dkato 0:ee40da884cfc 715 * bitreader functions that use them, and before returning */
dkato 0:ee40da884cfc 716 unsigned cwords, words, lsbs, msbs, x, y;
dkato 0:ee40da884cfc 717 unsigned ucbits; /* keep track of the number of unconsumed bits in word */
dkato 0:ee40da884cfc 718 uint32_t b;
dkato 0:ee40da884cfc 719 int *val, *end;
dkato 0:ee40da884cfc 720
dkato 0:ee40da884cfc 721 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 722 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 723 /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */
dkato 0:ee40da884cfc 724 FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32);
dkato 0:ee40da884cfc 725 FLAC__ASSERT(parameter < 32);
dkato 0:ee40da884cfc 726 /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */
dkato 0:ee40da884cfc 727
dkato 0:ee40da884cfc 728 val = vals;
dkato 0:ee40da884cfc 729 end = vals + nvals;
dkato 0:ee40da884cfc 730
dkato 0:ee40da884cfc 731 if(parameter == 0) {
dkato 0:ee40da884cfc 732 while(val < end) {
dkato 0:ee40da884cfc 733 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 734 if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
dkato 0:ee40da884cfc 735 return false;
dkato 0:ee40da884cfc 736
dkato 0:ee40da884cfc 737 *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1);
dkato 0:ee40da884cfc 738 }
dkato 0:ee40da884cfc 739
dkato 0:ee40da884cfc 740 return true;
dkato 0:ee40da884cfc 741 }
dkato 0:ee40da884cfc 742
dkato 0:ee40da884cfc 743 FLAC__ASSERT(parameter > 0);
dkato 0:ee40da884cfc 744
dkato 0:ee40da884cfc 745 cwords = br->consumed_words;
dkato 0:ee40da884cfc 746 words = br->words;
dkato 0:ee40da884cfc 747
dkato 0:ee40da884cfc 748 /* if we've not consumed up to a partial tail word... */
dkato 0:ee40da884cfc 749 if(cwords >= words) {
dkato 0:ee40da884cfc 750 x = 0;
dkato 0:ee40da884cfc 751 goto process_tail;
dkato 0:ee40da884cfc 752 }
dkato 0:ee40da884cfc 753
dkato 0:ee40da884cfc 754 ucbits = FLAC__BITS_PER_WORD - br->consumed_bits;
dkato 0:ee40da884cfc 755 b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */
dkato 0:ee40da884cfc 756
dkato 0:ee40da884cfc 757 while(val < end) {
dkato 0:ee40da884cfc 758 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 759 x = y = FLAC__clz2_uint32(b);
dkato 0:ee40da884cfc 760 if(x == FLAC__BITS_PER_WORD) {
dkato 0:ee40da884cfc 761 x = ucbits;
dkato 0:ee40da884cfc 762 do {
dkato 0:ee40da884cfc 763 /* didn't find stop bit yet, have to keep going... */
dkato 0:ee40da884cfc 764 crc16_update_word_(br, br->buffer[cwords++]);
dkato 0:ee40da884cfc 765 if (cwords >= words)
dkato 0:ee40da884cfc 766 goto incomplete_msbs;
dkato 0:ee40da884cfc 767 b = br->buffer[cwords];
dkato 0:ee40da884cfc 768 y = FLAC__clz2_uint32(b);
dkato 0:ee40da884cfc 769 x += y;
dkato 0:ee40da884cfc 770 } while(y == FLAC__BITS_PER_WORD);
dkato 0:ee40da884cfc 771 }
dkato 0:ee40da884cfc 772 b <<= y;
dkato 0:ee40da884cfc 773 b <<= 1; /* account for stop bit */
dkato 0:ee40da884cfc 774 ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD;
dkato 0:ee40da884cfc 775 msbs = x;
dkato 0:ee40da884cfc 776
dkato 0:ee40da884cfc 777 /* read the binary LSBs */
dkato 0:ee40da884cfc 778 x = b >> (FLAC__BITS_PER_WORD - parameter);
dkato 0:ee40da884cfc 779 if(parameter <= ucbits) {
dkato 0:ee40da884cfc 780 ucbits -= parameter;
dkato 0:ee40da884cfc 781 b <<= parameter;
dkato 0:ee40da884cfc 782 } else {
dkato 0:ee40da884cfc 783 /* there are still bits left to read, they will all be in the next word */
dkato 0:ee40da884cfc 784 crc16_update_word_(br, br->buffer[cwords++]);
dkato 0:ee40da884cfc 785 if (cwords >= words)
dkato 0:ee40da884cfc 786 goto incomplete_lsbs;
dkato 0:ee40da884cfc 787 b = br->buffer[cwords];
dkato 0:ee40da884cfc 788 ucbits += FLAC__BITS_PER_WORD - parameter;
dkato 0:ee40da884cfc 789 x |= b >> ucbits;
dkato 0:ee40da884cfc 790 b <<= FLAC__BITS_PER_WORD - ucbits;
dkato 0:ee40da884cfc 791 }
dkato 0:ee40da884cfc 792 lsbs = x;
dkato 0:ee40da884cfc 793
dkato 0:ee40da884cfc 794 /* compose the value */
dkato 0:ee40da884cfc 795 x = (msbs << parameter) | lsbs;
dkato 0:ee40da884cfc 796 *val++ = (int)(x >> 1) ^ -(int)(x & 1);
dkato 0:ee40da884cfc 797
dkato 0:ee40da884cfc 798 continue;
dkato 0:ee40da884cfc 799
dkato 0:ee40da884cfc 800 /* at this point we've eaten up all the whole words */
dkato 0:ee40da884cfc 801 process_tail:
dkato 0:ee40da884cfc 802 do {
dkato 0:ee40da884cfc 803 if(0) {
dkato 0:ee40da884cfc 804 incomplete_msbs:
dkato 0:ee40da884cfc 805 br->consumed_bits = 0;
dkato 0:ee40da884cfc 806 br->consumed_words = cwords;
dkato 0:ee40da884cfc 807 }
dkato 0:ee40da884cfc 808
dkato 0:ee40da884cfc 809 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 810 if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
dkato 0:ee40da884cfc 811 return false;
dkato 0:ee40da884cfc 812 msbs += x;
dkato 0:ee40da884cfc 813 x = ucbits = 0;
dkato 0:ee40da884cfc 814
dkato 0:ee40da884cfc 815 if(0) {
dkato 0:ee40da884cfc 816 incomplete_lsbs:
dkato 0:ee40da884cfc 817 br->consumed_bits = 0;
dkato 0:ee40da884cfc 818 br->consumed_words = cwords;
dkato 0:ee40da884cfc 819 }
dkato 0:ee40da884cfc 820
dkato 0:ee40da884cfc 821 /* read the binary LSBs */
dkato 0:ee40da884cfc 822 if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits))
dkato 0:ee40da884cfc 823 return false;
dkato 0:ee40da884cfc 824 lsbs = x | lsbs;
dkato 0:ee40da884cfc 825
dkato 0:ee40da884cfc 826 /* compose the value */
dkato 0:ee40da884cfc 827 x = (msbs << parameter) | lsbs;
dkato 0:ee40da884cfc 828 *val++ = (int)(x >> 1) ^ -(int)(x & 1);
dkato 0:ee40da884cfc 829 x = 0;
dkato 0:ee40da884cfc 830
dkato 0:ee40da884cfc 831 cwords = br->consumed_words;
dkato 0:ee40da884cfc 832 words = br->words;
dkato 0:ee40da884cfc 833 ucbits = FLAC__BITS_PER_WORD - br->consumed_bits;
dkato 0:ee40da884cfc 834 b = br->buffer[cwords] << br->consumed_bits;
dkato 0:ee40da884cfc 835 } while(cwords >= words && val < end);
dkato 0:ee40da884cfc 836 }
dkato 0:ee40da884cfc 837
dkato 0:ee40da884cfc 838 if(ucbits == 0 && cwords < words) {
dkato 0:ee40da884cfc 839 /* don't leave the head word with no unconsumed bits */
dkato 0:ee40da884cfc 840 crc16_update_word_(br, br->buffer[cwords++]);
dkato 0:ee40da884cfc 841 ucbits = FLAC__BITS_PER_WORD;
dkato 0:ee40da884cfc 842 }
dkato 0:ee40da884cfc 843
dkato 0:ee40da884cfc 844 br->consumed_bits = FLAC__BITS_PER_WORD - ucbits;
dkato 0:ee40da884cfc 845 br->consumed_words = cwords;
dkato 0:ee40da884cfc 846
dkato 0:ee40da884cfc 847 return true;
dkato 0:ee40da884cfc 848 }
dkato 0:ee40da884cfc 849
dkato 0:ee40da884cfc 850 #if 0 /* UNUSED */
dkato 0:ee40da884cfc 851 FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter)
dkato 0:ee40da884cfc 852 {
dkato 0:ee40da884cfc 853 FLAC__uint32 lsbs = 0, msbs = 0;
dkato 0:ee40da884cfc 854 unsigned bit, uval, k;
dkato 0:ee40da884cfc 855
dkato 0:ee40da884cfc 856 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 857 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 858
dkato 0:ee40da884cfc 859 k = FLAC__bitmath_ilog2(parameter);
dkato 0:ee40da884cfc 860
dkato 0:ee40da884cfc 861 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 862 if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
dkato 0:ee40da884cfc 863 return false;
dkato 0:ee40da884cfc 864
dkato 0:ee40da884cfc 865 /* read the binary LSBs */
dkato 0:ee40da884cfc 866 if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k))
dkato 0:ee40da884cfc 867 return false;
dkato 0:ee40da884cfc 868
dkato 0:ee40da884cfc 869 if(parameter == 1u<<k) {
dkato 0:ee40da884cfc 870 /* compose the value */
dkato 0:ee40da884cfc 871 uval = (msbs << k) | lsbs;
dkato 0:ee40da884cfc 872 }
dkato 0:ee40da884cfc 873 else {
dkato 0:ee40da884cfc 874 unsigned d = (1 << (k+1)) - parameter;
dkato 0:ee40da884cfc 875 if(lsbs >= d) {
dkato 0:ee40da884cfc 876 if(!FLAC__bitreader_read_bit(br, &bit))
dkato 0:ee40da884cfc 877 return false;
dkato 0:ee40da884cfc 878 lsbs <<= 1;
dkato 0:ee40da884cfc 879 lsbs |= bit;
dkato 0:ee40da884cfc 880 lsbs -= d;
dkato 0:ee40da884cfc 881 }
dkato 0:ee40da884cfc 882 /* compose the value */
dkato 0:ee40da884cfc 883 uval = msbs * parameter + lsbs;
dkato 0:ee40da884cfc 884 }
dkato 0:ee40da884cfc 885
dkato 0:ee40da884cfc 886 /* unfold unsigned to signed */
dkato 0:ee40da884cfc 887 if(uval & 1)
dkato 0:ee40da884cfc 888 *val = -((int)(uval >> 1)) - 1;
dkato 0:ee40da884cfc 889 else
dkato 0:ee40da884cfc 890 *val = (int)(uval >> 1);
dkato 0:ee40da884cfc 891
dkato 0:ee40da884cfc 892 return true;
dkato 0:ee40da884cfc 893 }
dkato 0:ee40da884cfc 894
dkato 0:ee40da884cfc 895 FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter)
dkato 0:ee40da884cfc 896 {
dkato 0:ee40da884cfc 897 FLAC__uint32 lsbs, msbs = 0;
dkato 0:ee40da884cfc 898 unsigned bit, k;
dkato 0:ee40da884cfc 899
dkato 0:ee40da884cfc 900 FLAC__ASSERT(0 != br);
dkato 0:ee40da884cfc 901 FLAC__ASSERT(0 != br->buffer);
dkato 0:ee40da884cfc 902
dkato 0:ee40da884cfc 903 k = FLAC__bitmath_ilog2(parameter);
dkato 0:ee40da884cfc 904
dkato 0:ee40da884cfc 905 /* read the unary MSBs and end bit */
dkato 0:ee40da884cfc 906 if(!FLAC__bitreader_read_unary_unsigned(br, &msbs))
dkato 0:ee40da884cfc 907 return false;
dkato 0:ee40da884cfc 908
dkato 0:ee40da884cfc 909 /* read the binary LSBs */
dkato 0:ee40da884cfc 910 if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, k))
dkato 0:ee40da884cfc 911 return false;
dkato 0:ee40da884cfc 912
dkato 0:ee40da884cfc 913 if(parameter == 1u<<k) {
dkato 0:ee40da884cfc 914 /* compose the value */
dkato 0:ee40da884cfc 915 *val = (msbs << k) | lsbs;
dkato 0:ee40da884cfc 916 }
dkato 0:ee40da884cfc 917 else {
dkato 0:ee40da884cfc 918 unsigned d = (1 << (k+1)) - parameter;
dkato 0:ee40da884cfc 919 if(lsbs >= d) {
dkato 0:ee40da884cfc 920 if(!FLAC__bitreader_read_bit(br, &bit))
dkato 0:ee40da884cfc 921 return false;
dkato 0:ee40da884cfc 922 lsbs <<= 1;
dkato 0:ee40da884cfc 923 lsbs |= bit;
dkato 0:ee40da884cfc 924 lsbs -= d;
dkato 0:ee40da884cfc 925 }
dkato 0:ee40da884cfc 926 /* compose the value */
dkato 0:ee40da884cfc 927 *val = msbs * parameter + lsbs;
dkato 0:ee40da884cfc 928 }
dkato 0:ee40da884cfc 929
dkato 0:ee40da884cfc 930 return true;
dkato 0:ee40da884cfc 931 }
dkato 0:ee40da884cfc 932 #endif /* UNUSED */
dkato 0:ee40da884cfc 933
dkato 0:ee40da884cfc 934 /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */
dkato 0:ee40da884cfc 935 FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen)
dkato 0:ee40da884cfc 936 {
dkato 0:ee40da884cfc 937 FLAC__uint32 v = 0;
dkato 0:ee40da884cfc 938 FLAC__uint32 x;
dkato 0:ee40da884cfc 939 unsigned i;
dkato 0:ee40da884cfc 940
dkato 0:ee40da884cfc 941 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 942 return false;
dkato 0:ee40da884cfc 943 if(raw)
dkato 0:ee40da884cfc 944 raw[(*rawlen)++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 945 if(!(x & 0x80)) { /* 0xxxxxxx */
dkato 0:ee40da884cfc 946 v = x;
dkato 0:ee40da884cfc 947 i = 0;
dkato 0:ee40da884cfc 948 }
dkato 0:ee40da884cfc 949 else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
dkato 0:ee40da884cfc 950 v = x & 0x1F;
dkato 0:ee40da884cfc 951 i = 1;
dkato 0:ee40da884cfc 952 }
dkato 0:ee40da884cfc 953 else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
dkato 0:ee40da884cfc 954 v = x & 0x0F;
dkato 0:ee40da884cfc 955 i = 2;
dkato 0:ee40da884cfc 956 }
dkato 0:ee40da884cfc 957 else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
dkato 0:ee40da884cfc 958 v = x & 0x07;
dkato 0:ee40da884cfc 959 i = 3;
dkato 0:ee40da884cfc 960 }
dkato 0:ee40da884cfc 961 else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
dkato 0:ee40da884cfc 962 v = x & 0x03;
dkato 0:ee40da884cfc 963 i = 4;
dkato 0:ee40da884cfc 964 }
dkato 0:ee40da884cfc 965 else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
dkato 0:ee40da884cfc 966 v = x & 0x01;
dkato 0:ee40da884cfc 967 i = 5;
dkato 0:ee40da884cfc 968 }
dkato 0:ee40da884cfc 969 else {
dkato 0:ee40da884cfc 970 *val = 0xffffffff;
dkato 0:ee40da884cfc 971 return true;
dkato 0:ee40da884cfc 972 }
dkato 0:ee40da884cfc 973 for( ; i; i--) {
dkato 0:ee40da884cfc 974 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 975 return false;
dkato 0:ee40da884cfc 976 if(raw)
dkato 0:ee40da884cfc 977 raw[(*rawlen)++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 978 if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */
dkato 0:ee40da884cfc 979 *val = 0xffffffff;
dkato 0:ee40da884cfc 980 return true;
dkato 0:ee40da884cfc 981 }
dkato 0:ee40da884cfc 982 v <<= 6;
dkato 0:ee40da884cfc 983 v |= (x & 0x3F);
dkato 0:ee40da884cfc 984 }
dkato 0:ee40da884cfc 985 *val = v;
dkato 0:ee40da884cfc 986 return true;
dkato 0:ee40da884cfc 987 }
dkato 0:ee40da884cfc 988
dkato 0:ee40da884cfc 989 /* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */
dkato 0:ee40da884cfc 990 FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen)
dkato 0:ee40da884cfc 991 {
dkato 0:ee40da884cfc 992 FLAC__uint64 v = 0;
dkato 0:ee40da884cfc 993 FLAC__uint32 x;
dkato 0:ee40da884cfc 994 unsigned i;
dkato 0:ee40da884cfc 995
dkato 0:ee40da884cfc 996 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 997 return false;
dkato 0:ee40da884cfc 998 if(raw)
dkato 0:ee40da884cfc 999 raw[(*rawlen)++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1000 if(!(x & 0x80)) { /* 0xxxxxxx */
dkato 0:ee40da884cfc 1001 v = x;
dkato 0:ee40da884cfc 1002 i = 0;
dkato 0:ee40da884cfc 1003 }
dkato 0:ee40da884cfc 1004 else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
dkato 0:ee40da884cfc 1005 v = x & 0x1F;
dkato 0:ee40da884cfc 1006 i = 1;
dkato 0:ee40da884cfc 1007 }
dkato 0:ee40da884cfc 1008 else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
dkato 0:ee40da884cfc 1009 v = x & 0x0F;
dkato 0:ee40da884cfc 1010 i = 2;
dkato 0:ee40da884cfc 1011 }
dkato 0:ee40da884cfc 1012 else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
dkato 0:ee40da884cfc 1013 v = x & 0x07;
dkato 0:ee40da884cfc 1014 i = 3;
dkato 0:ee40da884cfc 1015 }
dkato 0:ee40da884cfc 1016 else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
dkato 0:ee40da884cfc 1017 v = x & 0x03;
dkato 0:ee40da884cfc 1018 i = 4;
dkato 0:ee40da884cfc 1019 }
dkato 0:ee40da884cfc 1020 else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
dkato 0:ee40da884cfc 1021 v = x & 0x01;
dkato 0:ee40da884cfc 1022 i = 5;
dkato 0:ee40da884cfc 1023 }
dkato 0:ee40da884cfc 1024 else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */
dkato 0:ee40da884cfc 1025 v = 0;
dkato 0:ee40da884cfc 1026 i = 6;
dkato 0:ee40da884cfc 1027 }
dkato 0:ee40da884cfc 1028 else {
dkato 0:ee40da884cfc 1029 *val = FLAC__U64L(0xffffffffffffffff);
dkato 0:ee40da884cfc 1030 return true;
dkato 0:ee40da884cfc 1031 }
dkato 0:ee40da884cfc 1032 for( ; i; i--) {
dkato 0:ee40da884cfc 1033 if(!FLAC__bitreader_read_raw_uint32(br, &x, 8))
dkato 0:ee40da884cfc 1034 return false;
dkato 0:ee40da884cfc 1035 if(raw)
dkato 0:ee40da884cfc 1036 raw[(*rawlen)++] = (FLAC__byte)x;
dkato 0:ee40da884cfc 1037 if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */
dkato 0:ee40da884cfc 1038 *val = FLAC__U64L(0xffffffffffffffff);
dkato 0:ee40da884cfc 1039 return true;
dkato 0:ee40da884cfc 1040 }
dkato 0:ee40da884cfc 1041 v <<= 6;
dkato 0:ee40da884cfc 1042 v |= (x & 0x3F);
dkato 0:ee40da884cfc 1043 }
dkato 0:ee40da884cfc 1044 *val = v;
dkato 0:ee40da884cfc 1045 return true;
dkato 0:ee40da884cfc 1046 }
dkato 0:ee40da884cfc 1047
dkato 0:ee40da884cfc 1048 /* These functions are declared inline in this file but are also callable as
dkato 0:ee40da884cfc 1049 * externs from elsewhere.
dkato 0:ee40da884cfc 1050 * According to the C99 spec, section 6.7.4, simply providing a function
dkato 0:ee40da884cfc 1051 * prototype in a header file without 'inline' and making the function inline
dkato 0:ee40da884cfc 1052 * in this file should be sufficient.
dkato 0:ee40da884cfc 1053 * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To
dkato 0:ee40da884cfc 1054 * fix that we add extern declarations here.
dkato 0:ee40da884cfc 1055 */
dkato 0:ee40da884cfc 1056 extern FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br);
dkato 0:ee40da884cfc 1057 extern unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br);
dkato 0:ee40da884cfc 1058 extern unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br);
dkato 0:ee40da884cfc 1059 extern FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val);