/*
  Implements the pseudocode of page 98 of the IS
  */
int
HuffmanCode( int table_select, int x, int y, unsigned int *code, unsigned int *ext, int *cbits, int *xbits )
{
    unsigned signx, signy, linbitsx, linbitsy, linbits, xlen, ylen, idx;
    struct huffcodetab *h;

    *cbits = 0;
    *xbits = 0;
    *code  = 0;
    *ext   = 0;
    
    if ( table_select == 0 )
	return 0;
    
    signx = abs_and_sign( &x );
    signy = abs_and_sign( &y );
    h = &(ht[table_select]);
    xlen = h->xlen;
    ylen = h->ylen;
    linbits = h->linbits;
    linbitsx = linbitsy = 0;

    if ( table_select > 15 )
    { /* ESC-table is used */
	if ( x > 14 )
	{
	    linbitsx = x - 15;
	    assert( linbitsx <= h->linmax );
	    x = 15;
	}
	if ( y > 14 )
	{
	    linbitsy = y - 15;
	    assert( linbitsy <= h->linmax );
	    y = 15;
	}
	idx = (x * ylen) + y;
	*code = h->table[idx];
	*cbits = h->hlen[ idx ];
	if ( x > 14 )
	{
	    *ext |= linbitsx;
	    *xbits += linbits;
	}
	if ( x != 0 )
	{
	    *ext <<= 1;
	    *ext |= signx;
	    *xbits += 1;
	}
	if ( y > 14 )
	{
	    *ext <<= linbits;
	    *ext |= linbitsy;
	    *xbits += linbits;
	}
	if ( y != 0 )
	{
	    *ext <<= 1;
	    *ext |= signy;
	    *xbits += 1;
	}
    }
    else
    { /* No ESC-words */
	idx = (x * ylen) + y;
	*code = h->table[idx];
	*cbits += h->hlen[ idx ];
	if ( x != 0 )
	{
	    *code <<= 1;
	    *code |= signx;
	    *cbits += 1;
	}
	if ( y != 0 )
	{
	    *code <<= 1;
	    *code |= signy;
	    *cbits += 1;
	}
    }
    assert( *cbits <= 32 );
    assert( *xbits <= 32 );
    return *cbits + *xbits;
}
