Version 0.94.1 of the bladeenc mp3 encoder
[swftools.git] / lib / bladeenc / loop.c
diff --git a/lib/bladeenc/loop.c b/lib/bladeenc/loop.c
new file mode 100644 (file)
index 0000000..a65508b
--- /dev/null
@@ -0,0 +1,2590 @@
+/*
+                       (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;
+       }
+}
+
+
+