Plan 9 from Bell Labs’s /usr/web/sources/contrib/cnielsen/bladeenc/loop.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
			(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

	2001-05-02  ap
	-	bug fix: outer_loop() - correct handling of flag tjBitOverflow2
*/





/*  ========================================================================================  */
/*              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� 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� 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� 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�e 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� 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
		if (tjBitOverflow2)
			bits = infinity;
		else
			bits = count_bits ();
#else
		bits = count_bits ();
#endif

		while (bits > huff_bits)
		{
			cod_info->quantizerStepSize += 1.0;
#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 !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� 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� 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;
	}
}




Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.