//------------------------------------------------------------------------------
// jpegdecoder.cpp
// Small JPEG Decoder Library v0.93b
// Last updated: Dec. 28, 2001 
// Copyright (C) 1994-2000 Rich Geldreich
// richgel@voicenet.com
// 
// Dec. 19, 2001 - fixed dumb bug in the decode_next_row functions that
// could cause bogus non-zero coefficients from leaking through in rare cases.
//
// This library is free software; you can redistribute it 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.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

#ifndef max
#define max(a,b) (((a)>(b)) ? (a) : (b))
#endif

#ifndef min
#define min(a,b) (((a)<(b)) ? (a) : (b))
#endif

#ifndef TRUE
#define TRUE (1)
#endif

#ifndef FALSE
#define FALSE (0)
#endif

#include "jpegdecoder.h"
//------------------------------------------------------------------------------
// Coefficients are stored in this sequence in the data stream.
static const int ZAG[64] =
{
  0,  1,  8, 16,  9,  2,  3, 10,
 17, 24, 32, 25, 18, 11,  4,  5,
 12, 19, 26, 33, 40, 48, 41, 34,
 27, 20, 13,  6,  7, 14, 21, 28,
 35, 42, 49, 56, 57, 50, 43, 36,
 29, 22, 15, 23, 30, 37, 44, 51,
 58, 59, 52, 45, 38, 31, 39, 46,
 53, 60, 61, 54, 47, 55, 62, 63,
};
//------------------------------------------------------------------------------
const int AAN_SCALE_BITS = 14;
const int IFAST_SCALE_BITS = 2; /* fractional bits in scale factors */
//------------------------------------------------------------------------------
static const int16 aan_scales[64] =
{
  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
};

//------------------------------------------------------------------------------
// Unconditionally frees all allocated blocks.
void jpeg_decoder::free_all_blocks(void)
{
  for (int i = 0; i < JPGD_MAXBLOCKS; i++)
  {
    free(blocks[i]);
    blocks[i] = NULL;
  }
}

//------------------------------------------------------------------------------
// This method handles all errors.
// It could easily be changed to use C++ exceptions.
void jpeg_decoder::terminate(int status)
{
  error_code = status;

  free_all_blocks();

  printf("%d\n", status);
  //puts("JPEG ERror");
  exit(1);
}

//------------------------------------------------------------------------------
// Allocate a block of memory-- store block's address in list for
// later deallocation by free_all_blocks().
void *jpeg_decoder::alloc(int n)
{
  // Find a free slot. The number of allocated slots will
  // always be very low, so a linear search is good enough.
  int i;

  for (i = 0; i < JPGD_MAXBLOCKS; i++)
  {
    if (blocks[i] == NULL)
      break;
  }

  if (i == JPGD_MAXBLOCKS)
    terminate(JPGD_TOO_MANY_BLOCKS);

  void *q = malloc(n);
  if (q == NULL)
    terminate(JPGD_NOTENOUGHMEM);

  memset(q, 0, n);

  blocks[i] = q;

  return (q);
}

//------------------------------------------------------------------------------
// Clear buffer to word values.
void jpeg_decoder::word_clear(void *p, uint16 c, uint32 n)
{
  uint16 *ps = (uint16 *)p;
  while (n)
  {
    *ps++ = c;
    n--;
  }
}


void jpeg_decoder::set_in_buffer(uint8 *data, uint32 len)
{
 in_buf = (uint8 *)alloc(len);

 memcpy(in_buf, data, len);
 Pin_buf_ofs = in_buf;
 in_buf_left = len;
}

void jpeg_decoder::set_huffman(int index, const uint8 *data)
{
  int i, count;
  uint8 huff_num[17];
  uint8 huff_val[256];

  huff_num[0] = 0;

  count = 0;

  for (i = 1; i <= 16; i++)
  {
    huff_num[i] = data[i - 1];
    count += huff_num[i];
  }

  for (i = 0; i < count; i++)
    huff_val[i] = data[16 + i];

  index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAXHUFFTABLES >> 1);

  if (!this->huff_num[index])
   this->huff_num[index] = (uint8 *)alloc(17);

  if (!this->huff_val[index])
   this->huff_val[index] = (uint8 *)alloc(256);

  memcpy(this->huff_num[index], huff_num, 17);
  memcpy(this->huff_val[index], huff_val, 256);

 //printf("SetHuffman: %d %d\n", index, count);
}

void jpeg_decoder::set_quant(int n, uint8 *data)
{
  int i;

  n &= 0x0F;

  if (!quant[n])
   quant[n] = (QUANT_TYPE *)alloc(64 * sizeof(QUANT_TYPE));

  // read quantization entries, in zag order
  for (i = 0; i < 64; i++)
  {
    quant[n][i] = data[i];
  }
}

void jpeg_decoder::set_sof(int width, int height, int Y_h_samp, int Y_v_samp, int Y_quant, int Cb_h_samp, 
	int Cb_v_samp, int Cb_quant, int Cr_h_samp, int Cr_v_samp, int Cr_quant)
{
  image_y_size = height;
  image_x_size = width;

  comps_in_frame = 3;

  comp_ident[0] = 0;
  comp_h_samp[0] = Y_h_samp;
  comp_v_samp[0] = Y_v_samp;
  comp_quant[0] = Y_quant;

  comp_ident[1] = 0;
  comp_h_samp[1] = Cb_h_samp;
  comp_v_samp[1] = Cb_v_samp;
  comp_quant[1] = Cb_quant;

  comp_ident[2] = 0;
  comp_h_samp[2] = Cr_h_samp;
  comp_v_samp[2] = Cr_v_samp;
  comp_quant[2] = Cr_quant;

}

//------------------------------------------------------------------------------
// Read a start of scan (SOS) marker.
void jpeg_decoder::set_sos(int Y_dc_tab, int Y_ac_tab, int Cb_dc_tab, int Cb_ac_tab, int Cr_dc_tab, int Cr_ac_tab)
{
  comps_in_scan = 3;

  comp_dc_tab[0] = Y_dc_tab;
  comp_ac_tab[0] = Y_ac_tab;

  comp_dc_tab[1] = Cb_dc_tab;
  comp_ac_tab[1] = Cb_ac_tab;

  comp_dc_tab[2] = Cr_dc_tab;
  comp_ac_tab[2] = Cr_ac_tab;

  spectral_start = 0;
  spectral_end = 63;
}

//------------------------------------------------------------------------------
// Reset everything to default/uninitialized state.
void jpeg_decoder::init(void)
{
  error_code = 0;

  ready_flag = false;

  image_x_size = image_y_size = 0;

  memset(huff_num, 0, sizeof(huff_num));
  memset(huff_val, 0, sizeof(huff_val));
  memset(quant, 0, sizeof(quant));

  scan_type = 0;

  comps_in_frame = 0;

  memset(comp_h_samp, 0, sizeof(comp_h_samp));
  memset(comp_v_samp, 0, sizeof(comp_v_samp));
  memset(comp_quant, 0, sizeof(comp_quant));
  memset(comp_ident, 0, sizeof(comp_ident));
  memset(comp_h_blocks, 0, sizeof(comp_h_blocks));
  memset(comp_v_blocks, 0, sizeof(comp_v_blocks));

  comps_in_scan = 0;
  memset(comp_dc_tab, 0, sizeof(comp_dc_tab));
  memset(comp_ac_tab, 0, sizeof(comp_ac_tab));

  spectral_start = 0;
  spectral_end = 0;

  max_mcu_x_size = 0;
  max_mcu_y_size = 0;

  blocks_per_mcu = 0;
  max_blocks_per_row = 0;
  mcus_per_row = 0;
  mcus_per_col = 0;

  memset(mcu_org, 0, sizeof(mcu_org));

  total_lines_left = 0;
  mcu_lines_left = 0;

  real_dest_bytes_per_scan_line = 0;
  dest_bytes_per_scan_line = 0;
  dest_bytes_per_pixel = 0;

  memset(blocks, 0, sizeof(blocks));

  memset(h, 0, sizeof(h));

  memset(dc_coeffs, 0, sizeof(dc_coeffs));
  memset(ac_coeffs, 0, sizeof(ac_coeffs));
  memset(block_y_mcu, 0, sizeof(block_y_mcu));

  eob_run = 0;

  memset(block_y_mcu, 0, sizeof(block_y_mcu));

  Pin_buf_ofs = NULL;
  in_buf_left = 0;
  eof_flag = false;
  tem_flag = 0;

  max_mcus_per_row = 0;
  max_blocks_per_mcu = 0;
  max_mcus_per_col = 0;

  memset(component, 0, sizeof(component));
  memset(last_dc_val, 0, sizeof(last_dc_val));
  memset(dc_huff_seg, 0, sizeof(dc_huff_seg));
  memset(ac_huff_seg, 0, sizeof(ac_huff_seg));
  memset(block_seg, 0, sizeof(block_seg));
  Psample_buf = NULL;

  // Prime the bit buffer.
  bits_left = 0; //16;
  bit_buf_64[0] = 0;
  bit_buf_64[1] = 0;

  for (int i = 0; i < JPGD_MAXBLOCKSPERROW; i++)
    block_max_zag_set[i] = 64;
}

//------------------------------------------------------------------------------
// Performs a 2D IDCT over the entire row's coefficient buffer.
void jpeg_decoder::transform_row(void)
{
    BLOCK_TYPE *Psrc_ptr = block_seg[0];
    uint8 *Pdst_ptr = Psample_buf;

    for (int i = max_blocks_per_row; i > 0; i--)
    {
      // Copy the block to a temp. buffer to prevent the IDCT
      // from modifying the entire block.
      memcpy(temp_block, Psrc_ptr, 64 * sizeof(BLOCK_TYPE));
      idct(temp_block, Pdst_ptr);
      Psrc_ptr += 64;
      Pdst_ptr += 64;
    }
}

//------------------------------------------------------------------------------
// Decodes and dequantizes the next row of coefficients.
void jpeg_decoder::decode_next_row(void)
{
  int row_block = 0;

  // Clearing the entire row block buffer can take a lot of time!
  // Instead of clearing the entire buffer each row, keep track
  // of the number of nonzero entries written to each block and do
  // selective clears.
  //memset(block_seg[0], 0, mcus_per_row * blocks_per_mcu * 64 * sizeof(BLOCK_TYPE));

  for (int mcu_row = 0; mcu_row < mcus_per_row; mcu_row++)
  {
    for (int mcu_block = 0; mcu_block < blocks_per_mcu; mcu_block++)
    {
      int component_id = mcu_org[mcu_block];

      BLOCK_TYPE *p = block_seg[row_block];
      QUANT_TYPE *q = quant[comp_quant[component_id]];
      int r, s;

      if ((s = huff_decode(h[comp_dc_tab[component_id]])) != 0)
      {
        r = get_bits_2(s);
        s = HUFF_EXTEND(r, s);
      }

      last_dc_val[component_id] = (s += last_dc_val[component_id]);

      p[0] = s * q[0];

      int prev_num_set = block_max_zag_set[row_block];

      Phuff_tables_t Ph = h[comp_ac_tab[component_id]];

      int k;
      for (k = 1; k < 64; k++)
      {
        s = huff_decode(Ph);

        r = s >> 4;
        s &= 15;

        if (s)
        {
          if (r)
          {
            //if ((k + r) > 63)
            // terminate(JPGD_DECODE_ERROR);

            if (k < prev_num_set)
            {
              int n = min(r, prev_num_set - k);
              int kt = k;
              while (n--)
                p[ZAG[kt++]] = 0;
            }

            k += r;
            //if(k > 63) k = 63;
	    k &= 63;
          }

          r = get_bits_2(s);
          s = HUFF_EXTEND(r, s);

          //assert(k < 64);

          p[ZAG[k]] = s * q[k];
        }
        else
        {
          if (r == 15)
          {
           //if ((k + 15) > 63)
           //  terminate(JPGD_DECODE_ERROR);

            if (k < prev_num_set)
            {
              int n = min(16, prev_num_set - k);		//bugfix Dec. 19, 2001 - was 15!
              int kt = k;
              while (n--)
                p[ZAG[kt++]] = 0;
            }

            k += 15;
	    //if(k > 63) k = 63;
	    k &= 63;
          }
          else
          {
            //while (k < 64)
            //  p[ZAG[k++]] = 0;

            break;
          }
        }
      }

      if (k < prev_num_set)
      {
        int kt = k;
        while (kt < prev_num_set)
          p[ZAG[kt++]] = 0;
      }

      block_max_zag_set[row_block] = k;

      //block_num[row_block++] = k;
      row_block++;
    }
  }
}

//------------------------------------------------------------------------------
// YCbCr H1V1 (1x1:1:1, 3 blocks per MCU) to 24-bit YCbCr
void jpeg_decoder::H1V1Convert(void)
{
  int row = max_mcu_y_size - mcu_lines_left;
  uint8 *d = scan_line_0;
  uint8 *s = Psample_buf + row * 8;

  for (int i = max_mcus_per_row; i > 0; i--)
  {
    for (int j = 0; j < 8; j++)
    {
      int y = s[j];
      int cb = s[64+j];
      int cr = s[128+j];

      d[0] = y;
      d[1] = cb;
      d[2] = cr;
      d += 4;
    }

    s += 64*3;
  }
}
//------------------------------------------------------------------------------
// YCbCr H2V1 (2x1:1:1, 4 blocks per MCU) to 24-bit YCbCr
void jpeg_decoder::H2V1Convert(void)
{
  int row = max_mcu_y_size - mcu_lines_left;
  uint8 *d0 = scan_line_0;
  uint8 *y = Psample_buf + row * 8;
  uint8 *c = Psample_buf + 2*64 + row * 8;

  for (int i = max_mcus_per_row; i > 0; i--)
  {
    for (int l = 0; l < 2; l++)
    {
      for (int j = 0; j < 4; j++)
      {
        int cb = c[0];
        int cr = c[64];

        int yy = y[j<<1];
        d0[0] = yy;
        d0[1] = cb;
        d0[2] = cr;

        yy = y[(j<<1)+1];
        d0[4] = yy;
        d0[5] = cb;
        d0[6] = cr;

        d0 += 8;

        c++;
      }
      y += 64;
    }

    y += 64*4 - 64*2;
    c += 64*4 - 8;
  }
}
//------------------------------------------------------------------------------
// YCbCr H2V1 (1x2:1:1, 4 blocks per MCU) to 24-bit YCbCr
void jpeg_decoder::H1V2Convert(void)
{
  int row = max_mcu_y_size - mcu_lines_left;
  uint8 *d0 = scan_line_0;
  uint8 *d1 = scan_line_1;
  uint8 *y;
  uint8 *c;

  if (row < 8)
    y = Psample_buf + row * 8;
  else
    y = Psample_buf + 64*1 + (row & 7) * 8;

  c = Psample_buf + 64*2 + (row >> 1) * 8;

  for (int i = max_mcus_per_row; i > 0; i--)
  {
    for (int j = 0; j < 8; j++)
    {
      int cb = c[0+j];
      int cr = c[64+j];

      d0[0] = y[j];
      d0[1] = cb;
      d0[2] = cr;

      d1[0] = y[8+j];
      d1[1] = cb;
      d1[2] = cr;

      d0 += 4;
      d1 += 4;
    }

    y += 64*4;
    c += 64*4;
  }
}

//------------------------------------------------------------------------------
// Returns the next scan line.
// Returns JPGD_DONE if all scan lines have been returned.
// Returns JPGD_OKAY if a scan line has been returned.
// Returns JPGD_FAILED if an error occured.
int jpeg_decoder::decode(
  void * *Pscan_line_ofs, uint32 *Pscan_line_len)
{
  if ((error_code) || (!ready_flag))
    return (JPGD_FAILED);

  if (total_lines_left == 0)
    return (JPGD_DONE);

  if (mcu_lines_left == 0)
  {
    decode_next_row();

    transform_row();

    mcu_lines_left = max_mcu_y_size;
  }

  switch (scan_type)
  {
    case JPGD_YH2V2:
    {
      if ((mcu_lines_left & 1) == 0)
      {
        H2V2Convert();
        *Pscan_line_ofs = scan_line_0;
      }
      else
        *Pscan_line_ofs = scan_line_1;

      break;
    }
    case JPGD_YH2V1:
    {
      H2V1Convert();
      *Pscan_line_ofs = scan_line_0;
      break;
    }
    case JPGD_YH1V2:
    {
      if ((mcu_lines_left & 1) == 0)
      {
        H1V2Convert();
        *Pscan_line_ofs = scan_line_0;
      }
      else
        *Pscan_line_ofs = scan_line_1;

      break;
    }
    case JPGD_YH1V1:
    {
      H1V1Convert();
      *Pscan_line_ofs = scan_line_0;
      break;
    }
  }

  *Pscan_line_len = real_dest_bytes_per_scan_line;

  mcu_lines_left--;
  total_lines_left--;

  return (JPGD_OKAY);
}
//------------------------------------------------------------------------------
// Creates the tables needed for efficient Huffman decoding.
void jpeg_decoder::make_huff_table(
  int index,
  Phuff_tables_t hs)
{
  int p, i, l, si;
  uint8 huffsize[257];
  uint32 huffcode[257];
  uint32 code;
  uint32 subtree;
  int code_size;
  int lastp;
  int nextfreeentry;
  int currententry;

  p = 0;

  for (l = 1; l <= 16; l++)
  {
    for (i = 1; i <= huff_num[index][l]; i++)
      huffsize[p++] = l;
  }

  huffsize[p] = 0;

  lastp = p;

  code = 0;
  si = huffsize[0];
  p = 0;

  while (huffsize[p])
  {
    while (huffsize[p] == si)
    {
      huffcode[p++] = code;
      code++;
    }

    code <<= 1;
    si++;
  }

  memset(hs->look_up, 0, sizeof(hs->look_up));
  memset(hs->tree, 0, sizeof(hs->tree));
  memset(hs->code_size, 0, sizeof(hs->code_size));

  nextfreeentry = -1;

  p = 0;

  while (p < lastp)
  {
    i = huff_val[index][p];
    code = huffcode[p];
    code_size = huffsize[p];

    hs->code_size[i] = code_size;

    if (code_size <= 8)
    {
      code <<= (8 - code_size);

      for (l = 1 << (8 - code_size); l > 0; l--)
      {
        hs->look_up[code] = i;
        code++;
      }
    }
    else
    {
      subtree = (code >> (code_size - 8)) & 0xFF;

      currententry = hs->look_up[subtree];

      if (currententry == 0)
      {
        hs->look_up[subtree] = currententry = nextfreeentry;

        nextfreeentry -= 2;
      }

      code <<= (16 - (code_size - 8));

      for (l = code_size; l > 9; l--)
      {
        if ((code & 0x8000) == 0)
          currententry--;

        if (hs->tree[-currententry - 1] == 0)
        {
          hs->tree[-currententry - 1] = nextfreeentry;

          currententry = nextfreeentry;

          nextfreeentry -= 2;
        }
        else
          currententry = hs->tree[-currententry - 1];

        code <<= 1;
      }

      if ((code & 0x8000) == 0)
        currententry--;

      hs->tree[-currententry - 1] = i;
    }

    p++;
  }
}
//------------------------------------------------------------------------------
// Verifies the quantization tables needed for this scan are available.
void jpeg_decoder::check_quant_tables(void)
{
  int i;

  for (i = 0; i < comps_in_scan; i++)
    if (quant[comp_quant[i]] == NULL)
      terminate(JPGD_UNDEFINED_QUANT_TABLE);
}
//------------------------------------------------------------------------------
// Verifies that all the Huffman tables needed for this scan are available.
void jpeg_decoder::check_huff_tables(void)
{
  int i;

  for (i = 0; i < comps_in_scan; i++)
  {
    if ((spectral_start == 0) && (huff_num[comp_dc_tab[i]] == NULL))
      terminate(JPGD_UNDEFINED_HUFF_TABLE);

    if ((spectral_end > 0) && (huff_num[comp_ac_tab[i]] == NULL))
      terminate(JPGD_UNDEFINED_HUFF_TABLE);
  }

  for (i = 0; i < JPGD_MAXHUFFTABLES; i++)
    if (huff_num[i])
    {
      if (!h[i])
        h[i] = (Phuff_tables_t)alloc(sizeof(huff_tables_t));

      make_huff_table(i, h[i]);
    }

  for (i = 0; i < blocks_per_mcu; i++)
  {
    dc_huff_seg[i] = h[comp_dc_tab[mcu_org[i]]];
    ac_huff_seg[i] = h[comp_ac_tab[mcu_org[i]]];
    component[i]   = &last_dc_val[mcu_org[i]];
  }
}
//------------------------------------------------------------------------------
// Determines the component order inside each MCU.
// Also calcs how many MCU's are on each row, etc.
void jpeg_decoder::calc_mcu_block_order(void)
{
  int component_num, component_id;
  int max_h_samp = 0, max_v_samp = 0;

  for (component_id = 0; component_id < comps_in_frame; component_id++)
  {
    if (comp_h_samp[component_id] > max_h_samp)
      max_h_samp = comp_h_samp[component_id];

    if (comp_v_samp[component_id] > max_v_samp)
      max_v_samp = comp_v_samp[component_id];
  }

  for (component_id = 0; component_id < comps_in_frame; component_id++)
  {
    comp_h_blocks[component_id] = ((((image_x_size * comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
    comp_v_blocks[component_id] = ((((image_y_size * comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
  }

  mcus_per_row = (((image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
  mcus_per_col = (((image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;

  blocks_per_mcu = 0;

  for (component_num = 0; component_num < comps_in_scan; component_num++)
  {
   int num_blocks;

   num_blocks = comp_h_samp[component_num] * comp_v_samp[component_num];

   while (num_blocks--)
    mcu_org[blocks_per_mcu++] = component_num;
  }
}
//------------------------------------------------------------------------------
// Starts a new scan.
int jpeg_decoder::init_scan(void)
{
  calc_mcu_block_order();

  check_huff_tables();

  check_quant_tables();

  memset(last_dc_val, 0, comps_in_frame * sizeof(uint32));

  eob_run = 0;

  return TRUE;
}
//------------------------------------------------------------------------------
// Starts a frame. Determines if the number of components or sampling factors
// are supported.
void jpeg_decoder::init_frame(void)
{
  int i;
  uint8 *q;

    if ( ((comp_h_samp[1] != 1) || (comp_v_samp[1] != 1)) ||
         ((comp_h_samp[2] != 1) || (comp_v_samp[2] != 1)) )
      terminate(JPGD_UNSUPPORTED_SAMP_FACTORS);

    if ((comp_h_samp[0] == 1) && (comp_v_samp[0] == 1))
    {
      scan_type          = JPGD_YH1V1;

      max_blocks_per_mcu = 3;

      max_mcu_x_size     = 8;
      max_mcu_y_size     = 8;
    }
    else if ((comp_h_samp[0] == 2) && (comp_v_samp[0] == 1))
    {
      scan_type          = JPGD_YH2V1;

      max_blocks_per_mcu = 4;

      max_mcu_x_size     = 16;
      max_mcu_y_size     = 8;
    }
    else if ((comp_h_samp[0] == 1) && (comp_v_samp[0] == 2))
    {
      scan_type          = JPGD_YH1V2;

      max_blocks_per_mcu = 4;

      max_mcu_x_size     = 8;
      max_mcu_y_size     = 16;
    }
    else if ((comp_h_samp[0] == 2) && (comp_v_samp[0] == 2))
    {
      scan_type          = JPGD_YH2V2;

      max_blocks_per_mcu = 6;

      max_mcu_x_size     = 16;
      max_mcu_y_size     = 16;
    }
    else
      terminate(JPGD_UNSUPPORTED_SAMP_FACTORS);

  max_mcus_per_row = (image_x_size + (max_mcu_x_size - 1)) / max_mcu_x_size;
  max_mcus_per_col = (image_y_size + (max_mcu_y_size - 1)) / max_mcu_y_size;

  /* these values are for the *destination* pixels: after conversion */

  dest_bytes_per_pixel = 4;

  dest_bytes_per_scan_line = ((image_x_size + 15) & 0xFFF0) * dest_bytes_per_pixel;

  real_dest_bytes_per_scan_line = (image_x_size * dest_bytes_per_pixel);

  // Initialize two scan line buffers.
  // FIXME: Only the V2 sampling factors need two buffers.
  scan_line_0         = (uint8 *)alloc(dest_bytes_per_scan_line + 8);
  memset(scan_line_0, 0, dest_bytes_per_scan_line);

  scan_line_1         = (uint8 *)alloc(dest_bytes_per_scan_line + 8);
  memset(scan_line_1, 0, dest_bytes_per_scan_line);

  max_blocks_per_row = max_mcus_per_row * max_blocks_per_mcu;

  // Should never happen
  if (max_blocks_per_row > JPGD_MAXBLOCKSPERROW)
    terminate(JPGD_ASSERTION_ERROR);

  // Allocate the coefficient buffer, enough for one row's worth of MCU's
  q = (uint8 *)alloc(max_blocks_per_row * 64 * sizeof(BLOCK_TYPE));

  // The block_seg[] array's name dates back to the
  // 16-bit assembler implementation. "seg" stood for "segment".
  for (i = 0; i < max_blocks_per_row; i++)
    block_seg[i] = (BLOCK_TYPE *)(q + i * 64 * sizeof(BLOCK_TYPE));

  for (i = 0; i < max_blocks_per_row; i++)
    block_max_zag_set[i] = 64;

  Psample_buf = (uint8 *)alloc(max_blocks_per_row * 64);

  total_lines_left = image_y_size;

  mcu_lines_left = 0;
}

//------------------------------------------------------------------------------
void jpeg_decoder::init_sequential(void)
{
  if (!init_scan())
    terminate(JPGD_UNEXPECTED_MARKER);
}
//------------------------------------------------------------------------------
void jpeg_decoder::decode_start(void)
{
  init_frame();

  init_sequential();
}
//------------------------------------------------------------------------------
// Find the start of the JPEG file and reads enough data to determine
// its size, number of components, etc.
void jpeg_decoder::decode_init(void)
{
  init();
}

//------------------------------------------------------------------------------
// Call get_error_code() after constructing to determine if the stream
// was valid or not. You may call the get_width(), get_height(), etc.
// methods after the constructor is called.
// You may then either destruct the object, or begin decoding the image
// by calling begin(), then decode().
jpeg_decoder::jpeg_decoder(void)
{
  decode_init();
}
//------------------------------------------------------------------------------
// If you wish to decompress the image, call this method after constructing
// the object. If JPGD_OKAY is returned you may then call decode() to
// fetch the scan lines.
int jpeg_decoder::begin(void)
{
  if (ready_flag)
    return (JPGD_OKAY);

  if (error_code)
    return (JPGD_FAILED);

  decode_start();

  ready_flag = true;

  return (JPGD_OKAY);
}
//------------------------------------------------------------------------------
// Completely destroys the decoder object. May be called at any time.
jpeg_decoder::~jpeg_decoder()
{
  free_all_blocks();
}
//------------------------------------------------------------------------------

