--- /dev/null
+/*
+ (c) Copyright 1998-2001 - Tord Jansson
+ ======================================
+
+ This file is part of the BladeEnc MP3 Encoder, based on
+ ISO's reference code for MPEG Layer 3 compression, and might
+ contain smaller or larger sections that are directly taken
+ from ISO's reference code.
+
+ All changes to the ISO reference code herein are either
+ copyrighted by Tord Jansson (tord.jansson@swipnet.se)
+ or sublicensed to Tord Jansson by a third party.
+
+ BladeEnc is free software; you can redistribute this file
+ and/or modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+
+
+ ------------ Changes ------------
+
+ 2000-11-10 Andre Piotrowski
+
+ - reformatted, used 'static' functions, global variables, less parameters
+
+ 2000-11-11 ap
+
+ - a lot of functions redesigned to let the bladetable become superfluous:
+ genNoisePowTab(), iteration_loop(), calc_noise(), preemphasis(), amp_scalefac_bands()
+ - bladTabValue() replaced by cutting_crew()
+
+ 2000-11-22 ap
+
+ - bug fix: module - reset fInit_huffman_read_flag
+
+ 2000-11-28 ap
+ - speed up : implemented partial quantizing
+
+ 2000-11-30 ap
+ - speed up : implemented faster Huffman coding
+ - integration : improved (optional) Huffman coding
+ [choosing better tables]
+ - integration : improved (optional) binary search
+ [in fact, this is a BUG FIX (original dist10 bug)]
+
+ 2000-12-02 ap
+ - bug fix : original dist10's outer_loop could cause an endless loop (huff_bits <= 0).
+ - speed up : faster part2_length/scale_bitcount calculation
+ - integration : improved (optional) scalefactor compression
+ [smart preflag switching and choosing best compression]
+
+ 2000-12-03 ap
+ - integration : improved (optional) quantanf algorithm
+ [calculating exact quantizer step boundaries]
+ - integration : improved (optional) preemphasing/amplifying algorithm
+ [preemphase only if iteration==1, according to ISO]
+ - integration : improved (optional) outer_loop algorithm
+ [amplify the bands, marked as "should be amplified"]
+
+ 2000-12-10 ap
+ - definitely killed SCFSI
+
+ 2001-01-12 ap
+
+ - use some explicit type casting to avoid compiler warnings
+ - clear some backward compatability flags for 0.93.10
+
+ 2001-04-07 ap
+ - implemented flag CHECK_TJ_OVERFLOW to check for huffman table overflow
+*/
+
+
+
+
+
+/* ======================================================================================== */
+/* keeping backward compatability */
+/* ======================================================================================== */
+
+#define ORG_HUFFMAN_CODING 0 /* 0 = use better Huffman tables for shorter code */
+#define ORG_BINARY_SEARCH 0 /* 0 = use a correct implemented binary search */
+#define ORG_QUANTANF_INIT 0 /* 0 = use better quantization start value */
+#define ORG_PREEMPHASING 0 /* 0 = use a more ISO-like preemphasing algorithm */
+#define ORG_SCF_COMPRESS 0 /* 0 = choose better scalefactor compression tables and smart preemphasing */
+#define ORG_OUTER_LOOP 0 /* 0 = differ between marked as "been amplified" and "should be amplified" */
+#define ORG_HIGHEST_SFB 1 /* 0 = cut off highest frequencies (in last scale factor band) */
+
+#define CHECK_TJ_OVERFLOW 1 /* 1 = check for huffman table overflow */
+
+
+
+
+
+#define infinity 99999999
+
+
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+
+#include "system.h"
+#include "common.h"
+
+#include "l3side.h"
+#include "l3psy.h"
+#include "huffman.h"
+#include "l3bitstream.h"
+#include "reservoir.h"
+#include "loop.h"
+#include "loop-pvt.h"
+
+
+
+
+
+#if ORG_HUFFMAN_CODING
+static void tiny_single_Huffman_2 /* Escape tables */
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 15... */
+ unsigned *choice,
+ unsigned *sum
+);
+#endif
+
+
+
+static int amplify_short (void);
+static int amplify_long
+(
+ int iteration
+);
+
+
+
+
+
+int my_nint (double in)
+{
+
+ if (in < 0)
+ return (int)(in - 0.5);
+ else
+ return (int)(in + 0.5);
+}
+
+
+
+
+
+/*
+ Here are MPEG1 Table B.8 and MPEG2 Table B.1
+ -- Layer III scalefactor bands.
+ Index into this using a method such as:
+ idx = fr_ps->header->sampling_frequency
+ + (fr_ps->header->version * 3)
+*/
+
+struct scalefac_struct sfBandIndex[3] =
+{
+ { /* 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},
+ {0,4,8,12,16,22,30,40,52,66,84,106,136,192}
+ },
+ { /* 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},
+ {0,4,8,12,16,22,28,38,50,64,80,100,126,192}
+ },
+ { /* 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},
+ {0,4,8,12,16,22,30,42,58,78,104,138,180,192}
+ }
+};
+
+
+
+/*
+ The following table is used to implement the scalefactor
+ partitioning for MPEG2 as described in section
+ 2.4.3.2 of the IS. The indexing corresponds to the
+ way the tables are presented in the IS:
+
+ [table_number][row_in_table][column of nr_of_sfb]
+*/
+
+static unsigned nr_of_sfb_block[6][3][4] =
+{
+ {
+ { 6, 5, 5, 5},
+ { 9, 9, 9, 9},
+ { 6, 9, 9, 9}
+ },
+ {
+ {6, 5, 7, 3},
+ {9, 9, 12, 6},
+ {6, 9, 12, 6}
+ },
+ {
+ {11,10, 0, 0},
+ {18,18, 0, 0},
+ {15,18, 0, 0}
+ },
+ {
+ { 7, 7, 7, 0},
+ {12,12,12, 0},
+ { 6,15,12, 0}
+ },
+ {
+ { 6, 6, 6, 3},
+ {12, 9, 9, 6},
+ { 6,12, 9, 6}
+ },
+ {
+ { 8, 8, 5, 0},
+ {15,12, 9, 0},
+ { 6,18, 9, 0}
+ }
+};
+
+
+
+/* Table B.6: layer3 preemphasis */
+int pretab[21] =
+{
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1,
+ 1, 2, 2, 3, 3, 3, 2
+};
+
+
+
+/* This is the scfsi_band table from 2.4.2.7 of the IS */
+int scfsi_band_long[5] = { 0, 6, 11, 16, 21 };
+
+
+
+int *scalefac_band_long;
+int *scalefac_band_short;
+
+int fInit_iteration_loop;
+
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+int tjBitOverflow2;
+#endif
+
+
+/* We need this initialization here since some compilers chokes on the
+ the declaration if it constains an initialization that point directly
+ into a struct.
+*/
+
+void fixStatic_loop( void )
+{
+ scalefac_band_long = &sfBandIndex[0].l[0];
+ scalefac_band_short = &sfBandIndex[0].s[0];
+}
+
+
+
+
+
+/* ======================================================================== */
+/* generating the power tables */
+/* ======================================================================== */
+
+
+
+#define BOT 200
+#define POW216_MAX (BOT/2 * 16)
+#define POW216_MIN (-25 * 16)
+
+
+
+static double pow216_space[POW216_MAX-POW216_MIN+1];
+static double *pow216 = pow216_space - POW216_MIN;
+static double noisePowTab[8191+15];
+
+
+
+void genNoisePowTab (void)
+{
+ int i;
+
+ for (i = POW216_MIN; i <= POW216_MAX; i++)
+ pow216[i] = pow (2.0, (double)i/16.0);
+
+ for (i = 0; i < 8191+15; i++)
+ noisePowTab[i] = pow (i, 4.0/3.0);
+}
+
+
+
+
+
+/* ======================================================================== */
+/* static variables */
+/* ======================================================================== */
+
+
+
+static int gr; /* the current granule */
+static int ch; /* the current channel */
+
+
+
+static III_side_info_t *side_info; /* the current side information */
+static gr_info *cod_info; /* the current coding information */
+
+
+
+static double *xr_org_l; /* the initial magnitudes of the spectral values */
+static double xr34_l[576]; /* the magnitudes powered by 3/4 */
+static int *ix_l; /* quantized values */
+
+static double energy_l[SFB_LMAX];
+static double xmin_l[SFB_LMAX]; /* the allowed distortion of the scalefactor band */
+static double xfsf_l[SFB_LMAX]; /* the current distortion of the scalefactor band */
+static int expo16_l[SFB_LMAX]; /* sixteen times the scale factor band exponent */
+static int *scalefac_l; /* the current scale factors */
+static int *scalefac_0_l; /* scale factors for first granule */
+
+static double (*xr_org_s)[3]; /* some short block versions */
+static double (*xr34_s)[3] = (double (*)[3]) xr34_l;
+static int (*ix_s)[3];
+
+static double energy_s[SFB_SMAX][3];
+static double xmin_s[SFB_SMAX][3];
+static double xfsf_s[SFB_SMAX][3];
+static int expo16_s[SFB_SMAX][3];
+static int (*scalefac_s)[3];
+
+
+
+static int max_used_sfb_l;
+static int min_used_sfb_s;
+
+static int end_sfb_l;
+static int end_sfb_s;
+
+
+
+static double xmax_l[SFB_LMAX]; /* The initial (absolute) maximum magnitude */
+static int xmax_line_l[SFB_LMAX]; /* of the long bands and their line indices */
+
+static double xmax_s[SFB_SMAX][3]; /* Guess ... */
+static int xmax_line_s[SFB_SMAX][3];
+
+
+
+static int mark_idx_l; /* speed up - partial quantizing */
+static int mark_tab_l[SFB_LMAX]; /* changed sfb-s */
+
+static int mark_idx_s;
+static int mark_tab_s[SFB_SMAX*3*2]; /* changed (sfb,b)-s */
+
+
+
+#if !ORG_QUANTANF_INIT
+
+static int lo_quant_l [SFB_LMAX];
+static int hi_quant_l [SBMAX_l];
+
+static int lo_quant_s [SFB_SMAX][3];
+static int hi_quant_s [SFB_SMAX][3];
+
+static int the_lo_quant;
+static int the_hi_quant;
+
+static double log_2, cc, dd;
+
+#endif
+
+
+
+
+
+/* ======================================================================== */
+/* iteration_loop */
+/* ======================================================================== */
+
+void iteration_loop
+(
+ double pe[][2],
+ double xr_org[2][2][576],
+ III_psy_ratio *ratio,
+ III_side_info_t *l3_side,
+ int l3_enc[2][2][576],
+ int mean_bits,
+ int stereo,
+ double xr_dec[2][2][576],
+ III_scalefac_t *scalefac,
+ frame_params *fr_ps,
+ int ancillary_pad,
+ int bitsPerFrame
+)
+{
+ int max_bits;
+ int i, sfb, b, scfsi_band;
+ int mode_gr;
+
+ int *main_data_begin;
+ layer *info;
+
+ int start, end;
+
+#if ORG_QUANTANF_INIT
+ double log_sum;
+#endif
+ double total_energy, temp, x;
+
+
+
+ side_info = l3_side;
+
+ main_data_begin = &side_info->main_data_begin;
+ info = fr_ps->header;
+
+
+ side_info->resvDrain = 0;
+
+ if (!fInit_iteration_loop)
+ {
+ *main_data_begin = 0;
+ fInit_iteration_loop = 1;
+
+#if !ORG_QUANTANF_INIT
+ log_2 = log(2.0);
+ cc = 4.0/3.0 * log(8205.0 - 0.5 + 0.0946) / log_2;
+ dd = 4.0/3.0 * log( 1.0 - 0.5 + 0.0946) / log_2;
+#endif
+ }
+ mode_gr = 2;
+
+ scalefac_band_long = &sfBandIndex[info->sampling_frequency].l[0];
+ scalefac_band_short = &sfBandIndex[info->sampling_frequency].s[0];
+
+
+ ResvFrameBegin (fr_ps, side_info, mean_bits, bitsPerFrame);
+
+ for (gr = 0; gr < mode_gr; gr++)
+ {
+ for (ch = 0; ch < stereo; ch++)
+ {
+ xr_org_l = xr_org[gr][ch];
+ xr_org_s = (double (*)[3]) xr_org_l;
+
+ ix_l = l3_enc[gr][ch];
+ ix_s = (int (*)[3]) ix_l;
+
+ cod_info = &side_info->gr[gr].ch[ch].tt;
+
+ scalefac_l = scalefac->l[gr][ch]; scalefac_0_l = scalefac->l[0][ch];
+ scalefac_s = scalefac->s[gr][ch];
+
+
+
+ /* reset of iteration variables */
+
+ for (scfsi_band = 0; scfsi_band < 4; scfsi_band++)
+ cod_info->slen[scfsi_band] = 0;
+
+ cod_info->sfb_partition_table = &nr_of_sfb_block[0][0][0];
+ cod_info->part2_3_length = 0;
+ cod_info->big_values = 0;
+ cod_info->count1 = 0;
+ cod_info->scalefac_compress = 0;
+ cod_info->table_select[0] = 0;
+ cod_info->table_select[1] = 0;
+ cod_info->table_select[2] = 0;
+ cod_info->subblock_gain[0] = 0;
+ cod_info->subblock_gain[1] = 0;
+ cod_info->subblock_gain[2] = 0;
+ cod_info->region0_count = 0;
+ cod_info->region1_count = 0;
+ cod_info->part2_length = 0;
+ cod_info->preflag = 0;
+ cod_info->scalefac_scale = 0;
+ cod_info->quantizerStepSize = 0.0;
+ cod_info->count1table_select = 0;
+
+
+
+/* ======== gr_deco ======== */
+
+ if (cod_info->window_switching_flag && (cod_info->block_type == SHORT_TYPE))
+ {
+ if (cod_info->mixed_block_flag)
+ {
+ /*
+ In mixed blocks there come first 8 long scale factor band areas covering
+ the place normally used by the first 3 short scale factor band areas.
+ */
+ max_used_sfb_l = cod_info->sfb_lmax = 8;
+ min_used_sfb_s = cod_info->sfb_smax = 3;
+
+ /* The following values don«t need to be set again and again ... */
+ cod_info->region0_count = 7; /* scalefac_band_long[7+1 ] = 36 */
+ cod_info->region1_count = 13; /* scalefac_band_long[7+13+2] = 576 (no region2) */
+ }
+ else
+ {
+ max_used_sfb_l = cod_info->sfb_lmax = 0; /* No long blocks */
+ min_used_sfb_s = cod_info->sfb_smax = 0;
+
+ /* The following values don«t need to be set again and again ... */
+ cod_info->region0_count = 8; /* scalefac_band_short[(8+1 )/3] = 12 ( 12*3 = 36) */
+ cod_info->region1_count = 36; /* 36? should be 29: scalefac_band_short[(8+29+2)/3] = 192 (192*3 = 576) */
+ /* probably meant : scalefac_band_short[36/3 + 1 ] = 192 (192*3 = 576) */
+ /* 2000-02-27 AP no effect on output because block_type != NORM_TYPE */
+ }
+
+ /* to access the entire array we need the last scalefac_band_short area */
+ end_sfb_l = max_used_sfb_l; /*cod_info->sfb_lmax;*/
+ end_sfb_s = SFB_SMAX;
+
+ /* The following values don«t need to be set again and again ... */
+ cod_info->count1 = 0; /* (zero_region-bigv_region) / 4; */
+ cod_info->big_values = 288; /* bigv_region / 2; */
+
+ cod_info->count1table_select = 1; /* sum0 == sum1 == 0 */
+
+ cod_info->address1 = 36; /* choose one of the region0_count formulas above */
+ cod_info->address2 = 576; /* bigv_region; */
+ cod_info->address3 = 0;
+ }
+ else
+ {
+ max_used_sfb_l = cod_info->sfb_lmax = SBMAX_l;
+ min_used_sfb_s = cod_info->sfb_smax = SBMAX_s; /* No short blocks */
+
+ /* to access the entire array we need the last scalefac_band_long area */
+ end_sfb_l = SFB_LMAX;
+ end_sfb_s = min_used_sfb_s; /*cod_info->sfb_smax;*/
+ }
+
+
+ /* reset of iteration variables */
+
+ for (sfb = 0; sfb < max_used_sfb_l/*SFB_LMAX-1*/; sfb++)
+ scalefac_l[sfb] = 0;
+ for (sfb = min_used_sfb_s/*0*/; sfb < SFB_SMAX-1; sfb++)
+ for (b = 0; b < 3; b++)
+ scalefac_s[sfb][b] = 0;
+
+/* ======== calc_xmin and start of quantanf_init ======== */
+/*
+ Calculate the allowed distortion for each scalefactor band,
+ as determined by the psychoacoustic model.
+ xmin(sb) = ratio(sb) * energy(sb) / bandwidth(sb)
+*/
+
+#if ORG_QUANTANF_INIT
+ log_sum = 0.0;
+#endif
+ total_energy = 0.0;
+
+ for (sfb = 0; sfb < end_sfb_l; sfb++)
+ {
+ start = scalefac_band_long[sfb];
+ end = scalefac_band_long[sfb+1];
+
+ expo16_l[sfb] = 0;
+
+ xmax_l[sfb] = 0.0;
+ xmax_line_l[sfb] = start;
+
+ temp = 0.0;
+#if !ORG_HIGHEST_SFB
+ if (sfb < max_used_sfb_l)
+ {
+#endif
+ for (i = start; i < end; i++)
+ {
+ if ((x = fabs(xr_org_l[i])) != 0.0)
+ {
+ xr34_l[i] = sqrt(x * sqrt(x));
+ temp += x*x;
+# if ORG_QUANTANF_INIT
+ log_sum += log(x);
+# endif
+ if (x > xmax_l[sfb])
+ {
+ xmax_l[sfb] = x;
+ xmax_line_l[sfb] = i;
+ }
+ }
+ else
+ xr34_l[i] = 0.0;
+ }
+#if !ORG_HIGHEST_SFB
+ }
+ else /* cut off the (highest frequency) entries in the unused scale factor band */
+ {
+ for (i = start; i < end; i++)
+ xr34_l[i] = 0.0;
+ }
+#endif
+ total_energy += energy_l[sfb] = temp;
+
+ if (sfb < max_used_sfb_l)
+ xmin_l[sfb] = ratio->l[gr][ch][sfb] * temp;
+ }
+
+ for (sfb = min_used_sfb_s; sfb < end_sfb_s; sfb++)
+ {
+ start = scalefac_band_short[sfb];
+ end = scalefac_band_short[sfb+1];
+
+ for (b = 0; b < 3; b++)
+ {
+ expo16_s[sfb][b] = 0;
+
+ xmax_s[sfb][b] = 0.0;
+ xmax_line_s[sfb][b] = start;
+
+ temp = 0.0;
+#if !ORG_HIGHEST_SFB
+ if (sfb < SBMAX_s)
+ {
+#endif
+ for (i = start; i < end; i++)
+ {
+ if ((x = fabs(xr_org_s[i][b])) != 0.0)
+ {
+ xr34_s[i][b] = sqrt(x * sqrt(x));
+ temp += x*x;
+#if ORG_QUANTANF_INIT
+ log_sum += log(x);
+#endif
+ if (x > xmax_s[sfb][b])
+ {
+ xmax_s[sfb][b] = x;
+ xmax_line_s[sfb][b] = i;
+ }
+ }
+ else
+ xr34_s[i][b] = 0.0;
+ }
+#if !ORG_HIGHEST_SFB
+ }
+ else /* cut off the (highest frequency) entries in the unused scale factor band */
+ {
+ for (i = start; i < end; i++)
+ xr34_s[i][b] = 0.0;
+ }
+#endif
+ total_energy += energy_s[sfb][b] = temp;
+
+ if (sfb < SFB_SMAX-1)
+ xmin_s[sfb][b] = ratio->s[gr][ch][sfb][b] * temp;
+ }
+ }
+
+
+/* ======== calc_scfsi ======== */
+
+ /* None of the granules contains short blocks */
+ if (!cod_info->window_switching_flag || (cod_info->block_type != SHORT_TYPE))
+ {
+ if (gr == 1)
+ {
+ for (scfsi_band = 0; scfsi_band < 4; scfsi_band++)
+ side_info->scfsi[ch][scfsi_band] = 0;
+ }
+ }
+
+
+
+ /* calculation of number of available bit( per granule ) */
+ max_bits = ResvMaxBits (fr_ps, side_info, &pe[gr][ch], mean_bits);
+
+
+
+ /* all spectral values zero ? */
+ if (total_energy != 0.0)
+ {
+
+
+
+#if ORG_QUANTANF_INIT
+
+/* ======== quantanf_init (remaining) ======== */
+
+#define system_const 8.0
+#define minlimit -100.0
+
+ temp = my_nint (system_const * (log_sum/288.0 - log(total_energy/576.0)));
+ if (temp < minlimit)
+ temp = minlimit;
+ /*
+ SS 19-12-96. Starting value of
+ global_gain or quantizerStepSize
+ has to be reduced for iteration_loop
+ */
+ temp -= 70.0;
+
+ cod_info->quantizerStepSize = temp;
+
+#else /* ORG_QUANTANF_INIT */
+
+ double xmax, the_xmax;
+
+ the_lo_quant = -infinity; /* "-infinity" */
+ the_hi_quant = -infinity; /* the real maximum for high_quant is about +4 ! */
+
+ the_xmax = -1.0;
+
+ for (sfb = 0; sfb < end_sfb_l; sfb++)
+ {
+ xmax = xmax_l[sfb];
+ if (xmax == 0.0)
+ {
+ lo_quant_l[sfb] = -infinity;
+ hi_quant_l[sfb] = -infinity;
+ }
+ else
+ {
+ lo_quant_l[sfb] = floor (4.0 * (log(xmax)/log_2 - cc)) + 1;
+ hi_quant_l[sfb] = floor (4.0 * (log(xmax)/log_2 - dd)) + 1;
+
+ if (xmax > the_xmax)
+ {
+ the_xmax = xmax;
+ the_lo_quant = lo_quant_l[sfb];
+ the_hi_quant = hi_quant_l[sfb];
+ }
+ }
+ }
+
+ for (sfb = min_used_sfb_s; sfb < end_sfb_s; sfb++)
+ {
+ for (b = 0; b < 3; b++)
+ {
+ xmax = xmax_s[sfb][b];
+ if (xmax == 0.0)
+ {
+ lo_quant_s[sfb][b] = -infinity;
+ hi_quant_s[sfb][b] = -infinity;
+ }
+ else
+ {
+ lo_quant_s[sfb][b] = floor (4.0 * (log(xmax)/log_2 - cc) /* - 8 * cod_info->subblock_gain[b] */) + 1;
+ hi_quant_s[sfb][b] = floor (4.0 * (log(xmax)/log_2 - dd) /* - 8 * cod_info->subblock_gain[b] */) + 1;
+
+ if (xmax > the_xmax)
+ {
+ the_xmax = xmax;
+ the_lo_quant = lo_quant_s[sfb][b];
+ the_hi_quant = hi_quant_s[sfb][b];
+ }
+ }
+ }
+ }
+
+
+ /*
+ Try the power table at its least boundary
+ I«ve never reached this deep before!
+ */
+ assert (the_lo_quant > -POW216_MAX);
+
+ cod_info->quantizerStepSize = the_lo_quant;
+
+#endif /* ORG_QUANTANF_INIT */
+
+
+
+ cod_info->part2_3_length = outer_loop (max_bits, fr_ps);
+ }
+
+ ResvAdjust (fr_ps, cod_info, side_info, mean_bits);
+
+ cod_info->global_gain = my_nint (cod_info->quantizerStepSize + 210.0);
+/* assert (cod_info->global_gain < 256); */
+ } /* for ch */
+ } /* for gr */
+
+ ResvFrameEnd (fr_ps, side_info, mean_bits);
+}
+
+
+
+
+
+/* ======================================================================== */
+/* outer_loop */
+/* ======================================================================== */
+/*
+ The outer iteration loop controls the masking conditions
+ of all scalefactorbands. It computes the best scalefac and
+ global gain. This module calls the inner iteration loop
+*/
+
+static int outer_loop
+(
+ int max_bits,
+ frame_params *fr_ps
+)
+{
+ int scalesave_l[SFB_LMAX-1];
+ int scalesave_s[SFB_SMAX-1][3];
+ int bits, huff_bits, save_preflag, save_compress, save_part2_length;
+ int sfb, b, over, iteration;
+
+
+ /* reset the pointers of our changed sfb [(sfb,b)] indices list */
+ mark_idx_l = mark_idx_s = 0;
+
+
+#if 0
+ cod_info->preflag = 0; /* assignments are all done in iteration_loop() */
+ cod_info->scalefac_compress = 0; /* just to show what«s going on ... */
+ cod_info->part2_length = 0; /* == part2_length(fr_ps) because of slen1_tab[0] = slen2_tab[0] = 0 */
+#endif
+
+ huff_bits = max_bits /* - cod_info->part2_length */; /* try first without scaling */
+
+
+ iteration = 1;
+
+ bits = bin_search_StepSize (max_bits, cod_info->quantizerStepSize); /* speeds things up a bit */
+
+ while (1)
+ {
+ for (sfb = 0; sfb < SFB_LMAX-1; sfb++) /* save scaling factors */
+ scalesave_l[sfb] = scalefac_l[sfb];
+
+ for (sfb = 0; sfb < SFB_SMAX-1; sfb++)
+ for (b = 0; b < 3; b++)
+ scalesave_s[sfb][b] = scalefac_s[sfb][b];
+
+ save_preflag = cod_info->preflag;
+ save_compress = cod_info->scalefac_compress;
+ save_part2_length = cod_info->part2_length;
+
+ calc_noise (); /* distortion calculation */
+
+ over = amplify (iteration);
+
+#if ORG_OUTER_LOOP
+/*
+ misplaced break condition in original dist10:
+ - There is one flag only for both, marking a scalefactor band as
+ "should be amplified" or marking it as "is amplified", namely
+ a corresponding scalefactor greater than zero!
+ - The desired amplification of the scalefactors bands marked as
+ "should be amplified" is actually not done before the next call
+ to quantize(), respectively partial_quantize().
+ - Thus, it can happen that all scalefactor bands are marked, but
+ not all of the marked bands are amplified.
+ - Since loop_break() doesn't know that, the outer loop frequently
+ gets terminated to early.
+*/
+ if (loop_break ())
+ break;
+#endif
+
+ huff_bits = max_bits - needed_bits_for_storing_scalefactors (fr_ps);
+ if (huff_bits < 0)
+ break; /* not enough space to store the scale factors */
+
+
+ /* We have to wait checking this break condition */
+ /* until needed_bits_for_storing_scalefactors() */
+ /* set the scalefac compress index!!! */
+ if (over == 0)
+ break; /* no more bands to amplify */
+
+
+ iteration++;
+
+ /*
+ Most of the times, only a few bands will be changed,
+ so why quantize the whole area?
+ */
+ partial_quantize ();
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+assert (!tjBitOverflow2);
+#endif
+ bits = count_bits();
+
+ while (bits > huff_bits)
+ {
+ cod_info->quantizerStepSize += 1.0;
+ quantize ();
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+assert (!tjBitOverflow2);
+#endif
+ bits = count_bits ();
+ }
+
+#if !ORG_OUTER_LOOP
+ /*
+ A break would mean to restore the parameters of the last iteration,
+ but we like to accept the current state. If you want to avoid the
+ 'goto', you have to to take the long way home and place the loop
+ break condition in front of the call to calc_noise().
+ */
+ if (loop_break())
+ goto take_that_and_party;
+#endif
+ }
+
+
+ cod_info->preflag = save_preflag;
+ cod_info->scalefac_compress = save_compress;
+ cod_info->part2_length = save_part2_length;
+
+ for (sfb = 0; sfb < SFB_LMAX-1; sfb++)
+ scalefac_l[sfb] = scalesave_l[sfb];
+
+ for (sfb = 0; sfb < SFB_SMAX-1; sfb++)
+ for (b = 0; b < 3; b++)
+ scalefac_s[sfb][b] = scalesave_s[sfb][b];
+
+take_that_and_party:
+ cod_info->part2_3_length = cod_info->part2_length + bits;
+
+
+ return cod_info->part2_3_length;
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* needed_bits_for_storing_scalefactors */
+/* ======================================================================================== */
+/*
+ counts the bits needed to code the scale factors (cod_info->part2_length)
+ and the compression index (cod_info->scalefac_compress).
+
+ If there is no suitable index, it returns "infinity".
+*/
+
+static int needed_bits_for_storing_scalefactors
+(
+ frame_params *fr_ps
+)
+{
+#if 0
+ static int slen1[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
+ static int slen2[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };
+#endif
+
+ /* 2^^slen1[k] */
+ static int pow2_slen1[16] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16};
+ /* 2^^slen2[k] */
+ static int pow2_slen2[16] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8};
+
+ /* (8+9) * slen1[k] + (9+9) * slen2[k] */
+ static int part2_len_m[16] = { 0, 18, 36, 54, 51, 35, 53, 71, 52, 70, 88, 69, 87,105,104,122};
+ /* (9+9) * slen1[k] + (9+9) * slen2[k] */
+ static int part2_len_s[16] = { 0, 18, 36, 54, 54, 36, 54, 72, 54, 72, 90, 72, 90,108,108,126};
+ /* (6+5) * slen1[k] + (5+5) * slen2[k] */
+ static int part2_len_l[16] = { 0, 10, 20, 30, 33, 21, 31, 41, 32, 42, 52, 43, 53, 63, 64, 74};
+
+ int sfb, b, k;
+ int max_slen1, max_slen2, *table;
+
+
+ max_slen1 = max_slen2 = 0;
+
+ if (cod_info->window_switching_flag && (cod_info->block_type == SHORT_TYPE))
+ {
+ if (cod_info->mixed_block_flag)
+ {
+ table = part2_len_m;
+
+ for (sfb = 0; sfb < 8; sfb++)
+ if (scalefac_l[sfb] > max_slen1)
+ max_slen1 = scalefac_l[sfb];
+
+ for (sfb = 3; sfb < 6; sfb++)
+ for (b = 0; b < 3; b++)
+ if (scalefac_s[sfb][b] > max_slen1)
+ max_slen1 = scalefac_s[sfb][b];
+ }
+ else
+ {
+ table = part2_len_s;
+
+ for (sfb = 0; sfb < 6; sfb++)
+ for (b = 0; b < 3; b++)
+ if (scalefac_s[sfb][b] > max_slen1)
+ max_slen1 = scalefac_s[sfb][b];
+ }
+
+ for (sfb = 6; sfb < 12/*SBMAX_s*/; sfb++)
+ for (b = 0; b < 3; b++)
+ if (scalefac_s[sfb][b] > max_slen2)
+ max_slen2 = scalefac_s[sfb][b];
+ }
+ else
+ {
+ table = part2_len_l;
+
+ for (sfb = 0; sfb < 11; sfb++)
+ if (scalefac_l[sfb] > max_slen1)
+ max_slen1 = scalefac_l[sfb];
+
+
+#if ORG_SCF_COMPRESS && !ORG_PREEMPHASING
+ /* This was seen in LAME */
+ if (!cod_info->preflag)
+ {
+ for (sfb = 11; sfb < SBMAX_l; sfb++)
+ if (scalefac_l[sfb] < (1 + cod_info->scalefac_scale) * pretab[sfb])
+ break;
+
+ if (sfb == SBMAX_l)
+ {
+ for (sfb = 11; sfb < SBMAX_l; sfb++)
+ scalefac_l[sfb] -= (1 + cod_info->scalefac_scale) * pretab[sfb];
+ cod_info->preflag = 1;
+ }
+ }
+#endif
+
+
+ for (sfb = 11; sfb < 21/*SBMAX_l*/; sfb++)
+ if (scalefac_l[sfb] > max_slen2)
+ max_slen2 = scalefac_l[sfb];
+ }
+
+
+ cod_info->part2_length = infinity;
+
+ for (k = 0; k < 16; k++)
+ {
+ if (max_slen1 < pow2_slen1[k] && max_slen2 < pow2_slen2[k])
+ {
+#if ORG_SCF_COMPRESS
+ cod_info->scalefac_compress = k;
+ cod_info->part2_length = table[k];
+ break;
+#else
+ if (cod_info->part2_length > table[k])
+ {
+ cod_info->scalefac_compress = k;
+ cod_info->part2_length = table[k];
+ }
+#endif
+ }
+ }
+
+
+ return cod_info->part2_length;
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* calc_noise */
+/* ======================================================================================== */
+/*
+ calculates the distortion introduced by the qunatization
+ in each scale factor band.
+*/
+static void calc_noise (void)
+{
+ int i, b, sfb, start, end, off;
+ double f, sum, temp;
+
+
+ off = -4 * (int)cod_info->quantizerStepSize;
+
+
+ for (sfb = 0; sfb < max_used_sfb_l; sfb++)
+ {
+ if (ix_l[xmax_line_l[sfb]] == 0) /* quantized values all zero? */
+ {
+ xfsf_l[sfb] = energy_l[sfb]; /* see calculation of xmin_l */
+ }
+ else
+ {
+ start = scalefac_band_long[sfb];
+ end = scalefac_band_long[sfb+1];
+
+ sum = 0.0;
+
+ f = pow216[expo16_l[sfb] + off];
+
+ for (i = start; i < end; i++)
+ {
+ temp = fabs(xr_org_l[i]) - noisePowTab[ix_l[i]] / f;
+ sum += temp * temp;
+ }
+
+ xfsf_l[sfb] = sum;
+ }
+ }
+
+ for (b = 0; b < 3; b++)
+ {
+ off = -4 * ((int)cod_info->quantizerStepSize + 8 * cod_info->subblock_gain[b]);
+
+ for (sfb = min_used_sfb_s; sfb < SFB_SMAX-1; sfb++)
+ {
+ if (ix_s[xmax_line_s[sfb][b]] == 0) /* quantized values all zero? */
+ {
+ xfsf_s[sfb][b] = energy_s[sfb][b]; /* see calculation of xmin_s */
+ }
+ else
+ {
+ start = scalefac_band_short[sfb];
+ end = scalefac_band_short[sfb+1];
+
+ sum = 0.0;
+
+ f = pow216[expo16_s[sfb][b] + off];
+
+ for (i = start; i < end; i++)
+ {
+ temp = fabs(xr_org_s[i][b]) - noisePowTab[ix_s[i][b]] / f;
+ sum += temp * temp;
+ }
+
+ xfsf_s[sfb][b] = sum;
+ }
+ }
+ }
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* loop_break */
+/* ======================================================================================== */
+/*
+ returns zero if there is a scalefac which has not been amplified.
+ Otherwise it returns one.
+*/
+
+static int loop_break (void)
+{
+ int sfb, b;
+
+ for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++)
+ if (scalefac_l[sfb] == 0)
+ return 0;
+
+ for (sfb = min_used_sfb_s; sfb < 12; sfb++)
+ for (b = 0; b < 3; b++)
+ if (scalefac_s[sfb][b] == 0)
+ return 0;
+
+ return 1;
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* preemphasing and amplifying */
+/* ======================================================================================== */
+/*
+ Preemphasing: see ISO 11172-3 section C.1.5.4.3.4
+ Amplifying : see ISO 11172-3 section C.1.5.4.3.5
+
+ amplifying the scalefactor bands that violate the masking threshold.
+*/
+
+static int amplify
+(
+ int iteration
+)
+{
+ if (cod_info->window_switching_flag && cod_info->block_type == SHORT_TYPE)
+ return amplify_short ();
+ else
+ return amplify_long (iteration);
+}
+
+
+
+
+
+static int amplify_short (void)
+{
+ int sfb, b, over, expo16_off;
+
+ expo16_off = 16 * (1 + cod_info->scalefac_scale) / 2;
+ over = 0;
+
+#ifdef MIXED_BLOCKS
+ for (sfb = 0; sfb < max_used_sfb_l; sfb++)
+ {
+ if (xfsf_l[sfb] > xmin_l[sfb])
+ {
+ scalefac_l[sfb]++;
+ expo16_l[sfb] += expo16_off;
+ over++;
+ mark_tab_l[mark_idx_l++] = sfb;
+ }
+ }
+#endif
+
+ for (sfb = min_used_sfb_s; sfb < SBMAX_s; sfb++)
+ {
+ for (b = 0; b < 3; b++)
+ {
+ if (xfsf_s[sfb][b] > xmin_s[sfb][b])
+ {
+ scalefac_s[sfb][b]++;
+ expo16_s[sfb][b] += expo16_off;
+ over++;
+ mark_tab_s[mark_idx_s++] = sfb;
+ mark_tab_s[mark_idx_s++] = b;
+ }
+ }
+ }
+
+ return over;
+}
+
+
+
+
+
+static int amplify_long
+(
+ int iteration
+)
+{
+ int pre_expo_off[SFB_LMAX];
+
+ int sfb, stop_at, over = 0;
+ int expo16_off;
+
+
+ stop_at = max_used_sfb_l;
+
+ expo16_off = 16 * (1 + cod_info->scalefac_scale) / 2;
+
+
+ /*
+ Preemphasis is switched on if in all the upper four scalefactor
+ bands the actual distortion exceeds the threshold after the
+ first call of the inner loop.
+
+ Original bug of dist10 - preemphasis() didn't know 'iteration'!!!
+ */
+#if !ORG_PREEMPHASING
+ if (iteration == 1)
+#endif
+ if (!cod_info->preflag)
+ {
+ for (sfb = max_used_sfb_l-4; sfb < max_used_sfb_l; sfb++)
+ if (xfsf_l[sfb] <= xmin_l[sfb])
+ goto no_preemphasing;
+
+ cod_info->preflag = 1;
+
+ stop_at = 11; /* pretab[sfb] = 0 for sfb = 0..10 */
+
+ for (sfb = stop_at; sfb < max_used_sfb_l; sfb++)
+ {
+ expo16_l[sfb] += pre_expo_off[sfb] = expo16_off * pretab[sfb];
+
+ mark_tab_l[mark_idx_l++] = sfb;
+ }
+ }
+
+
+no_preemphasing:
+
+
+ for (sfb = 0; sfb < stop_at; sfb++)
+ {
+ if (xfsf_l[sfb] > xmin_l[sfb])
+ {
+ over++;
+ expo16_l[sfb] += expo16_off;
+ scalefac_l[sfb]++;
+
+ mark_tab_l[mark_idx_l++] = sfb;
+ }
+ }
+ for (sfb = stop_at; sfb < max_used_sfb_l; sfb++) /* The just preemphased bands have to be treated differently */
+ {
+ if (xfsf_l[sfb] > xmin_l[sfb] * pow216[2*pre_expo_off[sfb]])
+ {
+ over++;
+ expo16_l[sfb] += expo16_off;
+ scalefac_l[sfb]++;
+ }
+ }
+
+
+ return over;
+}
+
+
+
+
+
+/* ======================================================================== */
+/* quantize */
+/* ======================================================================== */
+/*
+ Quantization of the vector xr ( -> ix)
+*/
+
+static int INLINE cutting_crew (FLOAT in)
+{
+ int retVal;
+
+ retVal = (int) (in + 0.4054);
+
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+ if (retVal > 8191+14)
+ tjBitOverflow2 = TRUE;
+#endif
+
+ return retVal;
+}
+
+
+
+static void quantize (void)
+{
+ int sfb, i, b, start, end;
+ double f, z, y;
+
+ for (sfb = 0; sfb < end_sfb_l; sfb++)
+ {
+ start = scalefac_band_long[sfb];
+ end = scalefac_band_long[sfb+1];
+
+ /* (expo16_l[sfb] - 16/4 * quant_step) * 3/4 */
+ f = pow216[(expo16_l[sfb]/4 - (int)cod_info->quantizerStepSize) * 3];
+
+ for (i = start; i < end; i += 2)
+ {
+ z = xr34_l[i ] * f;
+ y = xr34_l[i+1] * f;
+ ix_l[i ] = cutting_crew (z);
+ ix_l[i+1] = cutting_crew (y);
+ }
+ }
+
+ for (sfb = min_used_sfb_s; sfb < end_sfb_s; sfb++)
+ {
+ start = scalefac_band_short[sfb];
+ end = scalefac_band_short[sfb+1];
+
+ for (b = 0; b < 3; b++)
+ {
+ /* (expo_s[sfb][b] - 16/4 * (quant_step + 8 * cod_info->subblock_gain[b])) * 3/4 */
+ f = pow216[(expo16_s[sfb][b] / 4 - (int)cod_info->quantizerStepSize - 8 * cod_info->subblock_gain[b]) * 3];
+
+ for (i = start; i < end; i += 2)
+ {
+ z = xr34_s[i ][b] * f;
+ y = xr34_s[i+1][b] * f;
+ ix_s[i ][b] = cutting_crew (z);
+ ix_s[i+1][b] = cutting_crew (y);
+ }
+ }
+ }
+}
+
+
+
+static void partial_quantize (void)
+{
+ int sfb, i, b, start, end;
+ double f, z, y;
+
+ while (mark_idx_l)
+ {
+ sfb = mark_tab_l[--mark_idx_l];
+
+ start = scalefac_band_long[sfb];
+ end = scalefac_band_long[sfb+1];
+
+ /* (expo16_l[sfb] - 16/4 * quant_step) * 3/4 */
+ f = pow216[(expo16_l[sfb]/4 - (int)cod_info->quantizerStepSize) * 3];
+
+ for (i = start; i < end; i += 2)
+ {
+ z = xr34_l[i ] * f;
+ y = xr34_l[i+1] * f;
+ ix_l[i ] = cutting_crew (z);
+ ix_l[i+1] = cutting_crew (y);
+ }
+ }
+
+ while (mark_idx_s)
+ {
+ b = mark_tab_s[--mark_idx_s];
+ sfb = mark_tab_s[--mark_idx_s];
+
+ start = scalefac_band_short[sfb];
+ end = scalefac_band_short[sfb+1];
+
+ /* (expo_16s[sfb][b] - 16/4 * (quant_step + 8 * cod_info->subblock_gain[b])) * 3/4 */
+ f = pow216[(expo16_s[sfb][b] / 4 - (int)cod_info->quantizerStepSize - 8 * cod_info->subblock_gain[b]) * 3];
+
+ for (i = start; i < end; i += 2)
+ {
+ z = xr34_s[i ][b] * f;
+ y = xr34_s[i+1][b] * f;
+ ix_s[i ][b] = cutting_crew (z);
+ ix_s[i+1][b] = cutting_crew (y);
+ }
+ }
+}
+
+
+
+
+
+/* ======================================================================== */
+/* count_bits */
+/* ======================================================================== */
+
+struct
+{
+ unsigned region0_count;
+ unsigned region1_count;
+} 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 */
+};
+
+
+
+/*
+ Calculation of rzero, count1, big_values
+ (Partitions ix into big values, quadruples and zeros).
+
+ Determines the number of bits to encode the quadruples.
+
+ Presumable subdivides the bigvalue region which will
+ use separate Huffman tables.
+
+ Select huffman code tables for bigvalues regions
+
+ Count the number of bits necessary to code the bigvalues region.
+*/
+
+static int count_bits (void)
+{
+ cod_info->table_select[0] = 0;
+ cod_info->table_select[1] = 0;
+ cod_info->table_select[2] = 0;
+
+ if (cod_info->window_switching_flag && (cod_info->block_type == SHORT_TYPE))
+ return count_bits_short ();
+ else
+ return count_bits_long ();
+}
+
+
+
+
+
+static int count_bits_short (void)
+{
+ unsigned int bits = 0;
+
+ /*
+ Within each scalefactor band, data is given for successive
+ time windows, beginning with window 0 and ending with window 2.
+ Within each window, the quantized values are then arranged in
+ order of increasing frequency...
+ */
+ int sfb, b;
+ unsigned int max, temp;
+
+
+ /*
+ the first part --- 8 long blocks or 3 short blocks
+ */
+
+ max = 0;
+#ifdef MIXED_BLOCKS
+ if (cod_info->mixed_block_flag)
+ {
+ for (sfb = 0; sfb < 8; sfb++)
+ if ((temp = ix_l[xmax_line_l[sfb]]) > max)
+ max = temp;
+ choose_table_long (0, 36, max, &cod_info->table_select[0], &bits);
+ }
+ else
+#endif
+ {
+ for (sfb = 0; sfb < 3; sfb++)
+ for (b = 0; b < 3; b++)
+ if ((temp = ix_s[xmax_line_s[sfb][b]][b]) > max)
+ max = temp;
+ choose_table_short (0, 3, max, &cod_info->table_select[0], &bits);
+ }
+
+
+ /*
+ the second part --- short blocks only
+ */
+
+ max = 0;
+ for (sfb = 3; sfb < SFB_SMAX; sfb++)
+ for (b = 0; b < 3; b++)
+ if ((temp = ix_s[xmax_line_s[sfb][b]][b]) > max)
+ max = temp;
+ choose_table_short (3, SFB_SMAX, max, &cod_info->table_select[1], &bits);
+
+ return bits;
+}
+
+
+
+
+
+static int count_bits_long (void)
+{
+ int zero_region;
+ int bigv_region;
+
+ unsigned bits = 0;
+ int sum0 = 0;
+ int sum1 = 0;
+
+ int sfb_anz, index0, index1, sfb, i;
+ unsigned max, temp;
+
+ int p;
+
+
+ for (zero_region = 576; zero_region > 1; zero_region -= 2)
+ if (ix_l[zero_region-1]) break;
+ else if (ix_l[zero_region-2]) break;
+
+ for (bigv_region = zero_region; bigv_region > 3; bigv_region -= 4)
+ {
+ if (ix_l[bigv_region-1] > 1) break;
+ else if (ix_l[bigv_region-2] > 1) break;
+ else if (ix_l[bigv_region-3] > 1) break;
+ else if (ix_l[bigv_region-4] > 1) break;
+
+ p = 0;
+ if (ix_l[bigv_region-1]) bits++, p |= 8;
+ if (ix_l[bigv_region-2]) bits++, p |= 4;
+ if (ix_l[bigv_region-3]) bits++, p |= 2;
+ if (ix_l[bigv_region-4]) bits++, p |= 1;
+
+ sum0 += ht[32].hlen[p];
+ sum1 += ht[33].hlen[p];
+ }
+
+ cod_info->count1 = (zero_region-bigv_region) / 4;
+ cod_info->big_values = bigv_region / 2;
+
+ if (sum0 < sum1)
+ {
+ bits += sum0;
+ cod_info->count1table_select = 0;
+ }
+ else
+ {
+ bits += sum1;
+ cod_info->count1table_select = 1;
+ }
+
+ if (bigv_region)
+ {
+ sfb_anz = 1;
+ while (scalefac_band_long[sfb_anz] < bigv_region)
+ sfb_anz++;
+
+ if (cod_info->window_switching_flag) /* START_TYPE, STOP_TYPE */
+ {
+ index0 = (cod_info->region0_count = 7) + 1;
+ cod_info->region1_count = 13;
+ index1 = sfb_anz - index0; if (index0 + index1 < 22) index1++;
+
+ cod_info->address1 = 36;
+ cod_info->address2 = bigv_region;
+ cod_info->address3 = 0;
+ }
+ else /* NORM_TYPE */
+ {
+ index0 = (cod_info->region0_count = subdv_table[sfb_anz].region0_count) + 1;
+ index1 = (cod_info->region1_count = subdv_table[sfb_anz].region1_count) + 1;
+
+ cod_info->address1 = scalefac_band_long[index0];
+ cod_info->address2 = scalefac_band_long[index0 + index1];
+ cod_info->address3 = bigv_region;
+ }
+
+ if (cod_info->address1 > 0)
+ {
+ max = 0;
+ for (sfb = 0; sfb < index0; sfb++)
+ if ((temp = ix_l[xmax_line_l[sfb]]) > max)
+ max = temp;
+ choose_table_long (0, cod_info->address1, max, &cod_info->table_select[0], &bits);
+ }
+
+ if (cod_info->address2 > cod_info->address1)
+ {
+ max = 0;
+ for (sfb = index0; sfb < index0+index1; sfb++)
+ if ((temp = ix_l[xmax_line_l[sfb]]) > max)
+ max = temp;
+ choose_table_long (cod_info->address1, cod_info->address2, max, &cod_info->table_select[1], &bits);
+ }
+
+ if (bigv_region > cod_info->address2)
+ {
+ max = 0;
+ for (sfb = index0+index1; sfb < sfb_anz-1; sfb++)
+ if ((temp = ix_l[xmax_line_l[sfb]]) > max)
+ max = temp;
+ for (i = scalefac_band_long[sfb_anz-1]; i < bigv_region; i++)
+ if ((temp = ix_l[i]) > max)
+ max = temp;
+ choose_table_long (cod_info->address2, bigv_region, max, &cod_info->table_select[2], &bits);
+ }
+ }
+ else
+ { /* no big_values region */
+ cod_info->region0_count = 0;
+ cod_info->region1_count = 0;
+
+ cod_info->address1 = 0;
+ cod_info->address2 = 0;
+ cod_info->address3 = 0;
+ }
+
+
+ return bits;
+}
+
+
+
+
+
+/* ======================================================================== */
+/* bin_search_step_size */
+/* ======================================================================== */
+/*
+ The following optional code written by Seymour Shlien
+ will speed up the outer_loop code which is called
+ by iteration_loop. When BIN_SEARCH is defined, the
+ outer_loop function precedes the call to the function inner_loop
+ with a call to bin_search gain defined below, which
+ returns a good starting quantizerStepSize.
+
+ The function count_bits() [a sequence of statements, originally part of inner_loop()]
+ was completely rewritten.
+
+
+ changed the behaviour:
+ now, it returns the found number of bits <= desired_rate
+*/
+
+static int bin_search_StepSize
+(
+ int desired_rate,
+ double start
+)
+{
+ int bits;
+
+ int top = start;
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT
+ int bot = 200;
+#else
+ int bot = the_hi_quant;
+#endif
+ int next = start;
+
+#if ORG_BINARY_SEARCH
+
+ int last;
+
+ do
+ {
+ last = next;
+ next = (top + bot) / 2;
+ cod_info->quantizerStepSize = next;
+
+ tjBitOverflow2 = FALSE;
+ quantize ();
+ if (tjBitOverflow2)
+ bits = infinity;
+ else
+ bits = count_bits ();
+
+ if (bits > desired_rate)
+ top = next;
+ else
+ bot = next;
+ }
+ while ((bits != desired_rate) && (abs(last-next) > 1));
+
+#else /* ORG_BINARY_SEARCH */
+
+ do
+ {
+ next = top + (bot - top) / 2;
+ cod_info->quantizerStepSize = next;
+
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+ tjBitOverflow2 = FALSE;
+ quantize ();
+ if (tjBitOverflow2)
+ bits = infinity;
+ else
+ bits = count_bits ();
+#else
+ quantize ();
+ bits = count_bits ();
+#endif
+
+ if (bits > desired_rate)
+ top = next + 1;
+ else
+ bot = next;
+ }
+ while (top < bot);
+
+#endif /* ORG_BINARY_SEARCH */
+
+ if (bits > desired_rate)
+ {
+ cod_info->quantizerStepSize = next+1;
+#if ORG_BINARY_SEARCH || ORG_QUANTANF_INIT || CHECK_TJ_OVERFLOW
+ tjBitOverflow2 = FALSE;
+ quantize ();
+assert(! tjBitOverflow2);
+#else
+ quantize ();
+#endif
+ bits = count_bits ();
+assert(bits <= desired_rate);
+ }
+
+ return bits;
+
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* choose_table_long */
+/* ======================================================================================== */
+/*
+ Choose the Huffman table that will encode ix[start..end] with the fewest
+ bits and increases the bit_sum by the amount of these bits.
+
+ Note: This code contains knowledge about the sizes and characteristics
+ of the Huffman tables as defined in the IS (Table B.7), and will not work
+ with any arbitrary tables.
+*/
+static void choose_table_long
+(
+ unsigned start,
+ unsigned end,
+ unsigned max,
+ unsigned *table,
+ unsigned *bit_sum
+)
+{
+ unsigned choice0, choice1;
+
+
+ if (max == 0)
+ {
+ *table = 0;
+ return;
+ }
+
+ if (max < 15)
+ {
+ choice0 = 1; /* we can start with 1 because ht[0].xlen == 0 <= max */
+ while (ht[choice0].xlen <= max)
+ choice0++;
+
+ switch (choice0)
+ {
+ case 1: single_Huffman (start, end,/* 1 */ table, bit_sum); break;
+ case 2: double_Huffman (start, end, 2, 3, table, bit_sum); break;
+ case 5: double_Huffman (start, end, 5, 6, table, bit_sum); break;
+ case 7: triple_Huffman (start, end, 7, 8, 9, table, bit_sum); break;
+ case 10: triple_Huffman (start, end, 10, 11, 12, table, bit_sum); break;
+ case 13: double_Huffman (start, end, 13, 15, table, bit_sum); break;
+ }
+ }
+#if !ORG_HUFFMAN_CODING /* no part of original BladeEnc */
+ else if (max == 15)
+ {
+ triple_Huffman_2 (start, end,/* 13, 15, 24, */ table, bit_sum);
+ }
+#endif
+ else
+ {
+ max -= 15;
+
+#if ORG_HUFFMAN_CODING
+ choice0 = 15; while (ht[choice0].linmax < max) choice0++;
+#else
+ choice0 = 16; while (ht[choice0].linmax < max) choice0++;
+#endif
+
+assert(choice0 < 24);
+ choice1 = 24; while (ht[choice1].linmax < max) choice1++;
+assert(choice1 < 32);
+
+#if ORG_HUFFMAN_CODING
+ double_Huffman_2 (start, end, choice1, choice0, table, bit_sum);
+#else
+ double_Huffman_2 (start, end, choice0, choice1, table, bit_sum);
+#endif
+ }
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* choose_table_short */
+/* ======================================================================================== */
+/*
+ Choose the Huffman table that will encode ix[start_sfb..end_sfb][0..2]
+ with the fewest bits and increases the bit_sum by the amount of these bits.
+
+ Note: This code contains knowledge about the sizes and characteristics
+ of the Huffman tables as defined in the IS (Table B.7), and will not work
+ with any arbitrary tables.
+*/
+
+static void choose_table_short
+(
+ unsigned start_sfb,
+ unsigned end_sfb,
+ unsigned max,
+ unsigned *table,
+ unsigned *bit_sum
+)
+{
+ unsigned choice0;
+#if !ORG_HUFFMAN_CODING
+ unsigned choice1;
+#endif
+ int start, end;
+
+ start = 3 * scalefac_band_short[start_sfb];
+ end = 3 * scalefac_band_short[ end_sfb];
+
+ if (max == 0)
+ {
+ *table = 0;
+ return;
+ }
+
+ if (max < 15)
+ {
+ choice0 = 1; /* we can start with 1 because ht[0].xlen == 0 <= max */
+ while (ht[choice0].xlen <= max)
+ choice0++;
+
+#if ORG_HUFFMAN_CODING
+ tiny_single_Huffman (start, end, choice0, table, bit_sum);
+#else
+ switch (choice0)
+ {
+ case 1: tiny_single_Huffman (start, end,/* 1 */ table, bit_sum); break;
+ case 2: tiny_double_Huffman (start, end, 2, 3, table, bit_sum); break;
+ case 5: tiny_double_Huffman (start, end, 5, 6, table, bit_sum); break;
+ case 7: tiny_triple_Huffman (start, end, 7, 8, 9, table, bit_sum); break;
+ case 10: tiny_triple_Huffman (start, end, 10, 11, 12, table, bit_sum); break;
+ case 13: tiny_double_Huffman (start, end, 13, 15, table, bit_sum); break;
+ }
+#endif
+ }
+#if !ORG_HUFFMAN_CODING /* no part of original BladeEnc */
+ else if (max == 15)
+ {
+ tiny_triple_Huffman_2 (start, end,/* 13, 15, 24, */ table, bit_sum);
+ }
+#endif
+ else
+ {
+ max -= 15;
+
+#if ORG_HUFFMAN_CODING
+
+ choice0 = 15; while (ht[choice0].linmax < max) choice0++;
+assert(choice0 < 24);
+ tiny_single_Huffman_2 (start, end, choice0, table, bit_sum);
+
+#else
+
+ choice0 = 16; while (ht[choice0].linmax < max) choice0++;
+assert(choice0 < 24);
+ choice1 = 24; while (ht[choice1].linmax < max) choice1++;
+assert(choice1 < 32);
+ tiny_double_Huffman_2 (start, end, choice0, choice1, table, bit_sum);
+
+#endif
+ }
+}
+
+
+
+
+
+/* ======================================================================================== */
+/* Huffmania */
+/* ======================================================================================== */
+
+
+
+/*
+ That case, we don«t need to decide which is the best table.
+*/
+
+static void single_Huffman
+(
+ unsigned start,
+ unsigned end,
+/* unsigned table0, == 1 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+/*
+ int v;
+*/
+ unsigned bits0, signs, idx;
+
+ static struct huffcodetab *h0 = ht + /* table0 */ 1; /* static because of the constant!!! */
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == 2 */
+#endif
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx = 0;
+#if 0
+ v = *pos++; if (v) {signs++; idx = v /* * ylen */ + v;}
+ v = *pos++; if (v) {signs++; idx += v;}
+#else
+ if (*pos++) {signs++; idx = 2;}
+ if (*pos++) {signs++; idx++;}
+#endif
+ bits0 += h0->hlen[idx];
+ }
+
+ *choice = /* table0 */ 1;
+ *sum += bits0 + signs;
+}
+
+
+
+#if ORG_HUFFMAN_CODING
+static void tiny_single_Huffman
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0,
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, signs, idx0, idx1, idx2;
+
+ struct huffcodetab *h0 = ht + table0;
+
+ unsigned ylen = h0->ylen;
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+
+ v0 = *pos++; if (v0) {signs++; idx0 = v0 * ylen;}
+ v1 = *pos++; if (v1) {signs++; idx1 = v1 * ylen;}
+ v2 = *pos++; if (v2) {signs++; idx2 = v2 * ylen;}
+ v0 = *pos++; if (v0) {signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {signs++; idx2 += v2;}
+
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ }
+
+ *choice = table0;
+ *sum += bits0 + signs;
+}
+#else
+static void tiny_single_Huffman
+(
+ unsigned start,
+ unsigned end,
+/* unsigned table0 == 1 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+/*
+ int v0, v1, v2;
+*/
+ unsigned bits0, signs, idx0, idx1, idx2;
+
+ static struct huffcodetab *h0 = ht + /* table0 */ 1; /* static because of the constant!!! */
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == 2 --- static because of the constant!!! */
+#endif
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+
+ if (*pos++) {signs++; idx0 = 2;}
+ if (*pos++) {signs++; idx1 = 2;}
+ if (*pos++) {signs++; idx2 = 2;}
+ if (*pos++) {signs++; idx0++;}
+ if (*pos++) {signs++; idx1++;}
+ if (*pos++) {signs++; idx2++;}
+
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ }
+
+ *choice = /* table0 */ 1;
+ *sum += bits0 + signs;
+}
+#endif
+
+
+
+#if ORG_HUFFMAN_CODING
+static void tiny_single_Huffman_2 /* Escape tables */
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 15... */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, signs, xbits, idx0, idx1, idx2;
+
+ struct huffcodetab *h0 = ht + table0;
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == h1->ylen == 16 --- static because of the constant!!! */
+#endif
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = signs = xbits = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+
+ v0 = *pos++; if (v0) {if (v0 > 14) {v0 = 15; xbits++;} signs++; idx0 = v0 /* * ylen */ << 4;}
+ v1 = *pos++; if (v1) {if (v1 > 14) {v1 = 15; xbits++;} signs++; idx1 = v1 /* * ylen */ << 4;}
+ v2 = *pos++; if (v2) {if (v2 > 14) {v2 = 15; xbits++;} signs++; idx2 = v2 /* * ylen */ << 4;}
+ v0 = *pos++; if (v0) {if (v0 > 14) {v0 = 15; xbits++;} signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {if (v1 > 14) {v1 = 15; xbits++;} signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {if (v2 > 14) {v2 = 15; xbits++;} signs++; idx2 += v2;}
+
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ }
+
+ bits0 += xbits * h0->linbits;
+
+ *choice = table0;
+ *sum += bits0 + signs;
+}
+#endif
+
+
+
+
+
+/*
+ The following function is called for the most maximum values below 16 (respectively 15)
+*/
+
+static void double_Huffman
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 2, 5, 13 */
+ unsigned table1, /* 3, 6, 15 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v;
+ unsigned bits0, bits1, signs, idx;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+
+ unsigned ylen = h0->ylen; /* == h1->ylen */
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx = 0;
+ v = *pos++; if (v) {signs++; idx = v * ylen;}
+ v = *pos++; if (v) {signs++; idx += v;}
+ bits0 += h0->hlen[idx];
+ bits1 += h1->hlen[idx];
+ }
+
+ if (bits0 < bits1)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+}
+
+
+
+static void tiny_double_Huffman
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 2, 5, 13 */
+ unsigned table1, /* 3, 6, 15 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, bits1, signs, idx0, idx1, idx2;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+
+ unsigned ylen = h0->ylen; /* == h1->ylen */
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+ v0 = *pos++; if (v0) {signs++; idx0 = v0 * ylen;}
+ v1 = *pos++; if (v1) {signs++; idx1 = v1 * ylen;}
+ v2 = *pos++; if (v2) {signs++; idx2 = v2 * ylen;}
+ v0 = *pos++; if (v0) {signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {signs++; idx2 += v2;}
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ bits1 += h1->hlen[idx0] + h1->hlen[idx1] + h1->hlen[idx2];
+ }
+
+ if (bits0 < bits1)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+}
+
+
+
+/*
+ poor men«s brave tailor --- only three at a blow...
+*/
+
+static void triple_Huffman
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 7, 10 */
+ unsigned table1, /* 8, 11 */
+ unsigned table2, /* 9, 12 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v;
+ unsigned bits0, bits1, bits2, signs, idx;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+ struct huffcodetab *h2 = ht + table2;
+
+ unsigned ylen = h0->ylen; /* == h1->ylen == h2->ylen */
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = bits2 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx = 0;
+ v = *pos++; if (v) {signs++; idx = v * ylen;}
+ v = *pos++; if (v) {signs++; idx += v;}
+ bits0 += h0->hlen[idx];
+ bits1 += h1->hlen[idx];
+ bits2 += h2->hlen[idx];
+ }
+
+ if (bits0 < bits1 && bits0 < bits2)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else if (bits1 < bits2)
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+ else
+ {
+ *choice = table2;
+ *sum += bits2 + signs;
+ }
+}
+
+
+
+static void tiny_triple_Huffman
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 7, 10 */
+ unsigned table1, /* 8, 11 */
+ unsigned table2, /* 9, 12 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, bits1, bits2, signs, idx0, idx1, idx2;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+ struct huffcodetab *h2 = ht + table2;
+
+ unsigned ylen = h0->ylen; /* == h1->ylen == h2->ylen */
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = bits2 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+ v0 = *pos++; if (v0) {signs++; idx0 = v0 * ylen;}
+ v1 = *pos++; if (v1) {signs++; idx1 = v1 * ylen;}
+ v2 = *pos++; if (v2) {signs++; idx2 = v2 * ylen;}
+ v0 = *pos++; if (v0) {signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {signs++; idx2 += v2;}
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ bits1 += h1->hlen[idx0] + h1->hlen[idx1] + h1->hlen[idx2];
+ bits2 += h2->hlen[idx0] + h2->hlen[idx1] + h2->hlen[idx2];
+ }
+
+ if (bits0 < bits1 && bits0 < bits2)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else if (bits1 < bits2)
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+ else
+ {
+ *choice = table2;
+ *sum += bits2 + signs;
+ }
+}
+
+
+
+
+
+/*
+ The escape table 24 deals with linbits=4 instead of linbits=0 in case of table 13 and 15.
+ Nevertheless, sometimes it produces the better result...
+ Furthermore we take advantage because of the constant table numbers.
+*/
+
+static void triple_Huffman_2
+(
+ unsigned start,
+ unsigned end,
+/* unsigned table0, == 13 */
+/* unsigned table1, == 15 */
+/* unsigned table2, == 24 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v;
+ unsigned bits0, bits1, bits2, signs, idx;
+
+ static struct huffcodetab *h0 = ht + /* table0 */ 13; /* all static declarations because of the constant values!!! */
+ static struct huffcodetab *h1 = ht + /* table1 */ 15;
+ static struct huffcodetab *h2 = ht + /* table2 */ 24;
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == h1->ylen == h2->ylen */ /* == 16 */
+#endif
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = bits2 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx = 0;
+ v = *pos++; if (v) {if (v == 15) bits2 += /* h2->linbits */ 4; signs++; idx = v /* * ylen */ << 4;}
+ v = *pos++; if (v) {if (v == 15) bits2 += /* h2->linbits */ 4; signs++; idx += v;}
+ bits0 += h0->hlen[idx];
+ bits1 += h1->hlen[idx];
+ bits2 += h2->hlen[idx];
+ }
+
+ if (bits0 < bits1 && bits0 < bits2)
+ {
+ *choice = /* table0 */ 13;
+ *sum += bits0 + signs;
+ }
+ else if (bits1 < bits2)
+ {
+ *choice = /* table1 */ 15;
+ *sum += bits1 + signs;
+ }
+ else
+ {
+ *choice = /* table2 */ 24;
+ *sum += bits2 + signs;
+ }
+}
+
+
+
+static void tiny_triple_Huffman_2
+(
+ unsigned start,
+ unsigned end,
+/* unsigned table0, == 13 */
+/* unsigned table1, == 15 */
+/* unsigned table2, == 24 */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, bits1, bits2, signs, idx0, idx1, idx2;
+
+ static struct huffcodetab *h0 = ht + /* table0 */ 13; /* all static declarations because of the constant values!!! */
+ static struct huffcodetab *h1 = ht + /* table1 */ 15;
+ static struct huffcodetab *h2 = ht + /* table2 */ 24;
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == h1->ylen == h2->ylen */ /* == 16 */
+#endif
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = bits2 = signs = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+ v0 = *pos++; if (v0) {if (v0 == 15) bits2 += /* h2->linbits */ 4; signs++; idx0 = v0 /* * ylen */ << 4;}
+ v1 = *pos++; if (v1) {if (v1 == 15) bits2 += /* h2->linbits */ 4; signs++; idx1 = v1 /* * ylen */ << 4;}
+ v2 = *pos++; if (v2) {if (v2 == 15) bits2 += /* h2->linbits */ 4; signs++; idx2 = v2 /* * ylen */ << 4;}
+ v0 = *pos++; if (v0) {if (v0 == 15) bits2 += /* h2->linbits */ 4; signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {if (v1 == 15) bits2 += /* h2->linbits */ 4; signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {if (v2 == 15) bits2 += /* h2->linbits */ 4; signs++; idx2 += v2;}
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ bits1 += h1->hlen[idx0] + h1->hlen[idx1] + h1->hlen[idx2];
+ bits2 += h2->hlen[idx0] + h2->hlen[idx1] + h2->hlen[idx2];
+ }
+
+ if (bits0 < bits1 && bits0 < bits2)
+ {
+ *choice = /* table0 */ 13;
+ *sum += bits0 + signs;
+ }
+ else if (bits1 < bits2)
+ {
+ *choice = /* table1 */ 15;
+ *sum += bits1 + signs;
+ }
+ else
+ {
+ *choice = /* table2 */ 24;
+ *sum += bits2 + signs;
+ }
+}
+
+
+
+
+
+/*
+ In case of two escape tables, we esepecially have to take care for
+ the possibly different linbits values...
+*/
+
+static void double_Huffman_2 /* Escape tables */
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 16... */
+ unsigned table1, /* 24... */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v;
+ unsigned bits0, bits1, signs, xbits, idx;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == h1->ylen */ /* == 16 */
+#endif
+ unsigned linbits0 = h0->linbits;
+ unsigned linbits1 = h1->linbits;
+
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = signs = xbits = 0;
+
+ while (pos < fin)
+ {
+ idx = 0;
+ v = *pos++; if (v) {if (v > 14) {v = 15; xbits++;/*bits0 += linbits0; bits1 += linbits1;*/} signs++; idx = v /* * ylen */ << 4;}
+ v = *pos++; if (v) {if (v > 14) {v = 15; xbits++;/*bits0 += linbits0; bits1 += linbits1;*/} signs++; idx += v;}
+ bits0 += h0->hlen[idx];
+ bits1 += h1->hlen[idx];
+ }
+ bits0 += xbits * linbits0;
+ bits1 += xbits * linbits1;
+
+ if (bits0 < bits1)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+}
+
+
+
+static void tiny_double_Huffman_2 /* Escape tables */
+(
+ unsigned start,
+ unsigned end,
+ unsigned table0, /* 16... */
+ unsigned table1, /* 24... */
+ unsigned *choice,
+ unsigned *sum
+)
+{
+ int v0, v1, v2;
+ unsigned bits0, bits1, signs, xbits, idx0, idx1, idx2;
+
+ struct huffcodetab *h0 = ht + table0;
+ struct huffcodetab *h1 = ht + table1;
+
+#if 0 /* not needed */
+ static unsigned ylen = h0->ylen; /* == h1->ylen == 16 --- static because of the constant!!! */
+#endif
+ int *pos = ix_l + start;
+ int *fin = ix_l + end;
+
+ bits0 = bits1 = signs = xbits = 0;
+
+ while (pos < fin)
+ {
+ idx0 = idx1 = idx2 = 0;
+
+ v0 = *pos++; if (v0) {if (v0 > 14) {v0 = 15; xbits++;} signs++; idx0 = v0 /* * ylen */ << 4;}
+ v1 = *pos++; if (v1) {if (v1 > 14) {v1 = 15; xbits++;} signs++; idx1 = v1 /* * ylen */ << 4;}
+ v2 = *pos++; if (v2) {if (v2 > 14) {v2 = 15; xbits++;} signs++; idx2 = v2 /* * ylen */ << 4;}
+ v0 = *pos++; if (v0) {if (v0 > 14) {v0 = 15; xbits++;} signs++; idx0 += v0;}
+ v1 = *pos++; if (v1) {if (v1 > 14) {v1 = 15; xbits++;} signs++; idx1 += v1;}
+ v2 = *pos++; if (v2) {if (v2 > 14) {v2 = 15; xbits++;} signs++; idx2 += v2;}
+
+ bits0 += h0->hlen[idx0] + h0->hlen[idx1] + h0->hlen[idx2];
+ bits1 += h1->hlen[idx0] + h1->hlen[idx1] + h1->hlen[idx2];
+ }
+
+ bits0 += xbits * h0->linbits;
+ bits1 += xbits * h1->linbits;
+
+ if (bits0 < bits1)
+ {
+ *choice = table0;
+ *sum += bits0 + signs;
+ }
+ else
+ {
+ *choice = table1;
+ *sum += bits1 + signs;
+ }
+}
+
+
+