/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * JPEG image viewer * (This is a real mess if it has to be coded in one single C file) * * Copyright (C) 2004 Jörg Hohensohn aka [IDC]Dragon * Grayscale framework (c) 2004 Jens Arnold * Heavily borrowed from the IJG implementation (c) Thomas G. Lane * Small & fast downscaling IDCT (c) 2002 by Guido Vollbeding JPEGclub.org * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" #if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio displays */ /* FIX: This would be a lot nicer if it depended on HAVE_LCD_BITMAP only, but we need to fix the grayscale lib for Gmini and iRiver. Either with true grayscale or 1bit. */ #include "gray.h" /* variable button definitions */ #if CONFIG_KEYPAD == RECORDER_PAD #define JPEG_ZOOM_IN BUTTON_PLAY #define JPEG_ZOOM_OUT BUTTON_ON #elif CONFIG_KEYPAD == ONDIO_PAD #define JPEG_ZOOM_PRE BUTTON_MENU #define JPEG_ZOOM_IN (BUTTON_MENU | BUTTON_REL) #define JPEG_ZOOM_OUT (BUTTON_MENU | BUTTON_REPEAT) #elif CONFIG_KEYPAD == IRIVER_H100_PAD #define JPEG_ZOOM_IN BUTTON_ON #define JPEG_ZOOM_OUT BUTTON_SELECT #endif /******************************* Globals ***********************************/ static struct plugin_api* rb; /* for portability of below JPEG code */ #define MEMSET(p,v,c) rb->memset(p,v,c) #define INLINE static inline #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */ /**************** begin JPEG code ********************/ /* LUT for IDCT, this could also be used for gamma correction */ const unsigned char range_limit[1024] = { 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127 }; /* IDCT implementation */ #define CONST_BITS 13 #define PASS1_BITS 2 /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus * causing a lot of useless floating-point operations at run time. * To get around this we use the following pre-calculated constants. * If you change CONST_BITS you may want to add appropriate values. * (With a reasonable C compiler, you can just rely on the FIX() macro...) */ #define FIX_0_298631336 2446 /* FIX(0.298631336) */ #define FIX_0_390180644 3196 /* FIX(0.390180644) */ #define FIX_0_541196100 4433 /* FIX(0.541196100) */ #define FIX_0_765366865 6270 /* FIX(0.765366865) */ #define FIX_0_899976223 7373 /* FIX(0.899976223) */ #define FIX_1_175875602 9633 /* FIX(1.175875602) */ #define FIX_1_501321110 12299 /* FIX(1.501321110) */ #define FIX_1_847759065 15137 /* FIX(1.847759065) */ #define FIX_1_961570560 16069 /* FIX(1.961570560) */ #define FIX_2_053119869 16819 /* FIX(2.053119869) */ #define FIX_2_562915447 20995 /* FIX(2.562915447) */ #define FIX_3_072711026 25172 /* FIX(3.072711026) */ /* Multiply an long variable by an long constant to yield an long result. * For 8-bit samples with the recommended scaling, all the variable * and constant values involved are no more than 16 bits wide, so a * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. * For 12-bit samples, a full 32-bit multiplication will be needed. */ #define MULTIPLY16(var,const) (((short) (var)) * ((short) (const))) /* Dequantize a coefficient by multiplying it by the multiplier-table * entry; produce an int result. In this module, both inputs and result * are 16 bits or less, so either int or short multiply will work. */ /* #define DEQUANTIZE(coef,quantval) (((int) (coef)) * (quantval)) */ #define DEQUANTIZE MULTIPLY16 /* Descale and correctly round an int value that's scaled by N bits. * We assume RIGHT_SHIFT rounds towards minus infinity, so adding * the fudge factor is correct for either sign of X. */ #define DESCALE(x,n) (((x) + (1l << ((n)-1))) >> (n)) #define RANGE_MASK (255 * 4 + 3) /* 2 bits wider than legal samples */ /* * Perform dequantization and inverse DCT on one block of coefficients, * producing a reduced-size 1x1 output block. */ void idct1x1(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line) { (void)skip_line; /* unused */ *p_byte = range_limit[(inptr[0] * quantptr[0] >> 3) & RANGE_MASK]; } /* * Perform dequantization and inverse DCT on one block of coefficients, * producing a reduced-size 2x2 output block. */ void idct2x2(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; unsigned char* outptr; /* Pass 1: process columns from input, store into work array. */ /* Column 0 */ tmp4 = DEQUANTIZE(inptr[8*0], quantptr[8*0]); tmp5 = DEQUANTIZE(inptr[8*1], quantptr[8*1]); tmp0 = tmp4 + tmp5; tmp2 = tmp4 - tmp5; /* Column 1 */ tmp4 = DEQUANTIZE(inptr[8*0+1], quantptr[8*0+1]); tmp5 = DEQUANTIZE(inptr[8*1+1], quantptr[8*1+1]); tmp1 = tmp4 + tmp5; tmp3 = tmp4 - tmp5; /* Pass 2: process 2 rows, store into output array. */ /* Row 0 */ outptr = p_byte; outptr[0] = range_limit[(int) DESCALE(tmp0 + tmp1, 3) & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp0 - tmp1, 3) & RANGE_MASK]; /* Row 1 */ outptr = p_byte + skip_line; outptr[0] = range_limit[(int) DESCALE(tmp2 + tmp3, 3) & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp2 - tmp3, 3) & RANGE_MASK]; } /* * Perform dequantization and inverse DCT on one block of coefficients, * producing a reduced-size 4x4 output block. */ void idct4x4(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line) { int tmp0, tmp2, tmp10, tmp12; int z1, z2, z3; int * wsptr; unsigned char* outptr; int ctr; int workspace[4*4]; /* buffers data between passes */ /* Pass 1: process columns from input, store into work array. */ wsptr = workspace; for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++) { /* Even part */ tmp0 = DEQUANTIZE(inptr[8*0], quantptr[8*0]); tmp2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]); tmp10 = (tmp0 + tmp2) << PASS1_BITS; tmp12 = (tmp0 - tmp2) << PASS1_BITS; /* Odd part */ /* Same rotation as in the even part of the 8x8 LL&M IDCT */ z2 = DEQUANTIZE(inptr[8*1], quantptr[8*1]); z3 = DEQUANTIZE(inptr[8*3], quantptr[8*3]); z1 = MULTIPLY16(z2 + z3, FIX_0_541196100); tmp0 = DESCALE(z1 + MULTIPLY16(z3, - FIX_1_847759065), CONST_BITS-PASS1_BITS); tmp2 = DESCALE(z1 + MULTIPLY16(z2, FIX_0_765366865), CONST_BITS-PASS1_BITS); /* Final output stage */ wsptr[4*0] = (int) (tmp10 + tmp2); wsptr[4*3] = (int) (tmp10 - tmp2); wsptr[4*1] = (int) (tmp12 + tmp0); wsptr[4*2] = (int) (tmp12 - tmp0); } /* Pass 2: process 4 rows from work array, store into output array. */ wsptr = workspace; for (ctr = 0; ctr < 4; ctr++) { outptr = p_byte + (ctr*skip_line); /* Even part */ tmp0 = (int) wsptr[0]; tmp2 = (int) wsptr[2]; tmp10 = (tmp0 + tmp2) << CONST_BITS; tmp12 = (tmp0 - tmp2) << CONST_BITS; /* Odd part */ /* Same rotation as in the even part of the 8x8 LL&M IDCT */ z2 = (int) wsptr[1]; z3 = (int) wsptr[3]; z1 = MULTIPLY16(z2 + z3, FIX_0_541196100); tmp0 = z1 + MULTIPLY16(z3, - FIX_1_847759065); tmp2 = z1 + MULTIPLY16(z2, FIX_0_765366865); /* Final output stage */ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; wsptr += 4; /* advance pointer to next row */ } } /* * Perform dequantization and inverse DCT on one block of coefficients. */ void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line) { long tmp0, tmp1, tmp2, tmp3; long tmp10, tmp11, tmp12, tmp13; long z1, z2, z3, z4, z5; int * wsptr; unsigned char* outptr; int ctr; static int workspace[64]; /* buffers data between passes */ /* Pass 1: process columns from input, store into work array. */ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ /* furthermore, we scale the results by 2**PASS1_BITS. */ wsptr = workspace; for (ctr = 8; ctr > 0; ctr--) { /* Due to quantization, we will usually find that many of the input * coefficients are zero, especially the AC terms. We can exploit this * by short-circuiting the IDCT calculation for any column in which all * the AC terms are zero. In that case each output is equal to the * DC coefficient (with scale factor as needed). * With typical images and quantization tables, half or more of the * column DCT calculations can be simplified this way. */ if ((inptr[8*1] | inptr[8*2] | inptr[8*3] | inptr[8*4] | inptr[8*5] | inptr[8*6] | inptr[8*7]) == 0) { /* AC terms all zero */ int dcval = DEQUANTIZE(inptr[8*0], quantptr[8*0]) << PASS1_BITS; wsptr[8*0] = wsptr[8*1] = wsptr[8*2] = wsptr[8*3] = wsptr[8*4] = wsptr[8*5] = wsptr[8*6] = wsptr[8*7] = dcval; inptr++; /* advance pointers to next column */ quantptr++; wsptr++; continue; } /* Even part: reverse the even part of the forward DCT. */ /* The rotator is sqrt(2)*c(-6). */ z2 = DEQUANTIZE(inptr[8*2], quantptr[8*2]); z3 = DEQUANTIZE(inptr[8*6], quantptr[8*6]); z1 = MULTIPLY16(z2 + z3, FIX_0_541196100); tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065); tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865); z2 = DEQUANTIZE(inptr[8*0], quantptr[8*0]); z3 = DEQUANTIZE(inptr[8*4], quantptr[8*4]); tmp0 = (z2 + z3) << CONST_BITS; tmp1 = (z2 - z3) << CONST_BITS; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; /* Odd part per figure 8; the matrix is unitary and hence its transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */ tmp0 = DEQUANTIZE(inptr[8*7], quantptr[8*7]); tmp1 = DEQUANTIZE(inptr[8*5], quantptr[8*5]); tmp2 = DEQUANTIZE(inptr[8*3], quantptr[8*3]); tmp3 = DEQUANTIZE(inptr[8*1], quantptr[8*1]); z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ wsptr[8*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); wsptr[8*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); wsptr[8*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); wsptr[8*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); wsptr[8*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); wsptr[8*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); wsptr[8*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); wsptr[8*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); inptr++; /* advance pointers to next column */ quantptr++; wsptr++; } /* Pass 2: process rows from work array, store into output array. */ /* Note that we must descale the results by a factor of 8 == 2**3, */ /* and also undo the PASS1_BITS scaling. */ wsptr = workspace; for (ctr = 0; ctr < 8; ctr++) { outptr = p_byte + (ctr*skip_line); /* Rows of zeroes can be exploited in the same way as we did with columns. * However, the column calculation has created many nonzero AC terms, so * the simplification applies less often (typically 5% to 10% of the time). * On machines with very fast multiplication, it's possible that the * test takes more time than it's worth. In that case this section * may be commented out. */ #ifndef NO_ZERO_ROW_TEST if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | wsptr[7]) == 0) { /* AC terms all zero */ unsigned char dcval = range_limit[(int) DESCALE((long) wsptr[0], PASS1_BITS+3) & RANGE_MASK]; outptr[0] = dcval; outptr[1] = dcval; outptr[2] = dcval; outptr[3] = dcval; outptr[4] = dcval; outptr[5] = dcval; outptr[6] = dcval; outptr[7] = dcval; wsptr += 8; /* advance pointer to next row */ continue; } #endif /* Even part: reverse the even part of the forward DCT. */ /* The rotator is sqrt(2)*c(-6). */ z2 = (long) wsptr[2]; z3 = (long) wsptr[6]; z1 = MULTIPLY16(z2 + z3, FIX_0_541196100); tmp2 = z1 + MULTIPLY16(z3, - FIX_1_847759065); tmp3 = z1 + MULTIPLY16(z2, FIX_0_765366865); tmp0 = ((long) wsptr[0] + (long) wsptr[4]) << CONST_BITS; tmp1 = ((long) wsptr[0] - (long) wsptr[4]) << CONST_BITS; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; /* Odd part per figure 8; the matrix is unitary and hence its * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. */ tmp0 = (long) wsptr[7]; tmp1 = (long) wsptr[5]; tmp2 = (long) wsptr[3]; tmp3 = (long) wsptr[1]; z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = MULTIPLY16(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ tmp0 = MULTIPLY16(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp1 = MULTIPLY16(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ tmp2 = MULTIPLY16(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ tmp3 = MULTIPLY16(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ z1 = MULTIPLY16(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ z2 = MULTIPLY16(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z3 = MULTIPLY16(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z4 = MULTIPLY16(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3) & RANGE_MASK]; wsptr += 8; /* advance pointer to next row */ } } /* JPEG decoder implementation */ #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ struct derived_tbl { /* Basic tables: (element [0] of each array is unused) */ long mincode[17]; /* smallest code of length k */ long maxcode[18]; /* largest code of length k (-1 if none) */ /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */ int valptr[17]; /* huffval[] index of 1st symbol of length k */ /* Back link to public Huffman table (needed only in slow_DECODE) */ int* pub; /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of the input data stream. If the next Huffman code is no more than HUFF_LOOKAHEAD bits long, we can obtain its length and the corresponding symbol directly from these tables. */ int look_nbits[1<p_entropy_end = p_src + size; while (p_src < p_bytes + size) { if (*p_src++ != 0xFF) /* no marker? */ { p_src--; /* it's image data, put it back */ p_jpeg->p_entropy_data = p_src; break; /* exit marker processing */ } switch (*p_src++) { case 0xFF: /* Fill byte */ ret |= FILL_FF; case 0x00: /* Zero stuffed byte - entropy data */ p_src--; /* put it back */ continue; case 0xC0: /* SOF Huff - Baseline DCT */ { ret |= SOF0; marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ n = *p_src++; /* sample precision (= 8 or 12) */ if (n != 8) { return(-1); /* Unsupported sample precision */ } p_jpeg->y_size = *p_src++ << 8; /* Highbyte */ p_jpeg->y_size |= *p_src++; /* Lowbyte */ p_jpeg->x_size = *p_src++ << 8; /* Highbyte */ p_jpeg->x_size |= *p_src++; /* Lowbyte */ n = (marker_size-2-6)/3; if (*p_src++ != n || (n != 1 && n != 3)) { return(-2); /* Unsupported SOF0 component specification */ } for (i=0; iframeheader[i].ID = *p_src++; /* Component info */ p_jpeg->frameheader[i].horizontal_sampling = *p_src >> 4; p_jpeg->frameheader[i].vertical_sampling = *p_src++ & 0x0F; p_jpeg->frameheader[i].quanttable_select = *p_src++; if (p_jpeg->frameheader[i].horizontal_sampling > 2 || p_jpeg->frameheader[i].vertical_sampling > 2) return -3; /* Unsupported SOF0 subsampling */ } p_jpeg->blocks = n; } break; case 0xC1: /* SOF Huff - Extended sequential DCT*/ case 0xC2: /* SOF Huff - Progressive DCT*/ case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/ case 0xC5: /* SOF Huff - Differential sequential DCT*/ case 0xC6: /* SOF Huff - Differential progressive DCT*/ case 0xC7: /* SOF Huff - Differential spatial*/ case 0xC8: /* SOF Arith - Reserved for JPEG extensions*/ case 0xC9: /* SOF Arith - Extended sequential DCT*/ case 0xCA: /* SOF Arith - Progressive DCT*/ case 0xCB: /* SOF Arith - Spatial (sequential) lossless*/ case 0xCD: /* SOF Arith - Differential sequential DCT*/ case 0xCE: /* SOF Arith - Differential progressive DCT*/ case 0xCF: /* SOF Arith - Differential spatial*/ { return (-4); /* other DCT model than baseline not implemented */ } case 0xC4: /* Define Huffman Table(s) */ { unsigned char* p_temp; ret |= DHT; marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ p_temp = p_src; while (p_src < p_temp+marker_size-2-17) /* another table */ { int sum = 0; i = *p_src & 0x0F; /* table index */ if (i > 1) { return (-5); /* Huffman table index out of range */ } else if (*p_src++ & 0xF0) /* AC table */ { for (j=0; j<16; j++) { sum += *p_src; p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++; } if(16 + sum > AC_LEN) return -10; /* longer than allowed */ for (; j < 16 + sum; j++) p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++; } else /* DC table */ { for (j=0; j<16; j++) { sum += *p_src; p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; } if(16 + sum > DC_LEN) return -11; /* longer than allowed */ for (; j < 16 + sum; j++) p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; } } /* while */ p_src = p_temp+marker_size - 2; // skip possible residue } break; case 0xCC: /* Define Arithmetic coding conditioning(s) */ return(-6); /* Arithmetic coding not supported */ case 0xD8: /* Start of Image */ case 0xD9: /* End of Image */ case 0x01: /* for temp private use arith code */ break; /* skip parameterless marker */ case 0xDA: /* Start of Scan */ { ret |= SOS; marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ n = (marker_size-2-1-3)/2; if (*p_src++ != n || (n != 1 && n != 3)) { return (-7); /* Unsupported SOS component specification */ } for (i=0; iscanheader[i].ID = *p_src++; p_jpeg->scanheader[i].DC_select = *p_src >> 4; p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F; } p_src += 3; /* skip spectral information */ } break; case 0xDB: /* Define quantization Table(s) */ { ret |= DQT; marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */ for (i=0; i= 4) { return (-8); /* Unsupported quantization table */ } /* Read Quantisation table: */ for (j=0; jquanttable[id][j] = *p_src++; } } break; case 0xDD: /* Define Restart Interval */ { marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */ p_jpeg->restart_interval |= *p_src++; /* Lowbyte */ p_src += marker_size-4; /* skip segment */ } break; case 0xDC: /* Define Number of Lines */ case 0xDE: /* Define Hierarchical progression */ case 0xDF: /* Expand Reference Component(s) */ case 0xE0: /* Application Field 0*/ case 0xE1: /* Application Field 1*/ case 0xE2: /* Application Field 2*/ case 0xE3: /* Application Field 3*/ case 0xE4: /* Application Field 4*/ case 0xE5: /* Application Field 5*/ case 0xE6: /* Application Field 6*/ case 0xE7: /* Application Field 7*/ case 0xE8: /* Application Field 8*/ case 0xE9: /* Application Field 9*/ case 0xEA: /* Application Field 10*/ case 0xEB: /* Application Field 11*/ case 0xEC: /* Application Field 12*/ case 0xED: /* Application Field 13*/ case 0xEE: /* Application Field 14*/ case 0xEF: /* Application Field 15*/ case 0xFE: /* Comment */ { marker_size = *p_src++ << 8; /* Highbyte */ marker_size |= *p_src++; /* Lowbyte */ p_src += marker_size-2; /* skip segment */ } break; case 0xF0: /* Reserved for JPEG extensions */ case 0xF1: /* Reserved for JPEG extensions */ case 0xF2: /* Reserved for JPEG extensions */ case 0xF3: /* Reserved for JPEG extensions */ case 0xF4: /* Reserved for JPEG extensions */ case 0xF5: /* Reserved for JPEG extensions */ case 0xF6: /* Reserved for JPEG extensions */ case 0xF7: /* Reserved for JPEG extensions */ case 0xF8: /* Reserved for JPEG extensions */ case 0xF9: /* Reserved for JPEG extensions */ case 0xFA: /* Reserved for JPEG extensions */ case 0xFB: /* Reserved for JPEG extensions */ case 0xFC: /* Reserved for JPEG extensions */ case 0xFD: /* Reserved for JPEG extensions */ case 0x02: /* Reserved */ default: return (-9); /* Unknown marker */ } /* switch */ } /* while */ return (ret); /* return flags with seen markers */ } void default_huff_tbl(struct jpeg* p_jpeg) { static const struct huffman_table luma_table = { { 0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B }, { 0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D, 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, 0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0, 0x24,0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28, 0x29,0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49, 0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69, 0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89, 0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, 0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5, 0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2, 0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8, 0xF9,0xFA } }; static const struct huffman_table chroma_table = { { 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B }, { 0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,0x02,0x77, 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0, 0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26, 0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48, 0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68, 0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5, 0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3, 0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA, 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8, 0xF9,0xFA } }; p_jpeg->hufftable[0] = luma_table; p_jpeg->hufftable[1] = chroma_table; return; } /* Compute the derived values for a Huffman table */ void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl) { int p, i, l, si; int lookbits, ctr; char huffsize[257]; unsigned int huffcode[257]; unsigned int code; dtbl->pub = htbl; /* fill in back link */ /* Figure C.1: make table of Huffman code length for each symbol */ /* Note that this is in code-length order. */ p = 0; for (l = 1; l <= 16; l++) { /* all possible code length */ for (i = 1; i <= (int) htbl[l-1]; i++) /* all codes per length */ huffsize[p++] = (char) l; } huffsize[p] = 0; /* Figure C.2: generate the codes themselves */ /* Note that this is in code-length order. */ code = 0; si = huffsize[0]; p = 0; while (huffsize[p]) { while (((int) huffsize[p]) == si) { huffcode[p++] = code; code++; } code <<= 1; si++; } /* Figure F.15: generate decoding tables for bit-sequential decoding */ p = 0; for (l = 1; l <= 16; l++) { if (htbl[l-1]) { dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */ dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */ p += htbl[l-1]; dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ } else { dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ } } dtbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */ /* Compute lookahead tables to speed up decoding. * First we set all the table entries to 0, indicating "too long"; * then we iterate through the Huffman codes that are short enough and * fill in all the entries that correspond to bit sequences starting * with that code. */ MEMSET(dtbl->look_nbits, 0, sizeof(dtbl->look_nbits)); p = 0; for (l = 1; l <= HUFF_LOOKAHEAD; l++) { for (i = 1; i <= (int) htbl[l-1]; i++, p++) { /* l = current code's length, p = its index in huffcode[] & huffval[]. */ /* Generate left-justified code followed by all possible bit sequences */ lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { dtbl->look_nbits[lookbits] = l; dtbl->look_sym[lookbits] = htbl[16+p]; lookbits++; } } } } /* zag[i] is the natural-order position of the i'th element of zigzag order. * If the incoming data is corrupted, decode_mcu could attempt to * reference values beyond the end of the array. To avoid a wild store, * we put some extra zeroes after the real entries. */ static const int zag[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, /* extra entries in case k>63 below */ 0, 0, 0, 0, 0, 0, 0, 0 }; void build_lut(struct jpeg* p_jpeg) { int i; fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_dc, &p_jpeg->dc_derived_tbls[0]); fix_huff_tbl(p_jpeg->hufftable[0].huffmancodes_ac, &p_jpeg->ac_derived_tbls[0]); fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_dc, &p_jpeg->dc_derived_tbls[1]); fix_huff_tbl(p_jpeg->hufftable[1].huffmancodes_ac, &p_jpeg->ac_derived_tbls[1]); /* build the dequantization tables for the IDCT (De-ZiZagged) */ for (i=0; i<64; i++) { p_jpeg->qt_idct[0][zag[i]] = p_jpeg->quanttable[0][i]; p_jpeg->qt_idct[1][zag[i]] = p_jpeg->quanttable[1][i]; } for (i=0; i<4; i++) p_jpeg->store_pos[i] = i; /* default ordering */ /* assignments for the decoding of blocks */ if (p_jpeg->frameheader[0].horizontal_sampling == 2 && p_jpeg->frameheader[0].vertical_sampling == 1) { /* 4:2:2 */ p_jpeg->blocks = 4; p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; p_jpeg->x_phys = p_jpeg->x_mbl * 16; p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; p_jpeg->y_phys = p_jpeg->y_mbl * 8; p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ p_jpeg->mcu_membership[1] = 0; p_jpeg->mcu_membership[2] = 2; p_jpeg->mcu_membership[3] = 3; p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ p_jpeg->tab_membership[1] = 0; p_jpeg->tab_membership[2] = 1; p_jpeg->tab_membership[3] = 1; } if (p_jpeg->frameheader[0].horizontal_sampling == 1 && p_jpeg->frameheader[0].vertical_sampling == 2) { /* 4:2:2 vertically subsampled */ p_jpeg->store_pos[1] = 2; /* block positions are mirrored */ p_jpeg->store_pos[2] = 1; p_jpeg->blocks = 4; p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8; p_jpeg->x_phys = p_jpeg->x_mbl * 8; p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; p_jpeg->y_phys = p_jpeg->y_mbl * 16; p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ p_jpeg->mcu_membership[1] = 0; p_jpeg->mcu_membership[2] = 2; p_jpeg->mcu_membership[3] = 3; p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ p_jpeg->tab_membership[1] = 0; p_jpeg->tab_membership[2] = 1; p_jpeg->tab_membership[3] = 1; } else if (p_jpeg->frameheader[0].horizontal_sampling == 2 && p_jpeg->frameheader[0].vertical_sampling == 2) { /* 4:2:0 */ p_jpeg->blocks = 6; p_jpeg->x_mbl = (p_jpeg->x_size+15) / 16; p_jpeg->x_phys = p_jpeg->x_mbl * 16; p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; p_jpeg->y_phys = p_jpeg->y_mbl * 16; p_jpeg->mcu_membership[0] = 0; p_jpeg->mcu_membership[1] = 0; p_jpeg->mcu_membership[2] = 0; p_jpeg->mcu_membership[3] = 0; p_jpeg->mcu_membership[4] = 2; p_jpeg->mcu_membership[5] = 3; p_jpeg->tab_membership[0] = 0; p_jpeg->tab_membership[1] = 0; p_jpeg->tab_membership[2] = 0; p_jpeg->tab_membership[3] = 0; p_jpeg->tab_membership[4] = 1; p_jpeg->tab_membership[5] = 1; } else if (p_jpeg->frameheader[0].horizontal_sampling == 1 && p_jpeg->frameheader[0].vertical_sampling == 1) { /* 4:4:4 */ /* don't overwrite p_jpeg->blocks */ p_jpeg->x_mbl = (p_jpeg->x_size+7) / 8; p_jpeg->x_phys = p_jpeg->x_mbl * 8; p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; p_jpeg->y_phys = p_jpeg->y_mbl * 8; p_jpeg->mcu_membership[0] = 0; p_jpeg->mcu_membership[1] = 2; p_jpeg->mcu_membership[2] = 3; p_jpeg->tab_membership[0] = 0; p_jpeg->tab_membership[1] = 1; p_jpeg->tab_membership[2] = 1; } } /* * These functions/macros provide the in-line portion of bit fetching. * Use check_bit_buffer to ensure there are N bits in get_buffer * before using get_bits, peek_bits, or drop_bits. * check_bit_buffer(state,n,action); * Ensure there are N bits in get_buffer; if suspend, take action. * val = get_bits(n); * Fetch next N bits. * val = peek_bits(n); * Fetch next N bits without removing them from the buffer. * drop_bits(n); * Discard next N bits. * The value N should be a simple variable, not an expression, because it * is evaluated multiple times. */ INLINE void check_bit_buffer(struct bitstream* pb, int nbits) { if (pb->bits_left < nbits) { /* nbits is <= 16, so I can always refill 2 bytes in this case */ unsigned char byte; byte = *pb->next_input_byte++; if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */ { /* simplification: just skip the (one-byte) marker code */ pb->next_input_byte++; } pb->get_buffer = (pb->get_buffer << 8) | byte; byte = *pb->next_input_byte++; if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */ { /* simplification: just skip the (one-byte) marker code */ pb->next_input_byte++; } pb->get_buffer = (pb->get_buffer << 8) | byte; pb->bits_left += 16; } } INLINE int get_bits(struct bitstream* pb, int nbits) { return ((int) (pb->get_buffer >> (pb->bits_left -= nbits))) & ((1<get_buffer >> (pb->bits_left - nbits))) & ((1<bits_left -= nbits; } /* re-synchronize to entropy data (skip restart marker) */ void search_restart(struct bitstream* pb) { pb->next_input_byte--; /* we may have overread it, taking 2 bytes */ /* search for a non-byte-padding marker, has to be RSTm or EOS */ while (pb->next_input_byte < pb->input_end && (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00)) { pb->next_input_byte++; } pb->bits_left = 0; } /* Figure F.12: extend sign bit. */ #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) static const int extend_test[16] = /* entry n is 2**(n-1) */ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; /* Decode a single value */ INLINE int huff_decode_dc(struct bitstream* bs, struct derived_tbl* tbl) { int nb, look, s, r; check_bit_buffer(bs, HUFF_LOOKAHEAD); look = peek_bits(bs, HUFF_LOOKAHEAD); if ((nb = tbl->look_nbits[look]) != 0) { drop_bits(bs, nb); s = tbl->look_sym[look]; check_bit_buffer(bs, s); r = get_bits(bs, s); s = HUFF_EXTEND(r, s); } else { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */ long code; nb=HUFF_LOOKAHEAD+1; check_bit_buffer(bs, nb); code = get_bits(bs, nb); while (code > tbl->maxcode[nb]) { code <<= 1; check_bit_buffer(bs, 1); code |= get_bits(bs, 1); nb++; } if (nb > 16) /* error in Huffman */ { s=0; /* fake a zero, this is most safe */ } else { s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ]; check_bit_buffer(bs, s); r = get_bits(bs, s); s = HUFF_EXTEND(r, s); } } /* end slow decode */ return s; } INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl) { int nb, look, s; check_bit_buffer(bs, HUFF_LOOKAHEAD); look = peek_bits(bs, HUFF_LOOKAHEAD); if ((nb = tbl->look_nbits[look]) != 0) { drop_bits(bs, nb); s = tbl->look_sym[look]; } else { /* slow_DECODE(s, HUFF_LOOKAHEAD+1)) < 0); */ long code; nb=HUFF_LOOKAHEAD+1; check_bit_buffer(bs, nb); code = get_bits(bs, nb); while (code > tbl->maxcode[nb]) { code <<= 1; check_bit_buffer(bs, 1); code |= get_bits(bs, 1); nb++; } if (nb > 16) /* error in Huffman */ { s=0; /* fake a zero, this is most safe */ } else { s = tbl->pub[16 + tbl->valptr[nb] + ((int) (code - tbl->mincode[nb])) ]; } } /* end slow decode */ return s; } /* a JPEG decoder specialized in decoding only the luminance (b&w) */ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale, void (*pf_progress)(int current, int total)) { struct bitstream bs; /* bitstream "object" */ static int block[64]; /* decoded DCT coefficients */ int width, height; int skip_line; /* bytes from one line to the next (skip_line) */ int skip_strip, skip_mcu; /* bytes to next DCT row / column */ int x, y; /* loop counter */ unsigned char* p_byte; /* bitmap pointer */ void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */ int k_need; /* AC coefficients needed up to here */ int zero_need; /* init the block with this many zeros */ int last_dc_val = 0; int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */ int restart = p_jpeg->restart_interval; /* MCUs until restart marker */ /* pick the IDCT we want, determine how to work with coefs */ if (downscale == 1) { pf_idct = idct8x8; k_need = 64; /* all */ zero_need = 63; /* all */ } else if (downscale == 2) { pf_idct = idct4x4; k_need = 25; /* this far in zig-zag to cover 4*4 */ zero_need = 27; /* clear this far in linear order */ } else if (downscale == 4) { pf_idct = idct2x2; k_need = 5; /* this far in zig-zag to cover 2*2 */ zero_need = 9; /* clear this far in linear order */ } else if (downscale == 8) { pf_idct = idct1x1; k_need = 0; /* no AC, not needed */ zero_need = 0; /* no AC, not needed */ } else return -1; /* not supported */ /* init bitstream, fake a restart to make it start */ bs.next_input_byte = p_jpeg->p_entropy_data; bs.bits_left = 0; bs.input_end = p_jpeg->p_entropy_end; width = p_jpeg->x_phys / downscale; height = p_jpeg->y_phys / downscale; skip_line = width; skip_strip = skip_line * (height / p_jpeg->y_mbl); skip_mcu = (width/p_jpeg->x_mbl); /* prepare offsets about where to store the different blocks */ store_offs[p_jpeg->store_pos[0]] = 0; store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */ store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */ store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */ for(y=0; yy_mbl && bs.next_input_byte <= bs.input_end; y++) { p_byte = p_pixel; p_pixel += skip_strip; for (x=0; xx_mbl; x++) { int blkn; /* Outer loop handles each block in the MCU */ for (blkn = 0; blkn < p_jpeg->blocks; blkn++) { /* Decode a single block's worth of coefficients */ int k = 1; /* coefficient index */ int s, r; /* huffman values */ int ci = p_jpeg->mcu_membership[blkn]; /* component index */ int ti = p_jpeg->tab_membership[blkn]; /* table index */ struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti]; struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti]; /* Section F.2.2.1: decode the DC coefficient difference */ s = huff_decode_dc(&bs, dctbl); if (ci == 0) /* only for Y component */ { last_dc_val += s; block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */ /* coefficient buffer must be cleared */ MEMSET(block+1, 0, zero_need*sizeof(block[0])); /* Section F.2.2.2: decode the AC coefficients */ for (; k < k_need; k++) { s = huff_decode_ac(&bs, actbl); r = s >> 4; s &= 15; if (s) { k += r; check_bit_buffer(&bs, s); r = get_bits(&bs, s); block[zag[k]] = HUFF_EXTEND(r, s); } else { if (r != 15) { k = 64; break; } k += r; } } /* for k */ } /* In this path we just discard the values */ for (; k < 64; k++) { s = huff_decode_ac(&bs, actbl); r = s >> 4; s &= 15; if (s) { k += r; check_bit_buffer(&bs, s); drop_bits(&bs, s); } else { if (r != 15) break; k += r; } } /* for k */ if (ci == 0) { /* only for Y component */ pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti], skip_line); } } /* for blkn */ p_byte += skip_mcu; if (p_jpeg->restart_interval && --restart == 0) { /* if a restart marker is due: */ restart = p_jpeg->restart_interval; /* count again */ search_restart(&bs); /* align the bitstream */ last_dc_val = 0; /* reset decoder */ } } /* for x */ if (pf_progress != NULL) pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */ } /* for y */ return 0; /* success */ } /**************** end JPEG code ********************/ /**************** begin Application ********************/ /************************* Types ***************************/ struct t_disp { unsigned char* bitmap; int width; int height; int stride; int x, y; }; /************************* Globals ***************************/ /* decompressed image in the possible sizes (1,2,4,8), wasting the other */ struct t_disp disp[9]; /* my memory pool (from the mp3 buffer) */ char print[32]; /* use a common snprintf() buffer */ unsigned char* buf; /* up to here currently used by image(s) */ int buf_size; unsigned char* buf_root; /* the root of the images */ int root_size; /************************* Implementation ***************************/ #define ZOOM_IN 100 // return codes for below function #define ZOOM_OUT 101 /* switch off overlay, for handling SYS_ events */ void cleanup(void *parameter) { (void)parameter; gray_show_display(false); } /* interactively scroll around the image */ int scroll_bmp(struct t_disp* pdisp) { int lastbutton = 0; /*empty the button queue first, to avoid unwanted scrolling */ rb->button_clear_queue(); while (true) { int button; int move; button = rb->button_get(true); switch(button) { case BUTTON_LEFT: case BUTTON_LEFT | BUTTON_REPEAT: move = MIN(10, pdisp->x); if (move > 0) { gray_scroll_right(move, false); /* scroll right */ pdisp->x -= move; gray_drawgraymap( pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), // x, y move, MIN(LCD_HEIGHT, pdisp->height), // w, h pdisp->stride); } break; case BUTTON_RIGHT: case BUTTON_RIGHT | BUTTON_REPEAT: move = MIN(10, pdisp->width - pdisp->x - LCD_WIDTH); if (move > 0) { gray_scroll_left(move, false); /* scroll left */ pdisp->x += move; gray_drawgraymap( pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x + LCD_WIDTH - move, LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ pdisp->stride); } break; case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: move = MIN(8, pdisp->y); if (move > 0) { if (move == 8) gray_scroll_down8(false); /* scroll down by 8 pixel */ else gray_scroll_down(move, false); /* scroll down 1..7 pixel */ pdisp->y -= move; gray_drawgraymap( pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ pdisp->stride); } break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: move = MIN(8, pdisp->height - pdisp->y - LCD_HEIGHT); if (move > 0) { if (move == 8) gray_scroll_up8(false); /* scroll up by 8 pixel */ else gray_scroll_up(move, false); /* scroll up 1..7 pixel */ pdisp->y += move; gray_drawgraymap( pdisp->bitmap + (pdisp->y + LCD_HEIGHT - move) * pdisp->stride + pdisp->x, MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ pdisp->stride); } break; case JPEG_ZOOM_IN: #ifdef JPEG_ZOOM_PRE if (lastbutton != JPEG_ZOOM_PRE) break; #endif return ZOOM_IN; break; case JPEG_ZOOM_OUT: #ifdef JPEG_ZOOM_PRE if (lastbutton != JPEG_ZOOM_PRE) break; #endif return ZOOM_OUT; break; case BUTTON_OFF: return PLUGIN_OK; default: if (rb->default_event_handler_ex(button, cleanup, NULL) == SYS_USB_CONNECTED) return PLUGIN_USB_CONNECTED; break; } /* switch */ if (button != BUTTON_NONE) lastbutton = button; } /* while (true) */ } /********************* main function *************************/ /* debug function */ int wait_for_button(void) { int button; do { button = rb->button_get(true); } while ((button & BUTTON_REL) && button != SYS_USB_CONNECTED); return button; } /* callback updating a progress meter while JPEG decoding */ void cb_progess(int current, int total) { rb->yield(); /* be nice to the other threads */ rb->scrollbar(0, LCD_HEIGHT-8, LCD_WIDTH, 8, total, 0, current, HORIZONTAL); rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); } /* helper to align a buffer to a given power of two */ void align(unsigned char** ppbuf, int* plen, int align) { unsigned int orig = (unsigned int)*ppbuf; unsigned int aligned = (orig + (align-1)) & ~(align-1); *plen -= aligned - orig; *ppbuf = (unsigned char*)aligned; } /* how far can we zoom in without running out of memory */ int min_downscale(int x, int y, int bufsize) { int downscale = 8; if ((x/8) * (y/8) > bufsize) return 0; /* error, too large, even 1:8 doesn't fit */ while ((x*2/downscale) * (y*2/downscale) < bufsize && downscale > 1) { downscale /= 2; } return downscale; } /* how far can we zoom out, to fit image into the LCD */ int max_downscale(int x, int y) { int downscale = 1; while ((x/downscale > LCD_WIDTH || y/downscale > LCD_HEIGHT) && downscale < 8) { downscale *= 2; } return downscale; } /* return decoded or cached image */ struct t_disp* get_image(struct jpeg* p_jpg, int ds) { int w, h; /* used to center output */ int size; /* decompressed image size */ long time; /* measured ticks */ int status; struct t_disp* p_disp = &disp[ds]; /* short cut */ if (p_disp->bitmap != NULL) { return p_disp; /* we still have it */ } /* assign image buffer */ /* physical size needed for decoding */ size = (p_jpg->x_phys/ds) * (p_jpg->y_phys / ds); if (buf_size <= size) { /* have to discard the current */ int i; for (i=1; i<=8; i++) disp[i].bitmap = NULL; /* invalidate all bitmaps */ buf = buf_root; /* start again from the beginning of the buffer */ buf_size = root_size; } /* size may be less when decoded (if height is not block aligned) */ size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds); p_disp->bitmap = buf; buf += size; buf_size -= size; rb->snprintf(print, sizeof(print), "decoding %d*%d", p_jpg->x_size/ds, p_jpg->y_size/ds); rb->lcd_puts(0, 3, print); rb->lcd_update(); /* update image properties */ p_disp->width = p_jpg->x_size/ds; p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */ p_disp->height = p_jpg->y_size/ds; /* the actual decoding */ time = *rb->current_tick; status = jpeg_decode(p_jpg, p_disp->bitmap, ds, cb_progess); if (status) { rb->splash(HZ*2, true, "decode error %d", status); return NULL; } time = *rb->current_tick - time; rb->snprintf(print, sizeof(print), " %d.%02d sec ", time/HZ, time%HZ); rb->lcd_getstringsize(print, &w, &h); /* centered in progress bar */ rb->lcd_putsxy((LCD_WIDTH - w)/2, LCD_HEIGHT - h, print); rb->lcd_update(); return p_disp; } /* set the view to the given center point, limit if necessary */ void set_view (struct t_disp* p_disp, int cx, int cy) { int x, y; /* plain center to available width/height */ x = cx - MIN(LCD_WIDTH, p_disp->width) / 2; y = cy - MIN(LCD_HEIGHT, p_disp->height) / 2; /* limit against upper image size */ x = MIN(p_disp->width - LCD_WIDTH, x); y = MIN(p_disp->height - LCD_HEIGHT, y); /* limit against negative side */ x = MAX(0, x); y = MAX(0, y); p_disp->x = x; /* set the values */ p_disp->y = y; } /* calculate the view center based on the bitmap position */ void get_view(struct t_disp* p_disp, int* p_cx, int* p_cy) { *p_cx = p_disp->x + MIN(LCD_WIDTH, p_disp->width) / 2; *p_cy = p_disp->y + MIN(LCD_HEIGHT, p_disp->height) / 2; } /* load, decode, display the image */ int main(char* filename) { int fd; int filesize; int grayscales; int graysize; // helper unsigned char* buf_jpeg; /* compressed JPEG image */ static struct jpeg jpg; /* too large for stack */ int status; int ds, ds_min, ds_max; /* scaling and limits */ struct t_disp* p_disp; /* currenly displayed image */ int cx, cy; /* view center */ fd = rb->open(filename, O_RDONLY); if (fd < 0) { rb->splash(HZ*2, true, "fopen err"); return PLUGIN_ERROR; } filesize = rb->filesize(fd); rb->memset(&disp, 0, sizeof(disp)); buf = rb->plugin_get_audio_buffer(&buf_size); /* start munching memory */ /* initialize the grayscale buffer: * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve * 32 bitplanes for 33 shades of gray. (uses 28856 bytes)*/ grayscales = gray_init_buffer(buf, buf_size, 112, 8, 32, &graysize) + 1; buf += graysize; buf_size -= graysize; if (grayscales < 33 || buf_size <= 0) { rb->splash(HZ*2, true, "gray buf error"); return PLUGIN_ERROR; } /* allocate JPEG buffer */ align(&buf, &buf_size, 2); /* 16 bit align */ buf_jpeg = (unsigned char*)(((int)buf + 1) & ~1); buf += filesize; buf_size -= filesize; buf_root = buf; /* we can start the decompressed images behind it */ root_size = buf_size; if (buf_size <= 0) { rb->splash(HZ*2, true, "out of memory"); rb->close(fd); return PLUGIN_ERROR; } rb->snprintf(print, sizeof(print), "loading %d bytes", filesize); rb->lcd_puts(0, 0, print); rb->lcd_update(); rb->read(fd, buf_jpeg, filesize); rb->close(fd); rb->snprintf(print, sizeof(print), "decoding markers"); rb->lcd_puts(0, 1, print); rb->lcd_update(); rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ /* process markers, unstuffing */ status = process_markers(buf_jpeg, filesize, &jpg); if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0)) { /* bad format or minimum components not contained */ rb->splash(HZ*2, true, "unsupported %d", status); return PLUGIN_ERROR; } if (!(status & DHT)) /* if no Huffman table present: */ default_huff_tbl(&jpg); /* use default */ build_lut(&jpg); /* derive Huffman and other lookup-tables */ rb->snprintf(print, sizeof(print), "image %d*%d", jpg.x_size, jpg.y_size); rb->lcd_puts(0, 2, print); rb->lcd_update(); /* check display constraint */ ds_max = max_downscale(jpg.x_size, jpg.y_size); /* check memory constraint */ ds_min = min_downscale(jpg.x_phys, jpg.y_phys, buf_size); if (ds_min == 0) { rb->splash(HZ*2, true, "too large"); return PLUGIN_ERROR; } ds = ds_max; /* initials setting */ cx = jpg.x_size/ds/2; /* center the view */ cy = jpg.y_size/ds/2; do /* loop the image prepare and decoding when zoomed */ { p_disp = get_image(&jpg, ds); /* decode or fetch from cache */ if (p_disp == NULL) return PLUGIN_ERROR; set_view(p_disp, cx, cy); rb->snprintf(print, sizeof(print), "showing %d*%d", p_disp->width, p_disp->height); rb->lcd_puts(0, 3, print); rb->lcd_update(); gray_clear_display(); gray_drawgraymap( p_disp->bitmap + p_disp->y * p_disp->stride + p_disp->x, MAX(0, (LCD_WIDTH - p_disp->width) / 2), MAX(0, (LCD_HEIGHT - p_disp->height) / 2), MIN(LCD_WIDTH, p_disp->width), MIN(LCD_HEIGHT, p_disp->height), p_disp->stride); gray_show_display(true); /* switch on grayscale overlay */ /* drawing is now finished, play around with scrolling * until you press OFF or connect USB */ while (1) { status = scroll_bmp(p_disp); if (status == ZOOM_IN) { if (ds > ds_min) { ds /= 2; /* reduce downscaling to zoom in */ get_view(p_disp, &cx, &cy); cx *= 2; /* prepare the position in the new image */ cy *= 2; } else continue; } if (status == ZOOM_OUT) { if (ds < ds_max) { ds *= 2; /* increase downscaling to zoom out */ get_view(p_disp, &cx, &cy); cx /= 2; /* prepare the position in the new image */ cy /= 2; } else continue; } break; } gray_show_display(false); /* switch off overlay */ } while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED); gray_release_buffer(); /* deinitialize */ return status; } /******************** Plugin entry point *********************/ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { /* this macro should be called as the first thing you do in the plugin. it test that the api version and model the plugin was compiled for matches the machine it is running on */ TEST_PLUGIN_API(api); rb = api; /* copy to global api pointer */ /* This plugin uses the grayscale framework, so initialize */ gray_init(api); return main((char*)parameter); } #endif /* #ifdef HAVE_LCD_BITMAP */ #endif /* #ifndef SIMULATOR */ 'n1858' href='#n1858'>1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2006 Antonius Hellmann
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

//    Shine is an MP3 encoder
//    Copyright (C) 1999-2000  Gabriel Bouvigne
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License as published by the Free Software Foundation; either
//    version 2 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Library General Public License for more details.

#ifndef SIMULATOR

#include <inttypes.h>
#include "codeclib.h"

CODEC_ENC_HEADER

#define ENC_PADDING_FRAMES1        2
#define ENC_PADDING_FRAMES2        4
#define ENC_DELAY_SAMP           576
#define ENC_DELAY_SIZE          (ENC_DELAY_SAMP*4)
#define SAMP_PER_FRAME1         1152
#define SAMP_PER_FRAME2          576
#define PCM_CHUNK_SIZE1         (SAMP_PER_FRAME1*4)
#define PCM_CHUNK_SIZE2         (SAMP_PER_FRAME2*4)
#define SAMPL2                576
#define SBLIMIT                32
#define HTN                    16
#define memcpy      ci->memcpy
#define memset      ci->memset
#define putlong(c, s)  if(s+sz <= 32) { cc = (cc << s) | c;      sz+= s; } \
                       else           { putbits(cc, sz); cc = c; sz = s; }

typedef struct {
    int   type; /* 0=(MPEG2 - 22.05,24,16kHz) 1=(MPEG1 - 44.1,48,32kHz) */
    int   mode; /* 0=stereo, 1=jstereo, 2=dual, 3=mono  */
    int   bitrate;
    int   padding;
    int   num_bands;
    long  bitr_id;
    int   smpl_id;
} mpeg_t;

/* Side information */
typedef struct {
    uint32_t part2_3_length;
    int    count1;          /* number of 0-1-quadruples  */
    uint32_t global_gain;
    uint32_t table_select[4];
    uint32_t region_0_1;
    uint32_t address1;
    uint32_t address2;
    uint32_t address3;
    long     quantStep;
    long     additStep;
    uint32_t max_val;
} side_info_t;

typedef struct {
    side_info_t       cod_info[2][2];
    mpeg_t            mpg;
    long              frac_per_frame;
    long              byte_per_frame;
    long              slot_lag;
    int               sideinfo_len;
    int               mean_bits;
    int               ResvSize;
    int               channels;
    int               rec_mono_mode;
    int               granules;
    long              samplerate;
} config_t;

typedef struct {
    int       bitpos;   /* current bitpos for writing */
    uint32_t  bbuf[263];
} BF_Data;

struct huffcodetab {
  int            len;    /* max. index                  */
  const uint8_t  *table; /* pointer to array[len][len]  */
  const uint8_t  *hlen;  /* pointer to array[len][len]  */
};

struct huffcodebig {
  int          len;     /* max. index                   */
  int          linbits; /* number of linbits            */
  int          linmax;  /* max number stored in linbits */
};

#define shft4(x)    ((x +     8) >>  4)
#define shft9(x)    ((x +   256) >>  9)
#define shft13(x)   ((x +  4096) >> 13)
#define shft15(x)   ((x + 16384) >> 15)
#define shft16(x)   ((x + 32768) >> 16)
#define shft_n(x,n) ((x) >> n)
#define SQRT        724 /* sqrt(2) * 512 */

static short     mfbuf       [2*(1152+512)]      IBSS_ATTR; /*  3328 Bytes */
static int       sb_data     [2][2][18][SBLIMIT] IBSS_ATTR; /* 13824 Bytes */
static int       mdct_freq   [SAMPL2]            IBSS_ATTR; /*  2304 Bytes */
static char      mdct_sign   [SAMPL2]            IBSS_ATTR; /*   576 Bytes */
static short     enc_data    [SAMPL2]            IBSS_ATTR; /*  1152 Bytes */
static uint32_t  scalefac    [23]                IBSS_ATTR; /*    92 Bytes */
static BF_Data   CodedData                       IBSS_ATTR; /*  1056 Bytes */
static int       ca          [8]                 IBSS_ATTR; /*    32 Bytes */
static int       cs          [8]                 IBSS_ATTR; /*    32 Bytes */
static int       cx          [9]                 IBSS_ATTR; /*    36 Bytes */
static int       win         [18][4]             IBSS_ATTR; /*   288 Bytes */
static short     enwindow    [15*27+24]          IBSS_ATTR; /*   862 Bytes */
static short     int2idx     [4096]              IBSS_ATTR; /*  8192 Bytes */
static uint8_t   ht_count    [2][2][16]          IBSS_ATTR; /*    64 Bytes */
static uint32_t  tab01       [ 16]               IBSS_ATTR; /*    64 Bytes */
static uint32_t  tab23       [  9]               IBSS_ATTR; /*    36 Bytes */
static uint32_t  tab56       [ 16]               IBSS_ATTR; /*    64 Bytes */
static uint32_t  tab1315     [256]               IBSS_ATTR; /*  1024 Bytes */
static uint32_t  tab1624     [256]               IBSS_ATTR; /*  1024 Bytes */
static uint32_t  tab789      [ 36]               IBSS_ATTR; /*   144 Bytes */
static uint32_t  tabABC      [ 64]               IBSS_ATTR; /*   256 Bytes */
static uint8_t   t1HB        [  4]               IBSS_ATTR;
static uint8_t   t2HB        [  9]               IBSS_ATTR;
static uint8_t   t3HB        [  9]               IBSS_ATTR;
static uint8_t   t5HB        [ 16]               IBSS_ATTR;
static uint8_t   t6HB        [ 16]               IBSS_ATTR;
static uint8_t   t7HB        [ 36]               IBSS_ATTR;
static uint8_t   t8HB        [ 36]               IBSS_ATTR;
static uint8_t   t9HB        [ 36]               IBSS_ATTR;
static uint8_t   t10HB       [ 64]               IBSS_ATTR;
static uint8_t   t11HB       [ 64]               IBSS_ATTR;
static uint8_t   t12HB       [ 64]               IBSS_ATTR;
static uint8_t   t13HB       [256]               IBSS_ATTR;
static uint8_t   t15HB       [256]               IBSS_ATTR;
static uint16_t  t16HB       [256]               IBSS_ATTR;
static uint16_t  t24HB       [256]               IBSS_ATTR;
static uint8_t   t1l         [  8]               IBSS_ATTR;
static uint8_t   t2l         [  9]               IBSS_ATTR;
static uint8_t   t3l         [  9]               IBSS_ATTR;
static uint8_t   t5l         [ 16]               IBSS_ATTR;
static uint8_t   t6l         [ 16]               IBSS_ATTR;
static uint8_t   t7l         [ 36]               IBSS_ATTR;
static uint8_t   t8l         [ 36]               IBSS_ATTR;
static uint8_t   t9l         [ 36]               IBSS_ATTR;
static uint8_t   t10l        [ 64]               IBSS_ATTR;
static uint8_t   t11l        [ 64]               IBSS_ATTR;
static uint8_t   t12l        [ 64]               IBSS_ATTR;
static uint8_t   t13l        [256]               IBSS_ATTR;
static uint8_t   t15l        [256]               IBSS_ATTR;
static uint8_t   t16l        [256]               IBSS_ATTR;
static uint8_t   t24l        [256]               IBSS_ATTR;
static struct huffcodetab ht [HTN]               IBSS_ATTR;

static unsigned pcm_chunk_size                   IBSS_ATTR;
static unsigned samp_per_frame                   IBSS_ATTR;

static config_t          cfg                     IBSS_ATTR;
static char             *res_buffer;
static int32_t           err                     IBSS_ATTR;
static uint8_t           band_scale_f[22];

static const uint8_t ht_count_const[2][2][16] =
{ { { 1,  5,  4,  5,  6,  5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1 },     /* table0 */
    { 1,  5,  5,  7,  5,  8, 7, 9, 5, 7, 7, 9, 7, 9, 9,10 } },   /* hleng0 */
  { {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },     /* table1 */
    { 4,  5,  5,  6,  5,  6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 } } }; /* hleng1 */

static const uint8_t  t1HB_const[4]  = {1,1,1,0}; 
static const uint8_t  t2HB_const[9]  = {1,2,1,3,1,1,3,2,0};
static const uint8_t  t3HB_const[9]  = {3,2,1,1,1,1,3,2,0};
static const uint8_t  t5HB_const[16] = {1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0};
static const uint8_t  t6HB_const[16] = {7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0};

static const uint8_t  t7HB_const[36] =
{  1, 2,10,19,16,10, 3, 3, 7,10, 5, 3,11, 4,13,17, 8, 4,
  12,11,18,15,11, 2, 7, 6, 9,14, 3, 1, 6, 4, 5, 3, 2, 0 };

static const uint8_t  t8HB_const[36] =
{  3, 4, 6,18,12, 5, 5, 1, 2,16, 9, 3, 7, 3, 5,14, 7, 3,
  19,17,15,13,10, 4,13, 5, 8,11, 5, 1,12, 4, 4, 1, 1, 0 };

static const uint8_t  t9HB_const[36] =
{  7, 5, 9,14,15, 7, 6, 4, 5, 5, 6, 7, 7, 6, 8, 8, 8, 5,
  15, 6, 9,10, 5, 1,11, 7, 9, 6, 4, 1,14, 4, 6, 2, 6, 0 };

static const uint8_t t10HB_const[64] =
{1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,
 40,19,6,14,13,22,34,46,23,18,7,20,19,33,47,27,22,9,3,31,22,
 41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8,7,8,4,4,2,0 };

static const uint8_t t11HB_const[64] =
{3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,
 31,20,5,25,11,19,59,27,18,12,5,35,33,31,58,30,16,7,5,28,26,
 32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0 };

static const uint8_t t12HB_const[64] =
{9,6,16,33,41,39,38,26,7,5,6,9,23,16,26,11,17,7,11,14,21,
30,10,7,17,10,15,12,18,28,14,5,32,13,22,19,18,16,9,5,40,17,
31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0 };

static const uint8_t t13HB_const[256] =
{1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19,3,4,12,19,31,26,44,33,31,24,32,
 24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30,40,27,33,42,16,22,20,37,61,56,
 79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,
 23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,
 79,69,83,71,50,59,38,36,15,72,34,56,95,92,85,91,90,86,73,77,65,51,44,43,42,43,
 20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,
 54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,
 60,51,36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,
 45,21,34,64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,
 10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1 };

static const uint8_t t15HB_const[256] =
{7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,
 42,70,52,83,65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,
 25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,
 49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40,38,125,32,60,56,50,
 92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91,73,56,42,64,44,
 21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,
 67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,
 42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68,30,55,50,46,74,65,49,39,
 24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,
 43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0};

static const uint16_t t16HB_const[256] =
{1,5,14,44,74,63,110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,
 83,75,68,119,201,107,207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,
 206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,
 115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,
 253,232,400,388,378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,
 366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,
 159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73,141,131,256,245,
 426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219,393,743,737,
 720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,
 6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,
 208,370,379,734,723,714,1735,883,877,876,3459,865,2,377,369,102,187,726,722,
 358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,
 1,3};

static const uint16_t t24HB_const[256] =
{15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,
 130,122,216,209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,
 182,340,315,295,541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,
 271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,
 129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,
 215,206,195,185,347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,
 353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,
 286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289,275,521,379,
 371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366,10,652,346,
 171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,
 292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,
 374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378,372,367,363,360,
 358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3};

static const uint32_t tab1315_const[256] =
{ 0x010003,0x050005,0x070006,0x080008,0x090008,0x0a0009,0x0a000a,0x0b000a,
  0x0a000a,0x0b000b,0x0c000b,0x0c000c,0x0d000c,0x0d000c,0x0e000d,0x0e000e,
  0x040005,0x060005,0x080007,0x090008,0x0a0009,0x0a0009,0x0b000a,0x0b000a,
  0x0b000a,0x0b000b,0x0c000b,0x0c000c,0x0d000c,0x0e000c,0x0e000d,0x0e000d,
  0x070006,0x080007,0x090007,0x0a0008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,
  0x0b000a,0x0c000b,0x0c000b,0x0d000c,0x0d000c,0x0e000d,0x0f000d,0x0f000d,
  0x080007,0x090008,0x0a0008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,0x0c000b,
  0x0c000b,0x0d000b,0x0d000c,0x0d000c,0x0d000c,0x0e000d,0x0f000d,0x0f000d,
  0x090008,0x090008,0x0b0009,0x0b0009,0x0c000a,0x0c000a,0x0d000b,0x0d000b,
  0x0c000b,0x0d000b,0x0d000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000d,
  0x0a0009,0x0a0009,0x0b0009,0x0c000a,0x0c000a,0x0c000a,0x0d000b,0x0d000b,
  0x0d000b,0x0d000b,0x0e000c,0x0d000c,0x0f000d,0x0f000d,0x10000d,0x10000e,
  0x0a000a,0x0b0009,0x0c000a,0x0c000a,0x0d000a,0x0d000b,0x0d000b,0x0d000b,
  0x0d000b,0x0e000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000e,0x10000e,
  0x0b000a,0x0b000a,0x0c000a,0x0d000b,0x0d000b,0x0d000b,0x0e000b,0x0e000c,
  0x0e000c,0x0e000c,0x0f000c,0x0f000c,0x0f000d,0x10000d,0x12000d,0x12000e,
  0x0a000a,0x0a000a,0x0b000a,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0e000c,
  0x0e000c,0x0e000c,0x0e000c,0x0f000d,0x0f000d,0x10000e,0x11000e,0x11000e,
  0x0b000a,0x0b000a,0x0c000b,0x0c000b,0x0d000b,0x0d000b,0x0d000c,0x0f000c,
  0x0e000c,0x0f000d,0x0f000d,0x10000d,0x10000d,0x10000e,0x12000e,0x11000e,
  0x0b000b,0x0c000b,0x0c000b,0x0d000b,0x0d000c,0x0e000c,0x0e000c,0x0f000c,
  0x0e000c,0x0f000d,0x10000d,0x0f000d,0x10000d,0x11000e,0x12000f,0x13000e,
  0x0c000b,0x0c000b,0x0c000b,0x0d000b,0x0e000c,0x0e000c,0x0e000c,0x0e000c,
  0x0f000d,0x0f000d,0x0f000d,0x10000d,0x11000e,0x11000e,0x11000e,0x12000f,
  0x0c000c,0x0d000c,0x0d000b,0x0e000c,0x0e000c,0x0f000c,0x0e000d,0x0f000d,
  0x10000d,0x10000d,0x11000d,0x11000d,0x11000e,0x12000e,0x12000f,0x12000f,
  0x0d000c,0x0d000c,0x0e000c,0x0f000c,0x0f000c,0x0f000d,0x10000d,0x10000d,
  0x10000d,0x10000e,0x10000e,0x11000e,0x12000e,0x11000e,0x12000f,0x12000f,
  0x0e000d,0x0e000d,0x0e000d,0x0f000d,0x0f000d,0x0f000d,0x11000d,0x10000d,
  0x10000e,0x13000e,0x11000e,0x11000e,0x11000f,0x13000f,0x12000e,0x12000f,
  0x0d000d,0x0e000d,0x0f000d,0x10000d,0x10000d,0x10000d,0x11000d,0x10000e,
  0x11000e,0x11000e,0x12000e,0x12000e,0x15000f,0x14000f,0x15000f,0x12000f };

static const uint32_t tab01_const[16] =
{ 0x10004,0x50005,0x50005,0x70006,0x50005,0x80006,0x70006,0x90007,
  0x50005,0x70006,0x70006,0x90007,0x70006,0x90007,0x90007,0xa0008 };

static const uint32_t tab23_const[ 9] =
{ 0x10002,0x40003,0x70007,0x40004,0x50004,0x70007,0x60006,0x70007,0x80008 };

static const uint32_t tab56_const[16] =
{ 0x10003,0x40004,0x70006,0x80008,0x40004,0x50004,0x80006,0x90007,
  0x70005,0x80006,0x90007,0xa0008,0x80007,0x80007,0x90008,0xa0009 };

static const uint32_t tab789_const[36] =
{0x00100803,0x00401004,0x00701c06,0x00902407,0x00902409,0x00a0280a,0x00401004,
 0x00601005,0x00801806,0x00902807,0x00902808,0x00a0280a,0x00701c05,0x00701806,
 0x00902007,0x00a02808,0x00a02809,0x00b02c0a,0x00802407,0x00902807,0x00a02808,
 0x00b02c09,0x00b02c09,0x00b0300a,0x00802408,0x00902408,0x00a02809,0x00b02c09,
 0x00b0300a,0x00c0300b,0x00902809,0x00a02809,0x00b02c0a,0x00c02c0a,0x00c0340b,
 0x00c0340b};

static const uint32_t tabABC_const[64] =
{0x00100804,0x00401004,0x00701806,0x00902008,0x00a02409,0x00a0280a,0x00a0240a,
 0x00b0280a,0x00401004,0x00601405,0x00801806,0x00902007,0x00a02809,0x00b02809,
 0x00a0240a,0x00a0280a,0x00701806,0x00801c06,0x00902007,0x00a02408,0x00b02809,
 0x00c02c0a,0x00b02809,0x00b0280a,0x00802007,0x00902007,0x00a02408,0x00b02c08,
 0x00c02809,0x00c0300a,0x00b0280a,0x00c02c0a,0x00902408,0x00a02808,0x00b02809,
 0x00c02c09,0x00c02c0a,0x00c0300a,0x00c02c0a,0x00c0300b,0x00a02409,0x00b02809,
 0x00c02c0a,0x00c0300a,0x00d0300a,0x00d0340b,0x00c0300a,0x00d0340b,0x00902409,
 0x00a02409,0x00b02409,0x00c0280a,0x00c02c0a,0x00c0300b,0x00d0300b,0x00d0300c,
 0x00a0240a,0x00a0240a,0x00b0280a,0x00c02c0b,0x00c0300b,0x00d0300b,0x00d0300b,
 0x00d0300c};

static const uint32_t tab1624_const[256] =
{0x00010004,0x00050005,0x00070007,0x00090008,0x000a0009,0x000a000a,0x000b000a,
 0x000b000b,0x000c000b,0x000c000c,0x000c000c,0x000d000c,0x000d000c,0x000d000c,
 0x000e000d,0x000a000a,0x00040005,0x00060006,0x00080007,0x00090008,0x000a0009,
 0x000b000a,0x000b000a,0x000b000b,0x000c000b,0x000c000b,0x000c000c,0x000d000c,
 0x000e000c,0x000d000c,0x000e000c,0x000a000a,0x00070007,0x00080007,0x00090008,
 0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000b,0x000d000b,0x000c000b,
 0x000d000b,0x000d000c,0x000d000c,0x000e000c,0x000e000d,0x000b0009,0x00090008,
 0x00090008,0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000a,0x000c000b,
 0x000d000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000f000c,0x000f000c,
 0x000c0009,0x000a0009,0x000a0009,0x000b0009,0x000b000a,0x000c000a,0x000c000a,
 0x000d000a,0x000d000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000f000c,
 0x000f000c,0x000f000d,0x000b0009,0x000a000a,0x000a0009,0x000b000a,0x000b000a,
 0x000c000a,0x000d000a,0x000d000b,0x000e000b,0x000d000b,0x000e000b,0x000e000c,
 0x000f000c,0x000f000c,0x000f000c,0x0010000c,0x000c0009,0x000b000a,0x000b000a,
 0x000b000a,0x000c000a,0x000d000a,0x000d000b,0x000d000b,0x000d000b,0x000e000b,
 0x000e000c,0x000e000c,0x000e000c,0x000f000c,0x000f000c,0x0010000d,0x000c0009,
 0x000b000b,0x000b000a,0x000c000a,0x000c000a,0x000d000b,0x000d000b,0x000d000b,
 0x000e000b,0x000e000c,0x000f000c,0x000f000c,0x000f000c,0x000f000c,0x0011000d,
 0x0011000d,0x000c000a,0x000b000b,0x000c000b,0x000c000b,0x000d000b,0x000d000b,
 0x000d000b,0x000e000b,0x000e000b,0x000f000b,0x000f000c,0x000f000c,0x000f000c,
 0x0010000c,0x0010000d,0x0010000d,0x000c000a,0x000c000b,0x000c000b,0x000c000b,
 0x000d000b,0x000d000b,0x000e000b,0x000e000b,0x000f000c,0x000f000c,0x000f000c,
 0x000f000c,0x0010000c,0x000f000d,0x0010000d,0x000f000d,0x000d000a,0x000c000c,
 0x000d000b,0x000c000b,0x000d000b,0x000e000b,0x000e000c,0x000e000c,0x000e000c,
 0x000f000c,0x0010000c,0x0010000c,0x0010000d,0x0011000d,0x0011000d,0x0010000d,
 0x000c000a,0x000d000c,0x000d000c,0x000d000b,0x000d000b,0x000e000b,0x000e000c,
 0x000f000c,0x0010000c,0x0010000c,0x0010000c,0x0010000c,0x0010000d,0x0010000d,
 0x000f000d,0x0010000d,0x000d000a,0x000d000c,0x000e000c,0x000e000c,0x000e000c,
 0x000e000c,0x000f000c,0x000f000c,0x000f000c,0x000f000c,0x0011000c,0x0010000d,
 0x0010000d,0x0010000d,0x0010000d,0x0012000d,0x000d000a,0x000f000c,0x000e000c,
 0x000e000c,0x000e000c,0x000f000c,0x000f000c,0x0010000c,0x0010000c,0x0010000d,
 0x0012000d,0x0011000d,0x0011000d,0x0011000d,0x0013000d,0x0011000d,0x000d000a,
 0x000e000d,0x000f000c,0x000d000c,0x000e000c,0x0010000c,0x0010000c,0x000f000c,
 0x0010000d,0x0010000d,0x0011000d,0x0012000d,0x0011000d,0x0013000d,0x0011000d,
 0x0010000d,0x000d000a,0x000a0009,0x000a0009,0x000a0009,0x000b0009,0x000b0009,
 0x000c0009,0x000c0009,0x000c0009,0x000d0009,0x000d0009,0x000d0009,0x000d000a,
 0x000d000a,0x000d000a,0x000d000a,0x000a0006};

static const uint8_t t1l_const[8]  = {1,3,2,3,1,4,3,5};
static const uint8_t t2l_const[9]  = {1,3,6,3,3,5,5,5,6};
static const uint8_t t3l_const[9]  = {2,2,6,3,2,5,5,5,6};
static const uint8_t t5l_const[16] = {1,3,6,7,3,3,6,7,6,6,7,8,7,6,7,8};
static const uint8_t t6l_const[16] = {3,3,5,7,3,2,4,5,4,4,5,6,6,5,6,7};

static const uint8_t t7l_const[36] =
{1,3,6,8,8,9,3,4,6,7,7,8,6,5,7,8,8,9,7,7,8,9,9,9,7,7,8,9,9,10,8,8,9,10,10,10};

static const uint8_t t8l_const[36] =
{2,3,6,8,8,9,3,2,4,8,8,8,6,4,6,8,8,9,8,8,8,9,9,10,8,7,8,9,10,10,9,8,9,9,11,11};

static const uint8_t t9l_const[36] =
{3,3,5,6,8,9,3,3,4,5,6,8,4,4,5,6,7,8,6,5,6,7,7,8,7,6,7,7,8,9,8,7,8,8,9,9};

static const uint8_t t10l_const[64] =
{1,3,6,8,9,9,9,10,3,4,6,7,8,9,8,8,6,6,7,8,9,10,9,9,7,7,8,9,10,10,9,10,8,8,9,10,
 10,10,10,10,9,9,10,10,11,11,10,11,8,8,9,10,10,10,11,11,9,8,9,10,10,11,11,11};

static const uint8_t t11l_const[64] =
{2,3,5,7,8,9,8,9,3,3,4,6,8,8,7,8,5,5,6,7,8,9,8,8,7,6,7,9,8,10,8,9,8,8,8,9,9,10,
 9,10,8,8,9,10,10,11,10,11,8,7,7,8,9,10,10,10,8,7,8,9,10,10,10,10};

static const uint8_t t12l_const[64] =
{4,3,5,7,8,9,9,9,3,3,4,5,7,7,8,8,5,4,5,6,7,8,7,8,6,5,6,6,7,8,8,8,7,6,7,7,8,
 8,8,9,8,7,8,8,8,9,8,9,8,7,7,8,8,9,9,10,9,8,8,9,9,9,9,10};

static const uint8_t t13l_const[256] =
{1,4,6,7,8,9,9,10,9,10,11,11,12,12,13,13,3,4,6,7,8,8,9,9,9,9,10,10,11,12,12,12,
 6,6,7,8,9,9,10,10,9,10,10,11,11,12,13,13,7,7,8,9,9,10,10,10,10,11,11,11,11,12,
 13,13,8,7,9,9,10,10,11,11,10,11,11,12,12,13,13,14,9,8,9,10,10,10,11,11,11,11,
 12,11,13,13,14,14,9,9,10,10,11,11,11,11,11,12,12,12,13,13,14,14,10,9,10,11,11,
 11,12,12,12,12,13,13,13,14,16,16,9,8,9,10,10,11,11,12,12,12,12,13,13,14,15,15,
 10,9,10,10,11,11,11,13,12,13,13,14,14,14,16,15,10,10,10,11,11,12,12,13,12,13,
 14,13,14,15,16,17,11,10,10,11,12,12,12,12,13,13,13,14,15,15,15,16,11,11,11,12,
 12,13,12,13,14,14,15,15,15,16,16,16,12,11,12,13,13,13,14,14,14,14,14,15,16,15,
 16,16,13,12,12,13,13,13,15,14,14,17,15,15,15,17,16,16,12,12,13,14,14,14,15,14,
 15,15,16,16,19,18,19,16};

static const uint8_t t15l_const[256] =
{3,4,5,7,7,8,9,9,9,10,10,11,11,11,12,13,4,3,5,6,7,7,8,8,8,9,9,10,10,10,11,11,5,
 5,5,6,7,7,8,8,8,9,9,10,10,11,11,11,6,6,6,7,7,8,8,9,9,9,10,10,10,11,11,11,7,6,
 7,7,8,8,9,9,9,9,10,10,10,11,11,11,8,7,7,8,8,8,9,9,9,9,10,10,11,11,11,12,9,7,8,
 8,8,9,9,9,9,10,10,10,11,11,12,12,9,8,8,9,9,9,9,10,10,10,10,10,11,11,11,12,9,8,
 8,9,9,9,9,10,10,10,10,11,11,12,12,12,9,8,9,9,9,9,10,10,10,11,11,11,11,12,12,
 12,10,9,9,9,10,10,10,10,10,11,11,11,11,12,13,12,10,9,9,9,10,10,10,10,11,11,11,
 11,12,12,12,13,11,10,9,10,10,10,11,11,11,11,11,11,12,12,13,13,11,10,10,10,10,
 11,11,11,11,12,12,12,12,12,13,13,12,11,11,11,11,11,11,11,12,12,12,12,13,13,12,
 13,12,11,11,11,11,11,11,12,12,12,12,12,13,13,13,13};

static const uint8_t t16l_const[256] =
{1,4,6,8,9,9,10,10,11,11,11,12,12,12,13,9,3,4,6,7,8,9,9,9,10,10,10,11,12,11,12,
 8,6,6,7,8,9,9,10,10,11,10,11,11,11,12,12,9,8,7,8,9,9,10,10,10,11,11,12,12,12,
 13,13,10,9,8,9,9,10,10,11,11,11,12,12,12,13,13,13,9,9,8,9,9,10,11,11,12,11,12,
 12,13,13,13,14,10,10,9,9,10,11,11,11,11,12,12,12,12,13,13,14,10,10,9,10,10,11,
 11,11,12,12,13,13,13,13,15,15,10,10,10,10,11,11,11,12,12,13,13,13,13,14,14,14,
 10,11,10,10,11,11,12,12,13,13,13,13,14,13,14,13,11,11,11,10,11,12,12,12,12,13,
 14,14,14,15,15,14,10,12,11,11,11,12,12,13,14,14,14,14,14,14,13,14,11,12,12,12,
 12,12,13,13,13,13,15,14,14,14,14,16,11,14,12,12,12,13,13,14,14,14,16,15,15,15,
 17,15,11,13,13,11,12,14,14,13,14,14,15,16,15,17,15,14,11,9,8,8,9,9,10,10,10,
 11,11,11,11,11,11,11,8};

static const uint8_t t24l_const[256] =
{4,4,6,7,8,9,9,10,10,11,11,11,11,11,12,9,4,4,5,6,7,8,8,9,9,9,10,10,10,10,10,8,
 6,5,6,7,7,8,8,9,9,9,9,10,10,10,11,7,7,6,7,7,8,8,8,9,9,9,9,10,10,10,10,7,8,7,7,
 8,8,8,8,9,9,9,10,10,10,10,11,7,9,7,8,8,8,8,9,9,9,9,10,10,10,10,10,7,9,8,8,8,8,
 9,9,9,9,10,10,10,10,10,11,7,10,8,8,8,9,9,9,9,10,10,10,10,10,11,11,8,10,9,9,9,
 9,9,9,9,9,10,10,10,10,11,11,8,10,9,9,9,9,9,9,10,10,10,10,10,11,11,11,8,11,9,9,
 9,9,10,10,10,10,10,10,11,11,11,11,8,11,10,9,9,9,10,10,10,10,10,10,11,11,11,11,
 8,11,10,10,10,10,10,10,10,10,10,11,11,11,11,11,8,11,10,10,10,10,10,10,10,11,
 11,11,11,11,11,11,8,12,10,10,10,10,10,10,11,11,11,11,11,11,11,11,8,8,7,7,7,7,
 7,7,7,7,7,7,8,8,8,8,4};

static const struct huffcodetab ht_const[HTN] =
{ { 0, NULL, NULL}, /* Apparently not used */
  { 2, t1HB,  t1l},
  { 3, t2HB,  t2l},
  { 3, t3HB,  t3l},
  { 0, NULL, NULL}, /* Apparently not used */
  { 4, t5HB,  t5l},
  { 4, t6HB,  t6l},
  { 6, t7HB,  t7l},
  { 6, t8HB,  t8l},
  { 6, t9HB,  t9l},
  { 8, t10HB, t10l},
  { 8, t11HB, t11l},
  { 8, t12HB, t12l},
  {16, t13HB, t13l},
  { 0, NULL,  NULL}, /* Apparently not used */
  {16, t15HB, t15l} };

static const struct huffcodebig ht_big[HTN] =
{ { 16,  1,    1 },
  { 16,  2,    3 },
  { 16,  3,    7 },
  { 16,  4,   15 },
  { 16,  6,   63 },
  { 16,  8,  255 },
  { 16, 10, 1023 },
  { 16, 13, 8191 },
  { 16,  4,   15 },
  { 16,  5,   31 },
  { 16,  6,   63 },
  { 16,  7,  127 },
  { 16,  8,  255 },
  { 16,  9,  511 },
  { 16, 11, 2047 },
  { 16, 13, 8191 } };

static const struct
{
  uint32_t region0_cnt;
  uint32_t region1_cnt;
} subdv_table[23] =
{ {0, 0}, /*  0 bands */
  {0, 0}, /*  1 bands */
  {0, 0}, /*  2 bands */
  {0, 0}, /*  3 bands */
  {0, 0}, /*  4 bands */
  {0, 1}, /*  5 bands */
  {1, 1}, /*  6 bands */
  {1, 1}, /*  7 bands */
  {1, 2}, /*  8 bands */
  {2, 2}, /*  9 bands */
  {2, 3}, /* 10 bands */
  {2, 3}, /* 11 bands */
  {3, 4}, /* 12 bands */
  {3, 4}, /* 13 bands */
  {3, 4}, /* 14 bands */
  {4, 5}, /* 15 bands */
  {4, 5}, /* 16 bands */
  {4, 6}, /* 17 bands */
  {5, 6}, /* 18 bands */
  {5, 6}, /* 19 bands */
  {5, 7}, /* 20 bands */
  {6, 7}, /* 21 bands */
  {6, 7}, /* 22 bands */
};

static const uint32_t sfBand[6][23] =
{
/* Table B.2.b: 22.05 kHz */
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
/* Table B.2.c: 24 kHz */
{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
/* Table B.2.a: 16 kHz */
{0,6,12,18,24,30,36,44,45,66,80,96,116,140,168,200,238,248,336,396,464,522,576},
/* Table B.8.b: 44.1 kHz */
{0,4, 8,12,16,20,24,30,36,44,52,62, 74, 90,110,134,162,196,238,288,342,418,576},
/* Table B.8.c: 48 kHz */
{0,4, 8,12,16,20,24,30,36,42,50,60, 72, 88,106,128,156,190,230,276,330,384,576},
/* Table B.8.a: 32 kHz */
{0,4, 8,12,16,20,24,30,36,44,54,66, 82,102,126,156,194,240,296,364,448,550,576} };


static const short int2idx_const[4096] = /*  int2idx[i] = sqrt(i*sqrt(i)); */
{
  0,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  8,  8,  8,  9,  9,
  9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16,
 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21,
 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26,
 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36,
 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 40,
 41, 41, 41, 41, 42, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45,
 45, 45, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49,
 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53,
 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57,
 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
 61, 61, 61, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65,
 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68,
 68, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72, 72,
 72, 72, 72, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75,
 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 79, 79, 79,
 79, 79, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82,
 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 86, 86, 86,
 86, 86, 86, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
 89, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 93,
 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 96, 96, 96,
 96, 96, 96, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99,
 99, 99,100,100,100,100,100,100,101,101,101,101,101,101,102,102,102,102,102,102,
103,103,103,103,103,103,104,104,104,104,104,104,104,105,105,105,105,105,105,106,
106,106,106,106,106,107,107,107,107,107,107,107,108,108,108,108,108,108,109,109,
109,109,109,109,110,110,110,110,110,110,110,111,111,111,111,111,111,112,112,112,
112,112,112,112,113,113,113,113,113,113,114,114,114,114,114,114,115,115,115,115,
115,115,115,116,116,116,116,116,116,117,117,117,117,117,117,117,118,118,118,118,
118,118,118,119,119,119,119,119,119,120,120,120,120,120,120,120,121,121,121,121,
121,121,122,122,122,122,122,122,122,123,123,123,123,123,123,123,124,124,124,124,
124,124,125,125,125,125,125,125,125,126,126,126,126,126,126,126,127,127,127,127,
127,127,128,128,128,128,128,128,128,129,129,129,129,129,129,129,130,130,130,130,
130,130,131,131,131,131,131,131,131,132,132,132,132,132,132,132,133,133,133,133,
133,133,133,134,134,134,134,134,134,134,135,135,135,135,135,135,136,136,136,136,
136,136,136,137,137,137,137,137,137,137,138,138,138,138,138,138,138,139,139,139,
139,139,139,139,140,140,140,140,140,140,140,141,141,141,141,141,141,141,142,142,
142,142,142,142,142,143,143,143,143,143,143,143,144,144,144,144,144,144,144,145,
145,145,145,145,145,145,146,146,146,146,146,146,146,147,147,147,147,147,147,147,
148,148,148,148,148,148,148,149,149,149,149,149,149,149,150,150,150,150,150,150,
150,151,151,151,151,151,151,151,152,152,152,152,152,152,152,153,153,153,153,153,
153,153,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155,156,156,156,
156,156,156,156,157,157,157,157,157,157,157,158,158,158,158,158,158,158,159,159,
159,159,159,159,159,160,160,160,160,160,160,160,160,161,161,161,161,161,161,161,
162,162,162,162,162,162,162,163,163,163,163,163,163,163,163,164,164,164,164,164,
164,164,165,165,165,165,165,165,165,166,166,166,166,166,166,166,167,167,167,167,
167,167,167,167,168,168,168,168,168,168,168,169,169,169,169,169,169,169,169,170,
170,170,170,170,170,170,171,171,171,171,171,171,171,172,172,172,172,172,172,172,
172,173,173,173,173,173,173,173,174,174,174,174,174,174,174,174,175,175,175,175,
175,175,175,176,176,176,176,176,176,176,176,177,177,177,177,177,177,177,178,178,
178,178,178,178,178,178,179,179,179,179,179,179,179,180,180,180,180,180,180,180,
180,181,181,181,181,181,181,181,182,182,182,182,182,182,182,182,183,183,183,183,
183,183,183,184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,186,186,
186,186,186,186,186,186,187,187,187,187,187,187,187,187,188,188,188,188,188,188,
188,189,189,189,189,189,189,189,189,190,190,190,190,190,190,190,190,191,191,191,
191,191,191,191,192,192,192,192,192,192,192,192,193,193,193,193,193,193,193,193,
194,194,194,194,194,194,194,195,195,195,195,195,195,195,195,196,196,196,196,196,
196,196,196,197,197,197,197,197,197,197,197,198,198,198,198,198,198,198,199,199,
199,199,199,199,199,199,200,200,200,200,200,200,200,200,201,201,201,201,201,201,
201,201,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203,204,204,204,
204,204,204,204,204,205,205,205,205,205,205,205,205,206,206,206,206,206,206,206,
206,207,207,207,207,207,207,207,207,208,208,208,208,208,208,208,208,209,209,209,
209,209,209,209,209,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211,
211,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213,213,214,214,214,
214,214,214,214,214,215,215,215,215,215,215,215,215,216,216,216,216,216,216,216,
216,217,217,217,217,217,217,217,217,218,218,218,218,218,218,218,218,219,219,219,
219,219,219,219,219,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221,
221,222,222,222,222,222,222,222,222,223,223,223,223,223,223,223,223,224,224,224,
224,224,224,224,224,225,225,225,225,225,225,225,225,226,226,226,226,226,226,226,
226,227,227,227,227,227,227,227,227,228,228,228,228,228,228,228,228,229,229,229,
229,229,229,229,229,229,230,230,230,230,230,230,230,230,231,231,231,231,231,231,
231,231,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,233,234,234,
234,234,234,234,234,234,234,235,235,235,235,235,235,235,235,236,236,236,236,236,
236,236,236,237,237,237,237,237,237,237,237,238,238,238,238,238,238,238,238,238,
239,239,239,239,239,239,239,239,240,240,240,240,240,240,240,240,241,241,241,241,
241,241,241,241,242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,
243,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,246,246,
246,246,246,246,246,246,247,247,247,247,247,247,247,247,248,248,248,248,248,248,
248,248,248,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,
251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,253,253,253,253,
253,253,253,253,253,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,
255,255,256,256,256,256,256,256,256,256,257,257,257,257,257,257,257,257,257,258,
258,258,258,258,258,258,258,259,259,259,259,259,259,259,259,259,260,260,260,260,
260,260,260,260,261,261,261,261,261,261,261,261,261,262,262,262,262,262,262,262,
262,263,263,263,263,263,263,263,263,263,264,264,264,264,264,264,264,264,265,265,
265,265,265,265,265,265,265,266,266,266,266,266,266,266,266,267,267,267,267,267,
267,267,267,267,268,268,268,268,268,268,268,268,268,269,269,269,269,269,269,269,
269,270,270,270,270,270,270,270,270,270,271,271,271,271,271,271,271,271,271,272,
272,272,272,272,272,272,272,273,273,273,273,273,273,273,273,273,274,274,274,274,
274,274,274,274,275,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,
276,276,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,279,
279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,281,281,281,
281,281,281,281,281,282,282,282,282,282,282,282,282,282,283,283,283,283,283,283,
283,283,283,284,284,284,284,284,284,284,284,284,285,285,285,285,285,285,285,285,
286,286,286,286,286,286,286,286,286,287,287,287,287,287,287,287,287,287,288,288,
288,288,288,288,288,288,288,289,289,289,289,289,289,289,289,289,290,290,290,290,
290,290,290,290,291,291,291,291,291,291,291,291,291,292,292,292,292,292,292,292,
292,292,293,293,293,293,293,293,293,293,293,294,294,294,294,294,294,294,294,294,
295,295,295,295,295,295,295,295,295,296,296,296,296,296,296,296,296,296,297,297,
297,297,297,297,297,297,297,298,298,298,298,298,298,298,298,299,299,299,299,299,
299,299,299,299,300,300,300,300,300,300,300,300,300,301,301,301,301,301,301,301,
301,301,302,302,302,302,302,302,302,302,302,303,303,303,303,303,303,303,303,303,
304,304,304,304,304,304,304,304,304,305,305,305,305,305,305,305,305,305,306,306,
306,306,306,306,306,306,306,307,307,307,307,307,307,307,307,307,308,308,308,308,
308,308,308,308,308,309,309,309,309,309,309,309,309,309,310,310,310,310,310,310,
310,310,310,311,311,311,311,311,311,311,311,311,312,312,312,312,312,312,312,312,
312,313,313,313,313,313,313,313,313,313,314,314,314,314,314,314,314,314,314,315,
315,315,315,315,315,315,315,315,316,316,316,316,316,316,316,316,316,317,317,317,
317,317,317,317,317,317,318,318,318,318,318,318,318,318,318,318,319,319,319,319,
319,319,319,319,319,320,320,320,320,320,320,320,320,320,321,321,321,321,321,321,
321,321,321,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323,323,323,
323,324,324,324,324,324,324,324,324,324,325,325,325,325,325,325,325,325,325,325,
326,326,326,326,326,326,326,326,326,327,327,327,327,327,327,327,327,327,328,328,
328,328,328,328,328,328,328,329,329,329,329,329,329,329,329,329,330,330,330,330,
330,330,330,330,330,330,331,331,331,331,331,331,331,331,331,332,332,332,332,332,
332,332,332,332,333,333,333,333,333,333,333,333,333,334,334,334,334,334,334,334,
334,334,335,335,335,335,335,335,335,335,335,335,336,336,336,336,336,336,336,336,
336,337,337,337,337,337,337,337,337,337,338,338,338,338,338,338,338,338,338,338,
339,339,339,339,339,339,339,339,339,340,340,340,340,340,340,340,340,340,341,341,
341,341,341,341,341,341,341,341,342,342,342,342,342,342,342,342,342,343,343,343,
343,343,343,343,343,343,344,344,344,344,344,344,344,344,344,344,345,345,345,345,
345,345,345,345,345,346,346,346,346,346,346,346,346,346,347,347,347,347,347,347,
347,347,347,347,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349,349,
349,349,350,350,350,350,350,350,350,350,350,350,351,351,351,351,351,351,351,351,
351,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,353,353,353,353,
354,354,354,354,354,354,354,354,354,355,355,355,355,355,355,355,355,355,355,356,
356,356,356,356,356,356,356,356,357,357,357,357,357,357,357,357,357,357,358,358,
358,358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359,360,360,360,
360,360,360,360,360,360,361,361,361,361,361,361,361,361,361,361,362,362,362,362,
362,362,362,362,362,363,363,363,363,363,363,363,363,363,363,364,364,364,364,364,
364,364,364,364,365,365,365,365,365,365,365,365,365,365,366,366,366,366,366,366,
366,366,366,367,367,367,367,367,367,367,367,367,367,368,368,368,368,368,368,368,
368,368,369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,370,370,
370,370,371,371,371,371,371,371,371,371,371,372,372,372,372,372,372,372,372,372,
372,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374,
375,375,375,375,375,375,375,375,375,375,376,376,376,376,376,376,376,376,376,377,
377,377,377,377,377,377,377,377,377,378,378,378,378,378,378,378,378,378,379,379,
379,379,379,379,379,379,379,379,380,380,380,380,380,380,380,380,380,380,381,381,
381,381,381,381,381,381,381,382,382,382,382,382,382,382,382,382,382,383,383,383,
383,383,383,383,383,383,383,384,384,384,384,384,384,384,384,384,385,385,385,385,
385,385,385,385,385,385,386,386,386,386,386,386,386,386,386,386,387,387,387,387,
387,387,387,387,387,387,388,388,388,388,388,388,388,388,388,389,389,389,389,389,
389,389,389,389,389,390,390,390,390,390,390,390,390,390,390,391,391,391,391,391,
391,391,391,391,391,392,392,392,392,392,392,392,392,392,393,393,393,393,393,393,
393,393,393,393,394,394,394,394,394,394,394,394,394,394,395,395,395,395,395,395,
395,395,395,395,396,396,396,396,396,396,396,396,396,397,397,397,397,397,397,397,
397,397,397,398,398,398,398,398,398,398,398,398,398,399,399,399,399,399,399,399,
399,399,399,400,400,400,400,400,400,400,400,400,400,401,401,401,401,401,401,401,
401,401,402,402,402,402,402,402,402,402,402,402,403,403,403,403,403,403,403,403,
403,403,404,404,404,404,404,404,404,404,404,404,405,405,405,405,405,405,405,405,
405,405,406,406,406,406,406,406,406,406,406,406,407,407,407,407,407,407,407,407,
407,407,408,408,408,408,408,408,408,408,408,408,409,409,409,409,409,409,409,409,
409,410,410,410,410,410,410,410,410,410,410,411,411,411,411,411,411,411,411,411,
411,412,412,412,412,412,412,412,412,412,412,413,413,413,413,413,413,413,413,413,
413,414,414,414,414,414,414,414,414,414,414,415,415,415,415,415,415,415,415,415,
415,416,416,416,416,416,416,416,416,416,416,417,417,417,417,417,417,417,417,417,
417,418,418,418,418,418,418,418,418,418,418,419,419,419,419,419,419,419,419,419,
419,420,420,420,420,420,420,420,420,420,420,421,421,421,421,421,421,421,421,421,
421,422,422,422,422,422,422,422,422,422,422,423,423,423,423,423,423,423,423,423,
423,424,424,424,424,424,424,424,424,424,424,425,425,425,425,425,425,425,425,425,
425,426,426,426,426,426,426,426,426,426,426,427,427,427,427,427,427,427,427,427,
427,428,428,428,428,428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,
429,430,430,430,430,430,430,430,430,430,430,431,431,431,431,431,431,431,431,431,
431,432,432,432,432,432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,
433,434,434,434,434,434,434,434,434,434,434,435,435,435,435,435,435,435,435,435,
435,435,436,436,436,436,436,436,436,436,436,436,437,437,437,437,437,437,437,437,
437,437,438,438,438,438,438,438,438,438,438,438,439,439,439,439,439,439,439,439,
439,439,440,440,440,440,440,440,440,440,440,440,441,441,441,441,441,441,441,441,
441,441,442,442,442,442,442,442,442,442,442,442,443,443,443,443,443,443,443,443,
443,443,443,444,444,444,444,444,444,444,444,444,444,445,445,445,445,445,445,445,
445,445,445,446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,447,
447,447,447,448,448,448,448,448,448,448,448,448,448,448,449,449,449,449,449,449,
449,449,449,449,450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451,
451,451,451,451,452,452,452,452,452,452,452,452,452,452,453,453,453,453,453,453,
453,453,453,453,453,454,454,454,454,454,454,454,454,454,454,455,455,455,455,455,
455,455,455,455,455,456,456,456,456,456,456,456,456,456,456,457,457,457,457,457,
457,457,457,457,457,457,458,458,458,458,458,458,458,458,458,458,459,459,459,459,
459,459,459,459,459,459,460,460,460,460,460,460,460,460,460,460,460,461,461,461,
461,461,461,461,461,461,461,462,462,462,462,462,462,462,462,462,462,463,463,463,
463,463,463,463,463,463,463,463,464,464,464,464,464,464,464,464,464,464,465,465,
465,465,465,465,465,465,465,465,466,466,466,466,466,466,466,466,466,466,466,467,
467,467,467,467,467,467,467,467,467,468,468,468,468,468,468,468,468,468,468,469,
469,469,469,469,469,469,469,469,469,469,470,470,470,470,470,470,470,470,470,470,
471,471,471,471,471,471,471,471,471,471,472,472,472,472,472,472,472,472,472,472,
472,473,473,473,473,473,473,473,473,473,473,474,474,474,474,474,474,474,474,474,
474,475,475,475,475,475,475,475,475,475,475,475,476,476,476,476,476,476,476,476,
476,476,477,477,477,477,477,477,477,477,477,477,477,478,478,478,478,478,478,478,
478,478,478,479,479,479,479,479,479,479,479,479,479,479,480,480,480,480,480,480,
480,480,480,480,481,481,481,481,481,481,481,481,481,481,482,482,482,482,482,482,
482,482,482,482,482,483,483,483,483,483,483,483,483,483,483,484,484,484,484,484,
484,484,484,484,484,484,485,485,485,485,485,485,485,485,485,485,486,486,486,486,
486,486,486,486,486,486,486,487,487,487,487,487,487,487,487,487,487,488,488,488,
488,488,488,488,488,488,488,488,489,489,489,489,489,489,489,489,489,489,490,490,
490,490,490,490,490,490,490,490,490,491,491,491,491,491,491,491,491,491,491,492,
492,492,492,492,492,492,492,492,492,492,493,493,493,493,493,493,493,493,493,493,
494,494,494,494,494,494,494,494,494,494,494,495,495,495,495,495,495,495,495,495,
495,496,496,496,496,496,496,496,496,496,496,496,497,497,497,497,497,497,497,497,
497,497,497,498,498,498,498,498,498,498,498,498,498,499,499,499,499,499,499,499,
499,499,499,499,500,500,500,500,500,500,500,500,500,500,501,501,501,501,501,501,
501,501,501,501,501,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,
503,503,503,503,503,503,504,504,504,504,504,504,504,504,504,504,504,505,505,505,
505,505,505,505,505,505,505,506,506,506,506,506,506,506,506,506,506,506,507,507,
507,507,507,507,507,507,507,507,507,508,508,508,508,508,508,508,508,508,508,509,
509,509,509,509,509,509,509,509,509,509,510,510,510,510,510,510,510,510,510,510,
510,511,511,511,511,511,511,511,511,511,511,512,512,512,512,512 };

static const int order[32] = 
{ 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29,
  2, 3, 18, 19,10,11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 };

static const long sampr_index[2][3] = 
{ { 22050, 24000, 16000 },      /* MPEG 2 */
  { 44100, 48000, 32000 } };    /* MPEG 1 */

static const long bitr_index[2][15] =
{ {0, 8,16,24,32,40,48,56, 64, 80, 96,112,128,144,160},    /* MPEG 2 */
  {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320} };  /* MPEG 1 */

static const int num_bands[3][15]  =
{ {0,10,10,10,10,12,14,16, 20, 22, 24, 26, 28, 30, 32},
  {0,10,10,10,10,10,12,14, 18, 24, 26, 28, 30, 32, 32},
  {0,10,12,14,18,24,26,28, 30, 32, 32, 32, 32, 32, 32} };

static const int cx_const[9] =
{ 16135, 10531,  5604, 15396, -2845,-12551, 14189,  8192, 16384 };

static const int ca_const[8] =
{-16859,-15458,-10269, -5961, -3099, -1342,  -465,  -121 };

static const int cs_const[8] =
{ 28098, 28893, 31117, 32221, 32621, 32740, 32765, 32768 };

static const short enwindow_const[15*27+24] = 
{ 0,   65,  593,  1766, 22228, 2115, 611, 62,
  8,  119, 1419, 10564,-11659,-1635,-154, -9,
 -8, -119,-1419,-10564, 11659, 1635, 154,  9, 464,  100,  91,
  0,   69,  604,  1635, 23148, 2363, 643, 62,
  7,  107, 1368, 10449,-12733,-1818,-180,-11,
 -7, -107,-1368,-10449, 12733, 1818, 180, 11, 420,  200, 164,
  0,   72,  608,  1465, 23979, 2600, 671, 63,
  7,   94, 1305, 10265,-13818,-2004,-207,-12,
 -7,  -94,-1305,-10265, 13818, 2004, 207, 12, 380,  297, 220,
  0,   76,  606,  1256, 24718, 2825, 693, 63,
  6,   81, 1232, 10016,-14908,-2192,-236,-14,
 -6,  -81,-1232,-10016, 14908, 2192, 236, 14, 342,  392, 262,
  0,   78,  597,  1007, 25359, 3033, 712, 63,
  6,   68, 1150,  9706,-15995,-2380,-267,-15,
 -6,  -68,-1150, -9706, 15995, 2380, 267, 15, 307,  483, 289,
  0,   80,  580,   719, 25901, 3224, 726, 62,
  6,   54, 1060,  9343,-17072,-2565,-299,-17,
 -6,  -54,-1060, -9343, 17072, 2565, 299, 17, 274,  569, 304,
 -1,   82,  555,   391, 26339, 3395, 735, 61,
  5,   40,  963,  8930,-18131,-2747,-332,-19,
 -5,  -40, -963, -8930, 18131, 2747, 332, 19, 242,  650, 307,
 -1,   83,  523,    26, 26672, 3545, 740, 60,
  5,   27,  861,  8474,-19164,-2923,-366,-21,
 -5,  -27, -861, -8474, 19164, 2923, 366, 21, 212,  724, 300,
 -1,   83,  482,  -376, 26900, 3672, 739, 58,
  4,   14,  756,  7981,-20163,-3092,-401,-24,
 -4,  -14, -756, -7981, 20163, 3092, 401, 24, 183,  792, 283,
 -1,   82,  433,  -812, 27022, 3776, 735, 56,
  4,    1,  648,  7456,-21122,-3250,-435,-26,
 -4,   -1, -648, -7456, 21122, 3250, 435, 26, 155,  851, 258,
 -1,   81,  376, -1281, 27038, 3855, 726, 54,
  3,  -11,  539,  6907,-22032,-3397,-470,-28,
 -3,   11, -539, -6907, 22032, 3397, 470, 28, 128,  903, 226,
 -1,   78,  312, -1778, 26951, 3910, 713, 52,
  3,  -22,  430,  6338,-22887,-3530,-503,-31,
 -3,   22, -430, -6338, 22887, 3530, 503, 31, 102,  946, 188,
 -2,   75,  239, -2302, 26761, 3941, 696, 49,
  3,  -33,  322,  5757,-23678,-3648,-537,-34,
 -3,   33, -322, -5757, 23678, 3648, 537, 34,  76,  980, 145,
 -2,   70,  160, -2848, 26472, 3948, 676, 47,
  3,  -42,  217,  5167,-24399,-3749,-568,-36,
 -3,   42, -217, -5167, 24399, 3749, 568, 36,  50, 1004,  99,
 -2,   65,   74, -3412, 26087, 3931, 653, 44,
  2,  -51,  115,  4577,-25045,-3830,-599,-39,
 -2,   51, -115, -4577, 25045, 3830, 599, 39,  25, 1019,  50,

 25610,3891,627,42,-3990,-18,58,-2,
 21226,-21226,10604,-10604,1860,-1860,1458,-1458,576,-576,130,-130,60,-60,8,-8
};

static const int win_const[18][4] = {
  { -3072, -134, -146, 3352 },
  { -2747, -362, -471, 3579 },
  { -2387, -529, -831, 3747 },
  { -2004, -632,-1214, 3850 },
  { -1609, -666,-1609, 3884 },
  { -1214, -632,-2004, 3850 },
  {  -831, -529,-2387, 3747 },
  {  -471, -362,-2747, 3579 },
  {  -146, -134,-3072, 3352 },
  {   134,-3072,-3352, -146 },
  {   362,-2747,-3579, -471 },
  {   529,-2387,-3747, -831 },
  {   632,-2004,-3850,-1214 },
  {   666,-1609,-3884,-1609 },
  {   632,-1214,-3850,-2004 },
  {   529, -831,-3747,-2387 },
  {   362, -471,-3579,-2747 },
  {   134, -146,-3352,-3072 } };

/* forward declarations */
static int  HuffmanCode( short *ix, char *xr_sign, uint32_t begin, uint32_t end, int table);
static int  HuffmanCod1( short *ix, char *xr_sign, uint32_t begin, uint32_t end, int table);
static void putbits(uint32_t val, uint32_t nbit);
static int  find_best_2( short *ix, uint32_t start, uint32_t end, const uint32_t *table,
                          uint32_t len, int *bits);
static int  find_best_3( short *ix, uint32_t start, uint32_t end, const uint32_t *table,
                         uint32_t len, int *bits);
static int  count_bit1 ( short *ix, uint32_t start, uint32_t end, int *bits );
static int  count_bigv ( short *ix, uint32_t start, uint32_t end, int table0, int table1,
                  int *bits);


static void encodeSideInfo( side_info_t si[2][2] )
{
  int gr, ch, header;
  uint32_t  cc=0, sz=0;
  
  /*
   * MPEG header layout:
   * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
   * A (31-21) = frame sync
   * B (20-19) = MPEG type
   * C (18-17) = MPEG layer
   * D (16)    = protection bit
   * E (15-12) = bitrate index
   * F (11-10) = samplerate index
   * G (9)     = padding bit
   * H (8)     = private bit
   * I (7-6)   = channel mode
   * J (5-4)   = mode extension (jstereo only)
   * K (3)     = copyright bit
   * L (2)     = original
   * M (1-0)   = emphasis
   */

  header  = (0xfff00000) | /* frame sync (AAAAAAAAA AAA)
                              mp3 type (upper):  1 (B)  */
            (0x01 << 17) | /* mp3 layer:        01 (CC) */
            ( 0x1 << 16) | /* mp3 crc:           1 (D)  */
            ( 0x1 <<  2);  /* mp3 org:           1 (L)  */
  header |= cfg.mpg.type    << 19;
  header |= cfg.mpg.bitr_id << 12;
  header |= cfg.mpg.smpl_id << 10;
  header |= cfg.mpg.padding <<  9;
  header |= cfg.mpg.mode    <<  6;
  /* no emphasis (bits 0-1) */
  putbits( header, 32 );

  if(cfg.mpg.type == 1)
  { /* MPEG1 */
    if(cfg.channels == 2)  { putlong( 0, 20); }
    else                   { putlong( 0, 18); }

    for(gr=0; gr<cfg.granules; gr++)
      for(ch=0; ch<cfg.channels; ch++)
      {
        side_info_t *gi = &si[gr][ch];

        putlong((gi->part2_3_length+42),12 ); /* add scale_facs array size */
        putlong( gi->address3>>1,        9 );
        putlong( gi->global_gain,        8 );
        putlong( 9,                      4 ); /* set scale_facs compr type */
        putlong( gi->table_select[0],    6 );
        putlong( gi->table_select[1],    5 );
        putlong( gi->table_select[2],    5 );
        putlong( gi->region_0_1,         7 );
        putlong( 1                  ,    2 ); /* set scale_facs to 1bit */
        putlong( gi->table_select[3],    1 );
      }
  }
  else
  { /* MPEG2 */
    if(cfg.channels == 2)  { putlong( 0, 10); }
    else                   { putlong( 0,  9); }

    for(ch=0; ch<cfg.channels; ch++)
    {
      side_info_t *gi = &si[0][ch];

      putlong((gi->part2_3_length+42),12 ); /* add scale_facs array size */
      putlong( gi->address3>>1,        9 );
      putlong( gi->global_gain,        8 );
      putlong( 0xCA,                   9 ); /* set scale_facs compr type */
      putlong( gi->table_select[0],    6 );
      putlong( gi->table_select[1],    5 );
      putlong( gi->table_select[2],    5 );
      putlong( gi->region_0_1     ,    7 );
      putlong( 1                  ,    1 ); /* set scale_facs to 1bit */
      putlong( gi->table_select[3],    1 );
    }
  }
  /* flush remaining bits */
  putbits(cc, sz);
}

/* Note the discussion of huffmancodebits() on pages 28 and 29 of the IS,
   as well as the definitions of the side information on pages 26 and 27. */
static void Huffmancodebits( short *ix, char *xr_sign, side_info_t *gi )
{
  int    region1   = gi->address1;
  int    region2   = gi->address2;
  int    bigvals   = gi->address3;
  int    count1    = bigvals + (gi->count1 << 2);
  int    stuffBits = 0;
  int    bits      = 0;
  int    i, v;

  for(i=v=0; i<32; i+=2)
    v |= band_scale_f[i>>1] << (30-i);
  putbits(v, 32); // store scale_facs (part1)

  for(v=0; i<42; i+=2)
    v |= band_scale_f[i>>1] << (40-i);
  putbits(v, 10); // store scale_facs (part2)

  if(region1 > 0)
    bits += HuffmanCode(ix, xr_sign,   0    , region1, gi->table_select[0]);

  if(region2 > region1)
    bits += HuffmanCode(ix, xr_sign, region1, region2, gi->table_select[1]);

  if(bigvals > region2)
    bits += HuffmanCode(ix, xr_sign, region2, bigvals, gi->table_select[2]);
 
  if(count1 > bigvals)
    bits += HuffmanCod1(ix, xr_sign, bigvals,  count1, gi->table_select[3]);

  if((stuffBits = gi->part2_3_length - bits) > 0)
  {
    int stuffWords = stuffBits >> 5;
    int remainBits = stuffBits & 31;

    if( remainBits )
      putbits( ~0, remainBits );

    while( stuffWords-- )
      putbits( ~0, 32 ); /* Huffman code tables leed to padding ones */
  }
}

int HuffmanCod1( short *ix, char *xr_sign, uint32_t begin, uint32_t end, int tbl)
{
  uint32_t  cc=0, sz=0;
  uint32_t  i, d, p;
  int     sumbit=0, s=0, l=0, v, w, x, y;
  #define sgnv xr_sign[i+0]
  #define sgnw xr_sign[i+1]
  #define sgnx xr_sign[i+2]
  #define sgny xr_sign[i+3]

  for(i=begin; i<end; i+=4)
  {
    v = ix[i+0];
    w = ix[i+1];
    x = ix[i+2];
    y = ix[i+3];
    p = (v << 3) + (w << 2) + (x << 1) + y;

    switch(p)
    {
      case  0: l=0; s = 0; break;
      case  1: l=1; s =                                           sgny; break;
      case  2: l=1; s =                              sgnx;              break;
      case  3: l=2; s =                             (sgnx << 1) + sgny; break;
      case  4: l=1; s =                sgnw;                            break;
      case  5: l=2; s =               (sgnw << 1)               + sgny; break;
      case  6: l=2; s =               (sgnw << 1) +  sgnx;              break;
      case  7: l=3; s =               (sgnw << 2) + (sgnx << 1) + sgny; break;
      case  8: l=1; s =  sgnv;                                          break;
      case  9: l=2; s = (sgnv << 1)                             + sgny; break;
      case 10: l=2; s = (sgnv << 1)               +  sgnx;              break;
      case 11: l=3; s = (sgnv << 2)               + (sgnx << 1) + sgny; break;
      case 12: l=2; s = (sgnv << 1) +  sgnw;                            break;
      case 13: l=3; s = (sgnv << 2) + (sgnw << 1)               + sgny; break;
      case 14: l=3; s = (sgnv << 2) + (sgnw << 1) +  sgnx;              break;
      case 15: l=4; s = (sgnv << 3) + (sgnw << 2) + (sgnx << 1) + sgny; break;
    }

    d = (ht_count[tbl][0][p] << l) + s;
    l =  ht_count[tbl][1][p];
    putlong( d, l );
    sumbit += l;
  }

  /* flush remaining bits */
  putbits(cc, sz);

  return sumbit;
}

/* Implements the pseudocode of page 98 of the IS */
int HuffmanCode(short *ix, char *xr_sign, uint32_t begin, uint32_t end, int table)
{
  uint32_t       cc=0, sz=0, code;
  uint32_t       i, xl=0, yl=0, idx;
  int            x, y, bit, sumbit=0;
  #define sign_x xr_sign[i+0]
  #define sign_y xr_sign[i+1]

  if(table == 0)
    return 0;

  if( table > 15 )
  { /* ESC-table is used */
    uint32_t linbits  = ht_big[table-16].linbits;
    uint16_t *hffcode = table < 24 ? t16HB : t24HB;
    uint8_t  *hlen    = table < 24 ? t16l  : t24l;

    for(i=begin; i<end; i+=2)
    {
      x = ix[ i ];
      y = ix[i+1];

      if(x > 14) { xl = x - 15;  x = 15; }
      if(y > 14) { yl = y - 15;  y = 15; }

      idx  = x * 16 + y;
      code = hffcode[idx];
      bit  = hlen   [idx];

      if(x)
      {
        if(x > 14)
        {
          code = (code << linbits) | xl;
          bit += linbits;
        }

        code = (code << 1) | sign_x;
        bit += 1;
      }

      if(y)
      {
        if(y > 14)
        {
          if(bit + linbits + 1 > 32)
          {
            putlong( code, bit );
            sumbit += bit;
            code = bit = 0;
          }

          code = (code << linbits) | yl;
          bit += linbits;
        }

        code = (code << 1) | sign_y;
        bit += 1;
      }

      putlong( code, bit );
      sumbit += bit;
    }
  }
  else
  { /* No ESC-words */
    const struct huffcodetab *h = &ht[table];

    for(i=begin; i<end; i+=2)
    {
      x = ix[i];
      y = ix[i+1];

      idx  = x * h->len + y;
      code = h->table[idx];
      bit  = h->hlen [idx];

      if(x)
      {
        code = (code << 1) | sign_x;
        bit += 1;
      }

      if(y)
      {
        code = (code << 1) | sign_y;
        bit += 1;
      }

      putlong( code, bit );
      sumbit += bit;
    }
  }

  /* flush remaining bits */
  putbits(cc, sz);

  return sumbit;
}

void putbits(uint32_t val, uint32_t nbit)
{
  int new_bitpos = CodedData.bitpos + nbit;
  int ptrpos     = CodedData.bitpos >> 5;

  val = val & (0xffffffff >> (32 - nbit));

  /* data fit in one uint32_t */
  if(((new_bitpos - 1) >> 5) == ptrpos)
    CodedData.bbuf[ptrpos] |= val << ((32 - new_bitpos) & 31);
  else
  {
    CodedData.bbuf[ptrpos  ] |= val >> ((new_bitpos - 32) & 31);
    CodedData.bbuf[ptrpos+1] |= val << ((32 - new_bitpos) & 31);
  }

  CodedData.bitpos = new_bitpos;
}

/***************************************************************************/
/*  Choose the Huffman table that will encode ix[begin..end] with          */
/*  the fewest bits.                                                       */
/*  Note: This code contains knowledge about the sizes and characteristic  */
/*  of the Huffman tables as defined in the IS (Table B.7), and will not   */
/*  work with any arbitrary tables.                                        */
/***************************************************************************/
static int choose_table( short *ix, uint32_t begin, uint32_t end, int *bits )
{
  uint32_t i;
  int    max, table0, table1;
  
  for(i=begin,max=0; i<end; i++)
    if(ix[i] > max)
      max = ix[i];

  if(max < 16)
  {
    /* tables without linbits */
    /* indx: 0  1  2  3  4  5  6  7  8  9 10 11 12  13 14  15 */
    /*  len: 0, 2, 3, 3, 0, 4, 4, 6, 6, 6, 8, 8, 8, 16, 0, 16 */
    switch(max)
    {
      case 0:  return  0;
      case 1:  return       count_bit1(ix, begin, end, bits);
      case 2:  return  2 + find_best_2(ix, begin, end, tab23, 3, bits);
      case 3:  return  5 + find_best_2(ix, begin, end, tab56, 4, bits);
      case 4:
      case 5:  return  7 + find_best_3(ix, begin, end, tab789, 6, bits);
      case 6:
      case 7:  return 10 + find_best_3(ix, begin, end, tabABC, 8, bits);
      default: return 13 + find_best_2(ix, begin, end, tab1315, 16, bits) * 2;
    }
  }
  else
  {
    /* tables with linbits */
    max -= 15;

    for(table0=0; table0<8; table0++)
      if(ht_big[table0].linmax >= max)
        break;

    for(table1=8; table1<16; table1++)
      if(ht_big[table1].linmax >= max)
        break;

    return 16 + count_bigv(ix, begin, end, table0, table1, bits);
  }
}

int find_best_2(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
                uint32_t len, int *bits)
{
  uint32_t i, sum = 0;

  for(i=start; i<end; i+=2)
    sum += table[ix[i] * len + ix[i+1]];

  if((sum & 0xffff) <= (sum >> 16))
  {
    *bits = (sum & 0xffff);
    return 1;
  }
  else
  {
    *bits = sum >> 16;
    return 0;
  }
}

int find_best_3(short *ix, uint32_t start, uint32_t end, const uint32_t *table,
                uint32_t len, int *bits)
{
  uint32_t i, j, sum  = 0;
  int          sum1 = 0;
  int          sum2 = 0;
  int          sum3 = 0;

  /* avoid overflow in packed additions: 78*13 < 1024 */
  for(i=start; i<end; )
  {
    j = i + 2*78 > end ? end : i + 2*78;

    for(sum=0; i<j; i+=2)
      sum += table[ix[i] * len + ix[i+1]];

    sum1 += (sum >> 20);
    sum2 += (sum >> 10) & 0x3ff;
    sum3 += (sum >>  0) & 0x3ff;
  }

  i = 0;
  if(sum1 > sum2) { sum1 = sum2;  i = 1; }
  if(sum1 > sum3) { sum1 = sum3;  i = 2; }

  *bits = sum1;

  return i;
}

/*************************************************************************/
/* Function: Count the number of bits necessary to code the subregion.   */
/*************************************************************************/
int count_bit1(short *ix, uint32_t start, uint32_t end, int *bits )
{
  uint32_t i, sum = 0;

  for(i=start; i<end; i+=2)
    sum += t1l[4 + ix[i] * 2 + ix[i+1]];

  *bits = sum;

  return 1; /* this is table1 */
}

int count_bigv(short *ix, uint32_t start, uint32_t end, int table0,
               int table1, int *bits )
{
  uint32_t  i, sum0, sum1, sum=0, bigv=0, x, y;

  /* ESC-table is used */
  for(i=start; i<end; i+=2)
  {
    x = ix[i];
    y = ix[i+1];

    if(x > 14) { x = 15; bigv++; }
    if(y > 14) { y = 15; bigv++; }

    sum += tab1624[x * 16 + y];
  }

  sum0 = (sum  >>  16)  + bigv * ht_big[table0].linbits;
  sum1 = (sum & 0xffff) + bigv * ht_big[table1].linbits;

  if(sum0 <= sum1)
  {
    *bits = sum0;
    return table0;
  }
  else
  {
    *bits = sum1;
    return table1;
  }
}

/*************************************************************************/
/* Function: Calculation of rzero, count1, address3                      */
/* (Partitions ix into big values, quadruples and zeros).                */
/*************************************************************************/
static int calc_runlen( short *ix, side_info_t *si )
{
  int  p, i, sum = 0;

  for(i=SAMPL2; i-=2; )
    if(*(uint32_t*)&ix[i-2]) /* !!!! short *ix; !!!!! */
      break;

  si->count1 = 0;

  for( ; i>3; i-=4)
  {
    int v = ix[i-1];
    int w = ix[i-2];
    int x = ix[i-3];
    int y = ix[i-4];
    
    if((v | w | x | y) <= 1)
    {
      p = (y<<3) + (x<<2) + (w<<1) + (v);

      sum += tab01[p];

      si->count1++;
    }
    else break;
  }

  si->address3 = i;

  if((sum >> 16) < (sum & 0xffff))
  {
    si->table_select[3] = 0;
    return sum >> 16;
  }
  else
  {
    si->table_select[3] = 1;
    return sum & 0xffff;
  }
}


/*************************************************************************/
/*   Function: Quantization of the vector xr ( -> ix)                    */
/*************************************************************************/
static int quantize_int(int *xr, short *ix, side_info_t *si)
{
  unsigned int i, idx, s, frac_pow[] = { 0x10000, 0xd745, 0xb505, 0x9838 };

  s = frac_pow[si->quantStep & 3] >> si->quantStep / 4;

  /* check for possible 'out of range' values */
  if(((si->max_val + 256) >> 8) * s >= (65536 << 8))
    return 0;

  if(((si->max_val + 256) >> 8) * s < (4096 << 8))
  { /* all values fit the table size */
    for(i=SAMPL2; i--; )
      ix[i] = int2idx[(xr[i] * s + 0x8000) >> 16];
  }
  else
  { /* check each index wether it fits the table */
    for(i=SAMPL2; i--; )
    {
      idx = (xr[i] * s + 0x08000) >> 16;

      if(idx > 4095)  ix[i] = int2idx[(idx + 8) >> 4] << 3;
      else            ix[i] = int2idx[idx];
    }
  }

  return 1;
}

/*************************************************************************/
/* subdivides the bigvalue region which will use separate Huffman tables */
/*************************************************************************/
static void subdivide(side_info_t *si)
{
  int scfb, count0, count1;
  
  if( !si->address3 )
  { /* no bigvalue region */
    si->region_0_1 = 0;
    si->address1   = 0;
    si->address2   = 0;
  }
  else
  {
    /* Calculate scale factor band index */
    for(scfb=0; scalefac[scfb] < si->address3; )
      scfb++;

    count0 = subdv_table[scfb].region0_cnt;
    count1 = subdv_table[scfb].region1_cnt;

    si->region_0_1 = (count0 << 3) | count1;
    si->address1   = scalefac[count0 + 1];
    si->address2   = scalefac[count0 + 1 + count1 + 1];
  }
}

/*******************************************************************/
/* Count the number of bits necessary to code the bigvalues region */
/*******************************************************************/
static int bigv_bitcount(short *ix, side_info_t *gi)
{
  int b1=0, b2=0, b3=0;

  /* Select huffman code tables for bigvalues regions */
  gi->table_select[0] = 0;
  gi->table_select[1] = 0;
  gi->table_select[2] = 0;

  if( gi->address1 > 0 )            /* region0 */
    gi->table_select[0] = choose_table(ix, 0           , gi->address1, &b1);

  if( gi->address2 > gi->address1 ) /* region1 */
    gi->table_select[1] = choose_table(ix, gi->address1, gi->address2, &b2);

  if( gi->address3 > gi->address2 ) /* region2 */
    gi->table_select[2] = choose_table(ix, gi->address2, gi->address3, &b3);

  return b1+b2+b3;
}

static int quantize_and_count_bits(int *xr, short *ix, side_info_t *si)
{
  int bits = 10000;

  if(quantize_int(xr, ix, si))
  {
    bits = calc_runlen(ix, si);      /* rzero,count1,address3  */
    subdivide(si);                   /* bigvalues sfb division */
    bits += bigv_bitcount(ix,si);    /* bit count */
  }

  return bits;
}

/************************************************************************/
/* The code selects the best quantStep for a particular set of scalefacs*/
/************************************************************************/ 
static int inner_loop(int *xr, int max_bits, side_info_t *si)
{
  int bits;

  while((bits=quantize_and_count_bits(xr, enc_data, si)) < max_bits-64)
  {
    if(si->quantStep == 0)
      break;

    if(si->quantStep <= 2)
      si->quantStep  = 0;
    else
      si->quantStep -= 2;
  }

  while(bits > max_bits)
  {
    si->quantStep++;
    bits = quantize_and_count_bits(xr, enc_data, si);
  }

  return bits;
}

static void iteration_loop(int *xr, side_info_t *si, int gr_cnt)
{
  int remain, tar_bits, max_bits = cfg.mean_bits;

  /* distribute reserved bits to remaining granules */
  tar_bits = max_bits + (cfg.ResvSize / gr_cnt & ~7);
  if(tar_bits > max_bits + max_bits/2)
    tar_bits = max_bits + max_bits/2;

  si->part2_3_length = inner_loop(xr, tar_bits, si);
  si->global_gain    = si->quantStep + 142 - si->additStep;

  /* unused bits of the reservoir can be used for remaining granules */
  cfg.ResvSize += max_bits - si->part2_3_length;

  /* end: distribute the reserved bits to one or two granules */
  if(gr_cnt == 1)
  {
    si->part2_3_length += cfg.ResvSize;
    /* mp3 format allows max 12bits for granule length */
    if(si->part2_3_length > 4092)
    {
      remain = (si->part2_3_length - 4092 + 31) >> 5;
      si->part2_3_length    -= remain << 5;
      si[-1].part2_3_length += remain << 5;

      while(remain--)
        putbits(~0, 32);
    }
  }
}


/* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */
void window_subband1(short *wk, int sb0[SBLIMIT], int sb1[SBLIMIT]) ICODE_ATTR;
void window_subband1(short *wk, int sb0[SBLIMIT], int sb1[SBLIMIT])
{
  int   k, i, u, v;
  short *wp, *x1, *x2;

#ifdef CPU_COLDFIRE
  int s0, s1, t0, t1;

  for(k=0; k<18; k++, wk+=64, sb0+=SBLIMIT, sb1+=SBLIMIT)
  {
    wp = enwindow;
    x1 = wk;
    x2 = x1 - 124;

    for(i=-15; i<0; i++)
    {
      asm volatile(
      "move.l (-224*4,%[x2]), %%d4\n"   /* d4 = x2[-224] */
      "movem.l (%[wp]), %%d0-%%d3\n"    /* load 8 values */
      "mac.w %%d0u, %%d4u,                       %%acc0\n"
      "mac.w %%d0u, %%d4l, (-160*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d0l, %%d4u,                       %%acc0\n"
      "mac.w %%d0l, %%d4l, ( -96*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d1u, %%d4u,                       %%acc0\n"
      "mac.w %%d1u, %%d4l, ( -32*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d1l, %%d4u,                       %%acc0\n"
      "mac.w %%d1l, %%d4l, (  32*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d2u, %%d4u,                       %%acc0\n"
      "mac.w %%d2u, %%d4l, (  96*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d2l, %%d4u,                       %%acc0\n"
      "mac.w %%d2l, %%d4l, ( 160*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d3u, %%d4u,                       %%acc0\n"
      "mac.w %%d3u, %%d4l, ( 224*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d3l, %%d4u,                       %%acc0\n"
      "mac.w %%d3l, %%d4l, (-256*4,%[x1]), %%d4, %%acc1\n"
      "movem.l (16,%[wp]), %%d0-%%d3\n" /* load 8 values */
      "mac.w %%d0u, %%d4u,                       %%acc0\n"
      "mac.w %%d0u, %%d4l, (-192*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d0l, %%d4u,                       %%acc0\n"
      "mac.w %%d0l, %%d4l, (-128*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d1u, %%d4u,                       %%acc0\n"
      "mac.w %%d1u, %%d4l, ( -64*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d1l, %%d4u,                       %%acc0\n"
      "mac.w %%d1l, %%d4l, (   0*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d2u, %%d4u,                       %%acc0\n"
      "mac.w %%d2u, %%d4l, (  64*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d2l, %%d4u,                       %%acc0\n"
      "mac.w %%d2l, %%d4l, ( 128*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d3u, %%d4u,                       %%acc0\n"
      "mac.w %%d3u, %%d4l, ( 192*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d3l, %%d4u,                       %%acc0\n"
      "mac.w %%d3l, %%d4l, ( 224*4,%[x1]), %%d4, %%acc1\n"
      "movclr.l %%acc0, %%d0\n"
      "move.l %%d0, %[s0]\n"
      "movclr.l %%acc1, %%d0\n"
      "move.l %%d0, %[s1]\n"

      "movem.l (%[wp]), %%d0-%%d3\n"    /* load 8 values */
      "mac.w %%d0u, %%d4u,                       %%acc0\n"
      "mac.w %%d0u, %%d4l, ( 160*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d0l, %%d4u,                       %%acc0\n"
      "mac.w %%d0l, %%d4l, (  96*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d1u, %%d4u,                       %%acc0\n"
      "mac.w %%d1u, %%d4l, (  32*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d1l, %%d4u,                       %%acc0\n"
      "mac.w %%d1l, %%d4l, ( -32*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d2u, %%d4u,                       %%acc0\n"
      "mac.w %%d2u, %%d4l, ( -96*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d2l, %%d4u,                       %%acc0\n"
      "mac.w %%d2l, %%d4l, (-160*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d3u, %%d4u,                       %%acc0\n"
      "mac.w %%d3u, %%d4l, (-224*4,%[x1]), %%d4, %%acc1\n"
      "mac.w %%d3l, %%d4u,                       %%acc0\n"
      "mac.w %%d3l, %%d4l, ( 256*4,%[x2]), %%d4, %%acc1\n"
      "movem.l (32,%[wp]), %%d0-%%d3\n"  /* load 8 values */
      "mac.w %%d0u, %%d4u,                       %%acc0\n"
      "mac.w %%d0u, %%d4l, ( 192*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d0l, %%d4u,                       %%acc0\n"
      "mac.w %%d0l, %%d4l, ( 128*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d1u, %%d4u,                       %%acc0\n"
      "mac.w %%d1u, %%d4l, (  64*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d1l, %%d4u,                       %%acc0\n"
      "mac.w %%d1l, %%d4l, (   0*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d2u, %%d4u,                       %%acc0\n"
      "mac.w %%d2u, %%d4l, ( -64*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d2l, %%d4u,                       %%acc0\n"
      "mac.w %%d2l, %%d4l, (-128*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d3u, %%d4u,                       %%acc0\n"
      "mac.w %%d3u, %%d4l, (-192*4,%[x2]), %%d4, %%acc1\n"
      "mac.w %%d3l, %%d4u,                       %%acc0\n"
      "mac.w %%d3l, %%d4l,                       %%acc1\n"
      "movclr.l %%acc0, %%d0\n"
      "move.l %%d0, %[t0]\n"
      "movclr.l %%acc1, %%d0\n"
      "move.l %%d0, %[t1]\n"

      : [x1] "+a" (x1), [x2] "+a" (x2), [s0] "+m" (s0), [t0] "+m" (t0),
                                        [s1] "+m" (s1), [t1] "+m" (t1)
      : [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");

      sb0[30+i*2] =  shft4(t0)          + shft13(s0) * wp[24];
      sb0[31+i*2] = shft13(t0) * wp[25] - shft13(s0) * wp[26];
      sb1[30+i*2] =  shft4(t1)          + shft13(s1) * wp[24];
      sb1[31+i*2] = shft13(t1) * wp[25] - shft13(s1) * wp[26];
      wp += 27;
      x1 -=  2;
      x2 +=  2;
    }

    asm volatile(
    "move.l ( -32*4,%[x1]), %%d4\n"   /* d4 = x1[-32] */
    "movem.l (%[wp]), %%d0-%%d3\n" /* load 8 values */

    "mac.w %%d0u, %%d4u,                       %%acc0\n"
    "mac.w %%d0u, %%d4l, ( -96*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d0l, %%d4u,                       %%acc0\n"
    "mac.w %%d0l, %%d4l, (-160*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1u, %%d4u,                       %%acc0\n"
    "mac.w %%d1u, %%d4l, (-224*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1l, %%d4u,                       %%acc0\n"
    "mac.w %%d1l, %%d4l, (  32*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2u, %%d4u,                       %%acc0\n"
    "mac.w %%d2u, %%d4l, (  96*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2l, %%d4u,                       %%acc0\n"
    "mac.w %%d2l, %%d4l, ( 160*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3u, %%d4u,                       %%acc0\n"
    "mac.w %%d3u, %%d4l, ( 224*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3l, %%d4u,                       %%acc0\n"
    "mac.w %%d3l, %%d4l, ( -16*4,%[x1]), %%d4, %%acc1\n"
    "movclr.l %%acc0, %%d0\n"
    "move.l %%d0, %[s0]\n"
    "movclr.l %%acc1, %%d0\n"
    "move.l %%d0, %[s1]\n"

    "movem.l (16,%[wp]), %%d0-%%d3\n" /* load 8 values */
    "mac.w %%d0u, %%d4u,                       %%acc0\n"
    "mac.w %%d0u, %%d4l, ( -48*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1u, %%d4u,                       %%acc0\n"
    "mac.w %%d1u, %%d4l, (  16*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1l, %%d4u,                       %%acc0\n"
    "mac.w %%d1l, %%d4l, ( -80*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2u, %%d4u,                       %%acc0\n"
    "mac.w %%d2u, %%d4l, (  48*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2u, %%d4u,                       %%acc0\n"
    "mac.w %%d2u, %%d4l, (-112*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3u, %%d4u,                       %%acc0\n"
    "mac.w %%d3u, %%d4l, (  80*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3l, %%d4u,                       %%acc0\n"
    "mac.w %%d3l, %%d4l, (-144*4,%[x1]), %%d4, %%acc1\n"
    "movem.l (32,%[wp]), %%d0-%%d3\n" /* load 8 values */
    "mac.w %%d0u, %%d4u,                       %%acc0\n"
    "mac.w %%d0u, %%d4l, ( 112*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d0u, %%d4u,                       %%acc0\n"
    "mac.w %%d0u, %%d4l, (-176*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1u, %%d4u,                       %%acc0\n"
    "mac.w %%d1u, %%d4l, ( 144*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d1l, %%d4u,                       %%acc0\n"
    "mac.w %%d1l, %%d4l, (-208*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2u, %%d4u,                       %%acc0\n"
    "mac.w %%d2u, %%d4l, ( 176*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d2u, %%d4u,                       %%acc0\n"
    "mac.w %%d2u, %%d4l, (-240*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3u, %%d4u,                       %%acc0\n"
    "mac.w %%d3u, %%d4l, ( 208*4,%[x1]), %%d4, %%acc1\n"
    "mac.w %%d3l, %%d4u,                       %%acc0\n"
    "mac.w %%d3l, %%d4l,                       %%acc1\n"
    "movclr.l %%acc0, %%d0\n"
    "move.l %%d0, %[t0]\n"
    "movclr.l %%acc1, %%d0\n"
    "move.l %%d0, %[t1]\n"

    : [x1] "+a" (x1), [s0] "+m" (s0), [t0] "+m" (t0),
                      [s1] "+m" (s1), [t1] "+m" (t1)
    : [wp] "a" (wp) : "d0", "d1", "d2", "d3", "d4");

    u  = shft4(s0 - t0);
    v  = shft4(s0 + t0);
    t0 = sb0[14];
    s0 = sb0[15] - t0;

    sb0[31] = v + t0;   /* A0 */
    sb0[30] = u + s0;   /* A1 */
    sb0[15] = u - s0;   /* A2 */
    sb0[14] = v - t0;   /* A3 */

    u  = shft4(s1 - t1);
    v  = shft4(s1 + t1);
    t1 = sb1[14];
    s1 = sb1[15] - t1;

    sb1[31] = v + t1;   /* A0 */
    sb1[30] = u + s1;   /* A1 */
    sb1[15] = u - s1;   /* A2 */
    sb1[14] = v - t1;   /* A3 */
  }
#else
  int ch, s, t, *a;

  for(ch=0; ch<cfg.channels; ch++)
  {
    a = ch ? sb1 : sb0;
    for(k=0; k<18; k++, wk+=64, a+=SBLIMIT)
    {
      wp = enwindow;
      x1 = wk;
      x2 = x1 - 124;

      /* x1[-572] .... x1[448] = 1022 */
      /* 18*4*16*32 */
      for(i=-15; i<0; i++)
      {
        s  = (int)x2[-224*2] * wp[ 0];  t  = (int)x1[ 224*2] * wp[ 0];
        s += (int)x2[-160*2] * wp[ 1];  t += (int)x1[ 160*2] * wp[ 1];
        s += (int)x2[- 96*2] * wp[ 2];  t += (int)x1[  96*2] * wp[ 2];
        s += (int)x2[- 32*2] * wp[ 3];  t += (int)x1[  32*2] * wp[ 3];
        s += (int)x2[  32*2] * wp[ 4];  t += (int)x1[- 32*2] * wp[ 4];
        s += (int)x2[  96*2] * wp[ 5];  t += (int)x1[- 96*2] * wp[ 5];
        s += (int)x2[ 160*2] * wp[ 6];  t += (int)x1[-160*2] * wp[ 6];
        s += (int)x2[ 224*2] * wp[ 7];  t += (int)x1[-224*2] * wp[ 7];
        s += (int)x1[-256*2] * wp[ 8];  t += (int)x2[ 256*2] * wp[16];
        s += (int)x1[-192*2] * wp[ 9];  t += (int)x2[ 192*2] * wp[17];
        s += (int)x1[-128*2] * wp[10];  t += (int)x2[ 128*2] * wp[18];
        s += (int)x1[- 64*2] * wp[11];  t += (int)x2[  64*2] * wp[19];
        s += (int)x1[   0*2] * wp[12];  t += (int)x2[   0*2] * wp[20];
        s += (int)x1[  64*2] * wp[13];  t += (int)x2[- 64*2] * wp[21];
        s += (int)x1[ 128*2] * wp[14];  t += (int)x2[-128*2] * wp[22];
        s += (int)x1[ 192*2] * wp[15];  t += (int)x2[-192*2] * wp[23];

        a[30+i*2] =  shft4(t)          + shft13(s) * wp[24];
        a[31+i*2] = shft13(t) * wp[25] - shft13(s) * wp[26];
        wp += 27;
        x1 -=  2;
        x2 +=  2;
      }

      t  =  (int)x1[- 16*2]            * wp[ 8];  s  = (int)x1[ -32*2] * wp[0];
      t += ((int)x1[- 48*2]-x1[ 16*2]) * wp[10];  s += (int)x1[ -96*2] * wp[1];
      t += ((int)x1[- 80*2]+x1[ 48*2]) * wp[12];  s += (int)x1[-160*2] * wp[2];
      t += ((int)x1[-112*2]-x1[ 80*2]) * wp[14];  s += (int)x1[-224*2] * wp[3];
      t += ((int)x1[-144*2]+x1[112*2]) * wp[16];  s += (int)x1[  32*2] * wp[4];
      t += ((int)x1[-176*2]-x1[144*2]) * wp[18];  s += (int)x1[  96*2] * wp[5];
      t += ((int)x1[-208*2]+x1[176*2]) * wp[20];  s += (int)x1[ 160*2] * wp[6];
      t += ((int)x1[-240*2]-x1[208*2]) * wp[22];  s += (int)x1[ 224*2] * wp[7];

      u = shft4(s - t);
      v = shft4(s + t);
      t = a[14];
      s = a[15] - t;

      a[31] = v + t;   /* A0 */
      a[30] = u + s;   /* A1 */
      a[15] = u - s;   /* A2 */
      a[14] = v - t;   /* A3 */
    }
    wk -= 18 * 64 - 1; /* rewind wk (to next channel start) */
  }
#endif
}

void window_subband2(short *x1, int a[SBLIMIT]) ICODE_ATTR;
void window_subband2(short *x1, int a[SBLIMIT])
{
  int   xr;
  short *wp = enwindow;
  short *x2 = x1 - 124;

  wp += 27 * 15;
  x1 -=  2 * 15;
  x2 +=  2 * 15;

  xr = a[28] - a[0];  a[0] += a[28];  a[28] = shft9(xr) * wp[-2*27+25];
  xr = a[29] - a[1];  a[1] += a[29];  a[29] = shft9(xr) * wp[-2*27+25];
  xr = a[26] - a[2];  a[2] += a[26];  a[26] = shft9(xr) * wp[-4*27+25];
  xr = a[27] - a[3];  a[3] += a[27];  a[27] = shft9(xr) * wp[-4*27+25];
  xr = a[24] - a[4];  a[4] += a[24];  a[24] = shft9(xr) * wp[-6*27+25];
  xr = a[25] - a[5];  a[5] += a[25];  a[25] = shft9(xr) * wp[-6*27+25];
  xr = a[22] - a[6];  a[6] += a[22];  a[22] = shft9(xr) * SQRT        ;
  xr = a[23] - a[7];  a[7] += a[23];  a[23] = shft9(xr) * SQRT  - a[7];
  a[ 7] -= a[ 6];
  a[22] -= a[ 7];
  a[23] -= a[22];
    
  xr = a[ 6];  a[ 6] = a[31] - xr;  a[31] = a[31] + xr;
  xr = a[ 7];  a[ 7] = a[30] - xr;  a[30] = a[30] + xr;
  xr = a[22];  a[22] = a[15] - xr;  a[15] = a[15] + xr;
  xr = a[23];  a[23] = a[14] - xr;  a[14] = a[14] + xr;

  xr = a[20] - a[ 8];  a[ 8] += a[20];  a[20] = shft9(xr) * wp[-10*27+25];
  xr = a[21] - a[ 9];  a[ 9] += a[21];  a[21] = shft9(xr) * wp[-10*27+25];
  xr = a[18] - a[10];  a[10] += a[18];  a[18] = shft9(xr) * wp[-12*27+25];
  xr = a[19] - a[11];  a[11] += a[19];  a[19] = shft9(xr) * wp[-12*27+25];
  xr = a[16] - a[12];  a[12] += a[16];  a[16] = shft9(xr) * wp[-14*27+25];
  xr = a[17] - a[13];  a[13] += a[17];  a[17] = shft9(xr) * wp[-14*27+25];
  xr =-a[20] + a[24];  a[20] += a[24];  a[24] = shft9(xr) * wp[-12*27+25];
  xr =-a[21] + a[25];  a[21] += a[25];  a[25] = shft9(xr) * wp[-12*27+25];
  xr = a[ 4] - a[ 8];  a[ 4] += a[ 8];  a[ 8] = shft9(xr) * wp[-12*27+25];
  xr = a[ 5] - a[ 9];  a[ 5] += a[ 9];  a[ 9] = shft9(xr) * wp[-12*27+25];
  xr = a[ 0] - a[12];  a[ 0] += a[12];  a[12] = shft9(xr) * wp[ -4*27+25];
  xr = a[ 1] - a[13];  a[ 1] += a[13];  a[13] = shft9(xr) * wp[ -4*27+25];
  xr = a[16] - a[28];  a[16] += a[28];  a[28] = shft9(xr) * wp[ -4*27+25];
  xr =-a[17] + a[29];  a[17] += a[29];  a[29] = shft9(xr) * wp[ -4*27+25];
  
  xr = SQRT * shft9(a[ 2] - a[10]);  a[ 2] += a[10];  a[10] = xr;
  xr = SQRT * shft9(a[ 3] - a[11]);  a[ 3] += a[11];  a[11] = xr;
  xr = SQRT * shft9(a[26] - a[18]);  a[18] += a[26];  a[26] = xr - a[18];
  xr = SQRT * shft9(a[27] - a[19]);  a[19] += a[27];  a[27] = xr - a[19];
  
  xr = a[ 2];  a[19] -= a[ 3];  a[ 3] -= xr;  a[ 2] = a[31] - xr;  a[31] += xr;
  xr = a[ 3];  a[11] -= a[19];  a[18] -= xr;  a[ 3] = a[30] - xr;  a[30] += xr;
  xr = a[18];  a[27] -= a[11];  a[19] -= xr;  a[18] = a[15] - xr;  a[15] += xr;
  
  xr = a[19];  a[10] -= xr;  a[19] = a[14] - xr;  a[14] += xr;
  xr = a[10];  a[11] -= xr;  a[10] = a[23] - xr;  a[23] += xr;
  xr = a[11];  a[26] -= xr;  a[11] = a[22] - xr;  a[22] += xr;
  xr = a[26];  a[27] -= xr;  a[26] = a[ 7] - xr;  a[ 7] += xr;
  
  xr = a[27];  a[27] = a[6] - xr;  a[6] += xr;
  
  xr = SQRT * shft9(a[ 0] - a[ 4]);  a[ 0] += a[ 4];  a[ 4] = xr;
  xr = SQRT * shft9(a[ 1] - a[ 5]);  a[ 1] += a[ 5];  a[ 5] = xr;
  xr = SQRT * shft9(a[16] - a[20]);  a[16] += a[20];  a[20] = xr;
  xr = SQRT * shft9(a[17] - a[21]);  a[17] += a[21];  a[21] = xr;
  xr =-SQRT * shft9(a[ 8] - a[12]);  a[ 8] += a[12];  a[12] = xr - a[ 8];
  xr =-SQRT * shft9(a[ 9] - a[13]);  a[ 9] += a[13];  a[13] = xr - a[ 9];
  xr =-SQRT * shft9(a[25] - a[29]);  a[25] += a[29];  a[29] = xr - a[25];
  xr =-SQRT * shft9(a[24] + a[28]);  a[24] -= a[28];  a[28] = xr - a[24];
  
  xr = a[24] - a[16]; a[24] = xr;
  xr = a[20] - xr;    a[20] = xr;
  xr = a[28] - xr;    a[28] = xr;
  
  xr = a[25] - a[17]; a[25] = xr;
  xr = a[21] - xr;    a[21] = xr;
  xr = a[29] - xr;    a[29] = xr;
  
  xr = a[17] - a[1];  a[17] = xr;
  xr = a[ 9] - xr;    a[ 9] = xr;
  xr = a[25] - xr;    a[25] = xr;
  xr = a[ 5] - xr;    a[ 5] = xr;
  xr = a[21] - xr;    a[21] = xr;
  xr = a[13] - xr;    a[13] = xr;
  xr = a[29] - xr;    a[29] = xr;
  
  xr = a[ 1] - a[0];  a[ 1] = xr;
  xr = a[16] - xr;    a[16] = xr;
  xr = a[17] - xr;    a[17] = xr;
  xr = a[ 8] - xr;    a[ 8] = xr;
  xr = a[ 9] - xr;    a[ 9] = xr;
  xr = a[24] - xr;    a[24] = xr;
  xr = a[25] - xr;    a[25] = xr;
  xr = a[ 4] - xr;    a[ 4] = xr;
  xr = a[ 5] - xr;    a[ 5] = xr;
  xr = a[20] - xr;    a[20] = xr;
  xr = a[21] - xr;    a[21] = xr;
  xr = a[12] - xr;    a[12] = xr;
  xr = a[13] - xr;    a[13] = xr;
  xr = a[28] - xr;    a[28] = xr;
  xr = a[29] - xr;    a[29] = xr;
  
  xr = a[ 0];  a[ 0] += a[31];  a[31] -= xr;
  xr = a[ 1];  a[ 1] += a[30];  a[30] -= xr;
  xr = a[16];  a[16] += a[15];  a[15] -= xr;
  xr = a[17];  a[17] += a[14];  a[14] -= xr;
  xr = a[ 8];  a[ 8] += a[23];  a[23] -= xr;
  xr = a[ 9];  a[ 9] += a[22];  a[22] -= xr;
  xr = a[24];  a[24] += a[ 7];  a[ 7] -= xr;
  xr = a[25];  a[25] += a[ 6];  a[ 6] -= xr;
  xr = a[ 4];  a[ 4] += a[27];  a[27] -= xr;
  xr = a[ 5];  a[ 5] += a[26];  a[26] -= xr;
  xr = a[20];  a[20] += a[11];  a[11] -= xr;
  xr = a[21];  a[21] += a[10];  a[10] -= xr;
  xr = a[12];  a[12] += a[19];  a[19] -= xr;
  xr = a[13];  a[13] += a[18];  a[18] -= xr;
  xr = a[28];  a[28] += a[ 3];  a[ 3] -= xr;
  xr = a[29];  a[29] += a[ 2];  a[ 2] -= xr;
}

void mdct_long(int *out, int *in) ICODE_ATTR;
void mdct_long(int *out, int *in)
{
  int ct,st;
  int tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;
  int ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;

  /* 1,2, 5,6, 9,10, 13,14, 17 */
  tc1 = in[17] - in[ 9];
  tc3 = in[15] - in[11];
  tc4 = in[14] - in[12];
  ts5 = in[ 0] + in[ 8];
  ts6 = in[ 1] + in[ 7];
  ts7 = in[ 2] + in[ 6];
  ts8 = in[ 3] + in[ 5];

  out[17] = (ts5 + ts7 - ts8) * cx[8] - (ts6 - in[4]) * cx[8];
  st      = (ts5 + ts7 - ts8) * cx[7] + (ts6 - in[4]) * cx[8];
  ct      = (tc1 - tc3 - tc4) * cx[6];
  out[5]  = ct + st;
  out[6]  = ct - st;
    
  tc2     = (in[16] - in[10]) * cx[6];
  ts6     =  ts6 * cx[7] + in[4] * cx[8];

  ct      =  tc1 * cx[0] + tc2 + tc3 * cx[1] + tc4 * cx[2];
  st      = -ts5 * cx[4] + ts6 - ts7 * cx[5] + ts8 * cx[3];
  out[1]  = ct + st;
  out[2]  = ct - st;
    
  ct      =  tc1 * cx[1] - tc2 - tc3 * cx[2] + tc4 * cx[0];
  st      = -ts5 * cx[5] + ts6 - ts7 * cx[3] + ts8 * cx[4];
  out[ 9] = ct + st;
  out[10] = ct - st;
    
  ct      = tc1 * cx[2] - tc2 + tc3 * cx[0] - tc4 * cx[1];
  st      = ts5 * cx[3] - ts6 + ts7 * cx[4] - ts8 * cx[5];
  out[13] = ct + st;
  out[14] = ct - st;

  ts1 = in[ 8] - in[ 0];
  ts3 = in[ 6] - in[ 2];
  ts4 = in[ 5] - in[ 3];
  tc5 = in[17] + in[ 9];
  tc6 = in[16] + in[10];
  tc7 = in[15] + in[11];
  tc8 = in[14] + in[12];

  out[0]  = (tc5 + tc7 + tc8) * cx[8] + (tc6 + in[13]) * cx[8];
  ct      = (tc5 + tc7 + tc8) * cx[7] - (tc6 + in[13]) * cx[8];
  st      = (ts1 - ts3 + ts4) * cx[6];
  out[11] = ct + st;
  out[12] = ct - st;

  ts2     = (in[7] - in[1]) * cx[6];
  tc6     = in[13] * cx[8] - tc6 * cx[7];

  ct      = tc5 * cx[3] - tc6 + tc7 * cx[4] + tc8 * cx[5];
  st      = ts1 * cx[2] + ts2 + ts3 * cx[0] + ts4 * cx[1];
  out[3]  = ct + st;
  out[4]  = ct - st;

  ct      =-tc5 * cx[5] + tc6 - tc7 * cx[3] - tc8 * cx[4];
  st      = ts1 * cx[1] + ts2 - ts3 * cx[2] - ts4 * cx[0];
  out[7]  = ct + st;
  out[8]  = ct - st;

  ct      =-tc5 * cx[4] + tc6 - tc7 * cx[5] - tc8 * cx[3];
  st      = ts1 * cx[0] - ts2 + ts3 * cx[1] - ts4 * cx[2];
  out[15] = ct + st;
  out[16] = ct - st;
}

static int find_bitrate_index(int type, int bitrate, bool stereo)
{
    if (type == 1 && !stereo && bitrate > 160)
        bitrate = 160;

    return ci->round_value_to_list32(bitrate,
        &bitr_index[type][1], 14, true) + 1;
}

static int find_samplerate_index(long freq, int *mp3_type)
{
    int mpeg = freq >= (32000+24000)/2 ? 1 : 0;
    int i = ci->round_value_to_list32(freq, sampr_index[mpeg], 3, true);
    *mp3_type = mpeg;
    return i;    
}

static bool init_mp3_encoder_engine(int sample_rate,
                                    int num_channels,
                                    int rec_mono_mode,
                                    struct encoder_config *enc_cfg)
{
    const bool stereo = num_channels > 1;
    uint32_t avg_byte_per_frame;

    cfg.channels      = stereo ? 2 : 1;
    cfg.rec_mono_mode = rec_mono_mode;
    cfg.mpg.mode      = stereo ? 0 : 3; /* 0=stereo, 3=mono */
    cfg.mpg.smpl_id   = find_samplerate_index(sample_rate, &cfg.mpg.type);
    cfg.samplerate    = sampr_index[cfg.mpg.type][cfg.mpg.smpl_id];
    cfg.mpg.bitr_id   = find_bitrate_index(cfg.mpg.type,
                                           enc_cfg->mp3_enc.bitrate,
                                           stereo);
    cfg.mpg.bitrate   = bitr_index[cfg.mpg.type][cfg.mpg.bitr_id];
    cfg.mpg.num_bands = num_bands[stereo ? cfg.mpg.type : 2][cfg.mpg.bitr_id];

    if (cfg.mpg.type == 1)
    {
        cfg.granules = 2;
        pcm_chunk_size = PCM_CHUNK_SIZE1;
        samp_per_frame = SAMP_PER_FRAME1;
    }
    else
    {
        cfg.granules = 1;
        pcm_chunk_size = PCM_CHUNK_SIZE2;
        samp_per_frame = SAMP_PER_FRAME2;
    }

    memcpy(scalefac, sfBand[cfg.mpg.smpl_id + 3*cfg.mpg.type], sizeof(scalefac));
    memset(mfbuf     , 0              , sizeof(mfbuf     ));
    memset(mdct_freq , 0              , sizeof(mdct_freq ));
    memset(enc_data  , 0              , sizeof(enc_data  ));
    memset(sb_data   , 0              , sizeof(sb_data   ));
    memset(&CodedData, 0              , sizeof(CodedData ));
    memcpy(ca        , ca_const       , sizeof(ca        ));
    memcpy(cs        , cs_const       , sizeof(cs        ));
    memcpy(cx        , cx_const       , sizeof(cx        ));
    memcpy(win       , win_const      , sizeof(win       ));
    memcpy(enwindow  , enwindow_const , sizeof(enwindow  ));
    memcpy(int2idx   , int2idx_const  , sizeof(int2idx   ));
    memcpy(ht_count  , ht_count_const , sizeof(ht_count  ));
    memcpy( tab01    , tab01_const    , sizeof(tab01     ));
    memcpy( tab23    , tab23_const    , sizeof(tab23     ));
    memcpy( tab56    , tab56_const    , sizeof(tab56     ));
    memcpy( tab1315  , tab1315_const  , sizeof(tab1315   ));
    memcpy( tab1624  , tab1624_const  , sizeof(tab1624   ));
    memcpy( tab789   , tab789_const   , sizeof(tab789    ));
    memcpy( tabABC   , tabABC_const   , sizeof(tabABC    ));
    memcpy( t1HB     , t1HB_const     , sizeof(t1HB      ));
    memcpy( t2HB     , t2HB_const     , sizeof(t2HB      ));
    memcpy( t3HB     , t3HB_const     , sizeof(t3HB      ));
    memcpy( t5HB     , t5HB_const     , sizeof(t5HB      ));
    memcpy( t6HB     , t6HB_const     , sizeof(t6HB      ));
    memcpy( t7HB     , t7HB_const     , sizeof(t7HB      ));
    memcpy( t8HB     , t8HB_const     , sizeof(t8HB      ));
    memcpy( t9HB     , t9HB_const     , sizeof(t9HB      ));
    memcpy(t10HB     , t10HB_const    , sizeof(t10HB     ));
    memcpy(t11HB     , t11HB_const    , sizeof(t11HB     ));
    memcpy(t12HB     , t12HB_const    , sizeof(t12HB     ));
    memcpy(t13HB     , t13HB_const    , sizeof(t13HB     ));
    memcpy(t15HB     , t15HB_const    , sizeof(t15HB     ));
    memcpy(t16HB     , t16HB_const    , sizeof(t16HB     ));
    memcpy(t24HB     , t24HB_const    , sizeof(t24HB     ));
    memcpy( t1l      , t1l_const      , sizeof(t1l       ));
    memcpy( t2l      , t2l_const      , sizeof(t2l       ));
    memcpy( t3l      , t3l_const      , sizeof(t3l       ));
    memcpy( t5l      , t5l_const      , sizeof(t5l       ));
    memcpy( t6l      , t6l_const      , sizeof(t6l       ));
    memcpy( t7l      , t7l_const      , sizeof(t7l       ));
    memcpy( t8l      , t8l_const      , sizeof(t8l       ));
    memcpy( t9l      , t9l_const      , sizeof(t9l       ));
    memcpy(t10l      , t10l_const     , sizeof(t10l      ));
    memcpy(t11l      , t11l_const     , sizeof(t11l      ));
    memcpy(t12l      , t12l_const     , sizeof(t12l      ));
    memcpy(t13l      , t13l_const     , sizeof(t13l      ));
    memcpy(t15l      , t15l_const     , sizeof(t15l      ));
    memcpy(t16l      , t16l_const     , sizeof(t16l      ));
    memcpy(t24l      , t24l_const     , sizeof(t24l      ));
    memcpy(ht        , ht_const       , sizeof(ht        ));

    ht[ 0].table =  NULL;  ht[ 0].hlen = NULL; /* Apparently not used */
    ht[ 1].table =  t1HB;  ht[ 1].hlen =  t1l;
    ht[ 2].table =  t2HB;  ht[ 2].hlen =  t2l;
    ht[ 3].table =  t3HB;  ht[ 3].hlen =  t3l;
    ht[ 4].table =  NULL;  ht[ 4].hlen = NULL; /* Apparently not used */
    ht[ 5].table =  t5HB;  ht[ 5].hlen =  t5l;
    ht[ 6].table =  t6HB;  ht[ 6].hlen =  t6l;
    ht[ 7].table =  t7HB;  ht[ 7].hlen =  t7l;
    ht[ 8].table =  t8HB;  ht[ 8].hlen =  t8l;
    ht[ 9].table =  t9HB;  ht[ 9].hlen =  t9l;
    ht[10].table = t10HB;  ht[10].hlen = t10l;
    ht[11].table = t11HB;  ht[11].hlen = t11l;
    ht[12].table = t12HB;  ht[12].hlen = t12l;
    ht[13].table = t13HB;  ht[13].hlen = t13l;
    ht[14].table =  NULL;  ht[14].hlen = NULL; /* Apparently not used */
    ht[15].table = t15HB;  ht[15].hlen = t15l;

    /* Figure average number of 'bytes' per frame */
    avg_byte_per_frame = SAMPL2 * 16000 * cfg.mpg.bitrate / (2 - cfg.mpg.type);
    avg_byte_per_frame = avg_byte_per_frame / cfg.samplerate;
    cfg.byte_per_frame = avg_byte_per_frame / 64;
    cfg.frac_per_frame = avg_byte_per_frame & 63;
    cfg.slot_lag       = 0;
    cfg.sideinfo_len   = 32 + (cfg.mpg.type ? (cfg.channels == 1 ? 136 : 256)
                                            : (cfg.channels == 1 ?  72 : 136));

    return true;
}

STATICIRAM void to_mono_mm(void) ICODE_ATTR;
STATICIRAM void to_mono_mm(void)
{
    /* |llllllllllllllll|rrrrrrrrrrrrrrrr| =>
     * |mmmmmmmmmmmmmmmm|mmmmmmmmmmmmmmmm|
     */
    uint16_t *samp = &mfbuf[2*512];
    uint16_t *samp_end = samp + 2*samp_per_frame;

    inline void to_mono(uint16_t **samp)
    {
        int16_t r = **samp;
        int16_t l = *(*samp+1);
        int32_t m;

        switch(cfg.rec_mono_mode)
        {
            case 1:
                /* mono = L */
                m  = l;
                break;
            case 2:
                /* mono = R */
                m  = r;
                break;
            case 0:
            default:
                /* mono = (L+R)/2 */
                m  = l + r + err;
                err = m & 1;
                m >>= 1;
                break;
        }
        *(*samp)++ = (uint16_t)m;
        *(*samp)++ = (uint16_t)m;
    } /* to_mono */

    do
    {
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
        to_mono(&samp);
    }
    while (samp < samp_end);
} /* to_mono_mm */

#ifdef ROCKBOX_LITTLE_ENDIAN
/* Swaps a frame to big endian */
static inline void byte_swap_frame32(uint32_t *dst, uint32_t *src,
                                     size_t size) ICODE_ATTR;
static inline void byte_swap_frame32(uint32_t *dst, uint32_t *src,
                                     size_t size)
{
    uint32_t *src_end = SKIPBYTES(src, size);

    do
    {
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
        *dst++ = swap32(*src++);
    }
    while(src < src_end);
} /* byte_swap_frame32 */
#endif /* ROCKBOX_LITTLE_ENDIAN */

static void set_scale_facs(int *mdct_freq)
{
  unsigned int i, is, ie, k, s;
  int max_freq_val, avrg_freq_val;

  /* calc average of first 256 frequency values */
  for(avrg_freq_val=i=0; i<256; i++)
    avrg_freq_val += mdct_freq[i];
  avrg_freq_val >>= 8;

  /* if max of current band is smaller than average, increase precision */
  /* last band keeps untouched (not scaled) */
  for(is=k=0; is<scalefac[21]; k++)
  {
    max_freq_val = 0;

    for(i=is, ie=scalefac[k+1]; i<ie; i++)
      if(max_freq_val < mdct_freq[i])
        max_freq_val = mdct_freq[i];

    for(s=0; s<3; s++)
      if((max_freq_val<<s) > avrg_freq_val)
        break;

    band_scale_f[k] = (unsigned char)s;

    for(i=is; s && i<ie; i++)
      mdct_freq[i] <<= s;

    is = ie;
  }
}

STATICIRAM void encode_frame(char *buffer, struct enc_chunk_hdr *chunk)
                             ICODE_ATTR;
STATICIRAM void encode_frame(char *buffer, struct enc_chunk_hdr *chunk)
{
   int      gr, gr_cnt;
   uint32_t max;

    /* encode one mp3 frame in this loop */
    CodedData.bitpos = 0;
    memset(CodedData.bbuf, 0, sizeof(CodedData.bbuf));

    if((cfg.slot_lag += cfg.frac_per_frame) >= 64)
    {   /* Padding for this frame */
        cfg.slot_lag   -= 64;
        cfg.mpg.padding = 1;
    }
    else
        cfg.mpg.padding = 0;

    cfg.mean_bits = (8 * cfg.byte_per_frame + 8 * cfg.mpg.padding
                       - cfg.sideinfo_len) / cfg.granules / cfg.channels
                       - 42; // reserved for scale_facs

    /* shift out old samples */
    memcpy(mfbuf, mfbuf + 2*cfg.granules*576, 4*512);

    if (chunk->flags & CHUNKF_START_FILE)
    {
        /* prefix silent samples for encoder delay */
        memset(mfbuf + 2*512, 0, ENC_DELAY_SIZE);
        /* read new samples to iram for further processing */
        memcpy(mfbuf + 2*512 + ENC_DELAY_SIZE/2,
               buffer, pcm_chunk_size - ENC_DELAY_SIZE);
        chunk->num_pcm = samp_per_frame - ENC_DELAY_SAMP;
    }
    else
    {
        /* read new samples to iram for further processing */
        memcpy(mfbuf + 2*512, buffer, pcm_chunk_size);
        chunk->num_pcm = samp_per_frame;
    }

    if (cfg.channels == 1)
        to_mono_mm();

    cfg.ResvSize = 0;
    gr_cnt = cfg.granules * cfg.channels;
    CodedData.bitpos = cfg.sideinfo_len; /* leave space for mp3 header */

    for(gr=0; gr<cfg.granules; gr++)
    {
        short *wk = mfbuf + 2*286 + gr*1152;
        int ch;

        /* 16bit packed wav data can be windowed efficiently on coldfire */
        window_subband1(wk, sb_data[0][1-gr][0], sb_data[1][1-gr][0]);

        for(ch=0; ch<cfg.channels; ch++)
        {
            int   ii, k, shift;

            wk = mfbuf + 2*286 + gr*1152 + ch;

            /* 36864=4*18*16*32 */
            for(k=0; k<18; k++, wk+=64)
            {
                window_subband2(wk, sb_data[ch][1-gr][k]);
                /* Compensate for inversion in the analysis filter */
                if(k & 1)
                {
                    int band;
                    for(band=1; band<32; band+=2)
                        sb_data[ch][1-gr][k][band] *= -1;
                }
            }

            /* Perform imdct of 18 previous + 18 current subband samples */
            /* for integer precision do this loop again (if neccessary)  */
            shift = 14 - (cfg.cod_info[gr][ch].additStep >> 2);
            for(k=1,ii=0; ii<3 && k; ii++)
            {
                int *mdct = mdct_freq;
                int band;

                cfg.cod_info[gr][ch].additStep = 4 * (14 - shift);

                for(band=0; band<cfg.mpg.num_bands; band++, mdct+=18)
                {
                    int *band0 = sb_data[ch][  gr][0] + order[band];
                    int *band1 = sb_data[ch][1-gr][0] + order[band];
                    int work[18];

                    /* 9216=4*32*9*8 */
                    for(k=-9; k<0; k++)
                    {
                        int a = shft_n(band1[(k+9)*32], shift);
                        int b = shft_n(band1[(8-k)*32], shift);
                        int c = shft_n(band0[(k+9)*32], shift);
                        int d = shft_n(band0[(8-k)*32], shift);

                        work[k+ 9] = shft16(a * win[k+ 9][0] +
                                            b * win[k+ 9][1] +
                                            c * win[k+ 9][2] +
                                            d * win[k+ 9][3]);

                        work[k+18] = shft16(c * win[k+18][0] +
                                            d * win[k+18][1] +
                                            a * win[k+18][2] +
                                            b * win[k+18][3]);
                    }

                    /* 7200=4*18*100 */
                    mdct_long(mdct, work);

                    /* Perform aliasing reduction butterfly */
                    if(band != 0)
                    {
                        for(k=7; k>=0; --k)
                        {
                            int bu, bd;
                            bu = shft15(mdct[k]) * ca[k] +
                                 shft15(mdct[-1-k]) * cs[k];
                            bd = shft15(mdct[k]) * cs[k] -
                                 shft15(mdct[-1-k]) * ca[k];
                            mdct[-1-k] = bu;
                            mdct[ k  ] = bd;
                        }
                    }
                }

                max = 0;
                for(k=0; k<576; k++)
                {
                    if(mdct_freq[k] < 0)
                    {
                        mdct_sign[k] = 1; /* negative */
                        mdct_freq[k] = shft13(-mdct_freq[k]);
                    }
                    else
                    {
                        mdct_sign[k] = 0; /* positive */
                        mdct_freq[k] = shft13(mdct_freq[k]);
                    }

                    if(max < (uint32_t)mdct_freq[k])
                        max = (uint32_t)mdct_freq[k];
                }
                cfg.cod_info[gr][ch].max_val = max;

                /* calc new shift for higher integer precision */
                for(k=0; max<(uint32_t)(0x7800>>k); k++) shift--;
                for( ; (max>>k)>=(uint32_t)0x10000; k++) shift++;
                if(shift < 0)  shift = 0;
            }

            cfg.cod_info[gr][ch].quantStep +=
                                cfg.cod_info[gr][ch].additStep;

            set_scale_facs(mdct_freq);

            /* bit and noise allocation */
            iteration_loop(mdct_freq, &cfg.cod_info[gr][ch],
                           gr_cnt--);
            /* write the frame to the bitstream */
            Huffmancodebits(enc_data, mdct_sign,
                            &cfg.cod_info[gr][ch]);

            cfg.cod_info[gr][ch].quantStep -=
                                cfg.cod_info[gr][ch].additStep;

            if(cfg.granules == 1)
            {
                memcpy(sb_data[ch][0], sb_data[ch][1],
                       sizeof(sb_data[ch][0]));
            }
        }
    }

    chunk->enc_size = cfg.byte_per_frame + cfg.mpg.padding;

    /* finish this chunk by adding sideinfo header data */
    CodedData.bitpos = 0;
    encodeSideInfo( cfg.cod_info );

#ifdef ROCKBOX_BIG_ENDIAN
    /* copy chunk to enc_buffer */
    memcpy(chunk->enc_data, CodedData.bbuf, chunk->enc_size);
#else
    /* swap frame to big endian */
    byte_swap_frame32((uint32_t *)chunk->enc_data, CodedData.bbuf, chunk->enc_size);
#endif
} /* encode_frame */

/* called very often - inline */
static inline bool is_file_data_ok(struct enc_file_event_data *filed) ICODE_ATTR;
static inline bool is_file_data_ok(struct enc_file_event_data *filed)
{
    return filed->rec_file >= 0 && (long)filed->chunk->flags >= 0;
} /* is_event_ok */

static unsigned char mp3_data[16384] __attribute__((aligned(4)));
static unsigned int  mp3_data_len; /* current data size in buffer */

/* called very often - inline */
static inline bool on_write_chunk(struct enc_file_event_data *data) ICODE_ATTR;
static inline bool on_write_chunk(struct enc_file_event_data *data)
{
    if (!is_file_data_ok(data))
        return false;

    if (data->chunk->enc_data == NULL)
    {
#ifdef ROCKBOX_HAS_LOGF
        ci->logf("mp3 enc: NULL data");
#endif
        return true;
    }

    /* if current chunk doesn't fit => write collected data */
    if (mp3_data_len + data->chunk->enc_size > sizeof(mp3_data))
    {
        if (ci->write(data->rec_file, mp3_data,
                    mp3_data_len) != (ssize_t)mp3_data_len)
            return false;

        mp3_data_len = 0;
    }

    memcpy(mp3_data+mp3_data_len, data->chunk->enc_data,
           data->chunk->enc_size);

    mp3_data_len += data->chunk->enc_size;

    data->num_pcm_samples += data->chunk->num_pcm;
    return true;
} /* on_write_chunk */

static bool on_start_file(struct enc_file_event_data *data)
{
    if ((data->chunk->flags & CHUNKF_ERROR) || *data->filename == '\0')
        return false;

    data->rec_file = ci->open(data->filename, O_RDWR|O_CREAT|O_TRUNC, 0666);

    if (data->rec_file < 0)
        return false;

    /* reset sample count */
    data->num_pcm_samples = 0;

    /* reset buffer write position */
    mp3_data_len = 0;

    return true;
} /* on_start_file */

static bool on_end_file(struct enc_file_event_data *data)
{
    if (data->rec_file < 0)
        return false; /* file already closed, nothing more we can do */

    /* write the remaining mp3_data */
    if (ci->write(data->rec_file, mp3_data, mp3_data_len)
                   != (ssize_t)mp3_data_len)
        return false;

    /* reset buffer write position */
    mp3_data_len = 0;

    /* always _try_ to write the file header, even on error */
    if (ci->close(data->rec_file) != 0)
        return false;

    data->rec_file = -1;

    return true;
} /* on_end_file */

static void on_rec_new_stream(struct enc_buffer_event_data *data)
{
    int num_frames = cfg.mpg.type == 1 ?
        ENC_PADDING_FRAMES1 : ENC_PADDING_FRAMES2;

    if (data->flags & CHUNKF_END_FILE)
    {
        /* add silent frames to end - encoder will also be flushed for start
           of next file if any */
        memset(res_buffer, 0, pcm_chunk_size);

        /* the initial chunk given for the end is at enc_wr_index */
        while (num_frames-- > 0)
        {
            data->chunk->enc_data = ENC_CHUNK_SKIP_HDR(data->chunk->enc_data,
                                                       data->chunk);

            encode_frame(res_buffer, data->chunk);
            data->chunk->num_pcm = samp_per_frame;

            ci->enc_finish_chunk();
            data->chunk = ci->enc_get_chunk();
        }
    }
    else if (data->flags & CHUNKF_PRERECORD)
    {
        /* nothing to add and we cannot change prerecorded data */
    }
    else if (data->flags & CHUNKF_START_FILE)
    {
        /* starting fresh ... be sure to flush encoder first */
        struct enc_chunk_hdr *chunk = ENC_CHUNK_HDR(res_buffer);

        chunk->flags    = 0;
        chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);

        while (num_frames-- > 0)
        {
            memset(chunk->enc_data, 0, pcm_chunk_size);
            encode_frame(chunk->enc_data, chunk);
        }
    }
} /* on_rec_new_stream */

STATICIRAM void enc_events_callback(enum enc_events event, void *data)
                                    ICODE_ATTR;
STATICIRAM void enc_events_callback(enum enc_events event, void *data)
{
    switch (event)
    {
    case ENC_WRITE_CHUNK:
        if (on_write_chunk((struct enc_file_event_data *)data))
            return;

        break;

    case ENC_START_FILE:
        if (on_start_file((struct enc_file_event_data *)data))
            return;

        break;
 
    case ENC_END_FILE:
         if (on_end_file((struct enc_file_event_data *)data))
            return;

         break;

    case ENC_REC_NEW_STREAM:
        on_rec_new_stream((struct enc_buffer_event_data *)data);
        return;

    default:
        return;
    }

    /* Something failed above. Signal error back to core. */
    ((struct enc_file_event_data *)data)->chunk->flags |= CHUNKF_ERROR;
} /* enc_events_callback */

static bool enc_init(void)
{
    struct enc_inputs     inputs;
    struct enc_parameters params;

    if (ci->enc_get_inputs         == NULL ||
        ci->enc_set_parameters     == NULL ||
        ci->enc_get_chunk          == NULL ||
        ci->enc_finish_chunk       == NULL ||
        ci->enc_get_pcm_data       == NULL ||
        ci->enc_unget_pcm_data     == NULL )
        return false;

    ci->enc_get_inputs(&inputs);

    if (inputs.config->afmt != AFMT_MPA_L3)
        return false;