void Scan::InstallDefaults(UBYTE depth,ULONG tagoffset,const struct JPG_TagItem *tags)
{
  bool ishuffman    = false;
  bool ispredictive = false;
  bool isjpegls     = false;
  bool colortrafo   = m_pFrame->TablesOf()->hasSeparateChroma(m_pFrame->DepthOf());
  ScanType type     = m_pFrame->ScanTypeOf();

  assert(m_pParser == NULL);
  
  switch(type) {
  case Baseline:
  case Sequential:
  case Progressive:
  case DifferentialSequential:
  case DifferentialProgressive:
  case Residual:
  case ResidualProgressive:
  case ResidualDCT:
    ishuffman    = true;
    break;
  case Lossless:
  case DifferentialLossless:
    ishuffman    = true;
    ispredictive = true;
    break;
  case ACSequential:
  case ACProgressive:
  case ACDifferentialSequential:
  case ACDifferentialProgressive:
  case ACResidual:
  case ACResidualProgressive:
  case ACResidualDCT:
    break;
  case ACLossless:
  case ACDifferentialLossless:
    ispredictive = true;
    break;
  case JPEG_LS:
    ispredictive = true;
    isjpegls     = true;
    break;
  default:
    JPG_THROW(NOT_IMPLEMENTED,"Scan::InstallDefaults",
              "sorry, unknown frame type, not yet implemented");
  }

  if (depth < 1 || depth > 4)
    JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
              "JPEG allows only between one and four components per scan");

  m_ucCount = depth;
  
  if (isjpegls) {
    // None of the below required. 
  } else if (ishuffman) {
    m_pHuffman     = new(m_pEnviron) HuffmanTable(m_pEnviron);
  } else {
    m_pConditioner = new(m_pEnviron) ACTable(m_pEnviron);
  }
  
  switch(type) {
  case Progressive:
  case ACProgressive:
  case DifferentialProgressive:
  case ACDifferentialProgressive:
    m_ucScanStart = 0;
    m_ucScanStop  = 0; // DC only. User must create other scans manually.
    m_ucHighBit   = 0;
    m_ucLowBit    = 0; 
    break;
  case Baseline:
  case Sequential: 
  case ACSequential:
  case DifferentialSequential:
  case ACDifferentialSequential:
  case Residual:
  case ACResidual:
  case ResidualProgressive:
  case ACResidualProgressive:
  case ResidualDCT:
  case ACResidualDCT:
    // Install default start and stop of scan for a sequential run.
    m_ucScanStart = 0;
    m_ucScanStop  = 63;
    m_ucHighBit   = 0;
    m_ucLowBit    = 0; 
    break;
  case Lossless:
  case ACLossless:
    m_ucScanStart = 4; // predictor to use. This is the default.
    m_ucScanStop  = 0; // shall be zero
    m_ucHighBit   = 0; // shall be zero
    m_ucLowBit    = 0; // point transform.
    break;
  case DifferentialLossless:
  case ACDifferentialLossless:
    m_ucScanStart = 0; // no predictor at all.
    m_ucScanStop  = 0; // shall be zero
    m_ucHighBit   = 0; // shall be zero
    m_ucLowBit    = 0; // point transform.
    break;
  case JPEG_LS:
    m_ucScanStart = 0; // default is lossless
    m_ucScanStop  = 0; // not interleaved
    m_ucHighBit   = 0; // shall be zero
    m_ucLowBit    = 0; // point transform.
    break;
  default:
    assert(!"unimplemented scan type");
    break;
  }
  //
  // Get the tags.
  m_ucComponent[0] = tags->GetTagData(JPGTAG_SCAN_COMPONENT0            ,0);
  m_ucComponent[1] = tags->GetTagData(JPGTAG_SCAN_COMPONENT1            ,1);
  m_ucComponent[2] = tags->GetTagData(JPGTAG_SCAN_COMPONENT2            ,2);  
  m_ucComponent[3] = tags->GetTagData(JPGTAG_SCAN_COMPONENT3            ,3);
  m_ucComponent[0] = tags->GetTagData(JPGTAG_SCAN_COMPONENT0 + tagoffset,m_ucComponent[0]);
  m_ucComponent[1] = tags->GetTagData(JPGTAG_SCAN_COMPONENT1 + tagoffset,m_ucComponent[1]);
  m_ucComponent[2] = tags->GetTagData(JPGTAG_SCAN_COMPONENT2 + tagoffset,m_ucComponent[2]);  
  m_ucComponent[3] = tags->GetTagData(JPGTAG_SCAN_COMPONENT3 + tagoffset,m_ucComponent[3]);
  m_ucHiddenBits   = m_pFrame->TablesOf()->HiddenDCTBitsOf();
  //
  // Install the Huffman table specifications
  // There are only two tables used here, thus this is always fine for baseline.
  for(UBYTE i = 0;i < depth;i++) {
    UBYTE c = m_ucComponent[i]; // get the component.

    if (/*ishuffman &&*/ colortrafo) {
      m_ucDCTable[i] = (c == 0)?(0):(1);
    } else {
      m_ucDCTable[i] = 0;
    }
    //
    // AC coding not required for predictive.
    if (/*ishuffman &&*/ !ispredictive && colortrafo) {
      m_ucACTable[i] = (c == 0)?(0):(1);
    } else {
      m_ucACTable[i] = 0;
    }
  } 
  //
  // Install and check the scan parameters for the progressive scan.
  switch(type) {
  case Progressive:
  case ACProgressive:
  case DifferentialProgressive:
  case ACDifferentialProgressive:
  case ResidualProgressive:
  case ACResidualProgressive:
    m_ucScanStart    = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_START            ,m_ucScanStart);
    m_ucScanStop     = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_STOP             ,m_ucScanStop);    
    m_ucScanStart    = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_START + tagoffset,m_ucScanStart);
    m_ucScanStop     = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_STOP  + tagoffset,m_ucScanStop);
    //
    if (type != ResidualProgressive && type != ACResidualProgressive) {
      if (m_ucScanStart == 0 && m_ucScanStop)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "DC coefficients must be in a separate scan in the progressive mode");
      if (m_ucScanStart && m_ucScanStop < m_ucScanStart)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "Spectral selection stop must be larger or equal than spectral selection start");
      if (m_ucScanStart && m_ucCount > 1)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "In the progressive mode, the AC components must be coded in all separate scans");
    } else {
      if (m_ucScanStop < m_ucScanStart)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "Spectral selection stop must be larger or equal than spectral selection start");
    }
    if (m_ucScanStop >= 64)
      JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
                "Spectral selection stop is out of range, must be <= 63");

    m_ucHighBit      = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_HI            ,m_ucHighBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_LO            ,m_ucLowBit);
    m_ucHighBit      = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_HI + tagoffset,m_ucHighBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_LO + tagoffset,m_ucLowBit);
    if (m_ucHighBit > 0 && m_ucHighBit != m_ucLowBit + 1)
      JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                "Successive approximation refinement must include only a single bitplane");
    //
    break;
  case JPEG_LS:
    // This is the NEAR value of LS. Note that this is never a residual scan.
    m_ucScanStart = tags->GetTagData(JPGTAG_IMAGE_ERRORBOUND,0);
    switch(tags->GetTagData(JPGTAG_SCAN_LS_INTERLEAVING)) {
    case JPGFLAG_SCAN_LS_INTERLEAVING_NONE:
      m_ucScanStop = 0;
      break;
    case JPGFLAG_SCAN_LS_INTERLEAVING_LINE:
      m_ucScanStop = 1;
      break;
    case JPGFLAG_SCAN_LS_INTERLEAVING_SAMPLE:
      m_ucScanStop = 2;
      break;
     default:
      JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                "Invalid component interleaving mode for JPEG LS scans");
      break;
    }
    // Runs into the following to read the point transformation.
  case Lossless:
  case ACLossless:
  case DifferentialLossless:
  case ACDifferentialLossless:
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_POINTTRANSFORM            ,m_ucLowBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_POINTTRANSFORM + tagoffset,m_ucLowBit);
    if (m_ucLowBit >= m_pFrame->PrecisionOf())
      JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
                "Point transformation removes more bits than available in the source data");
  default:
    break;
  }

  if (m_pParser)
    JPG_THROW(OBJECT_EXISTS,"Scan::CompleteSettings",
              "Settings are already installed and active");
  
  CreateParser();
}
void Scan::InstallDefaults(UBYTE depth,ULONG tagoffset,const struct JPG_TagItem *tags)
{
  bool ishuffman    = false;
  bool ispredictive = false;
  bool isjpegls     = false;
  bool colortrafo   = m_pFrame->TablesOf()->hasSeparateChroma(m_pFrame->DepthOf());
  ScanType type     = m_pFrame->ScanTypeOf();

  assert(m_pParser == NULL);
  
  switch(type) {
  case Baseline:
  case Sequential:
  case Progressive:
  case DifferentialSequential:
  case DifferentialProgressive:
  case Residual:
  case ResidualProgressive:
  case ResidualDCT:
    ishuffman    = true;
    break;
  case Lossless:
  case DifferentialLossless:
    ishuffman    = true;
    ispredictive = true;
    break;
  case ACSequential:
  case ACProgressive:
  case ACDifferentialSequential:
  case ACDifferentialProgressive:
  case ACResidual:
  case ACResidualProgressive:
  case ACResidualDCT:
    break;
  case ACLossless:
  case ACDifferentialLossless:
    ispredictive = true;
    break;
  case JPEG_LS:
    ispredictive = true;
    isjpegls     = true;
    break;
  default:
    JPG_THROW(NOT_IMPLEMENTED,"Scan::InstallDefaults",
              "sorry, unknown frame type, not yet implemented");
  }

  if (depth < 1 || depth > 4)
    JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
              "JPEG allows only between one and four components per scan");

  m_ucCount = depth;
  
  if (isjpegls) {
     
  } else if (ishuffman) {
    m_pHuffman     = new(m_pEnviron) HuffmanTable(m_pEnviron);
  } else {
    m_pConditioner = new(m_pEnviron) ACTable(m_pEnviron);
  }
  
  switch(type) {
  case Progressive:
  case ACProgressive:
  case DifferentialProgressive:
  case ACDifferentialProgressive:
    m_ucScanStart = 0;
    m_ucScanStop  = 0;  
    m_ucHighBit   = 0;
    m_ucLowBit    = 0; 
    break;
  case Baseline:
  case Sequential: 
  case ACSequential:
  case DifferentialSequential:
  case ACDifferentialSequential:
  case Residual:
  case ACResidual:
  case ResidualProgressive:
  case ACResidualProgressive:
  case ResidualDCT:
  case ACResidualDCT:
     
    m_ucScanStart = 0;
    m_ucScanStop  = 63;
    m_ucHighBit   = 0;
    m_ucLowBit    = 0; 
    break;
  case Lossless:
  case ACLossless:
    m_ucScanStart = 4;  
    m_ucScanStop  = 0;  
    m_ucHighBit   = 0;  
    m_ucLowBit    = 0;  
    break;
  case DifferentialLossless:
  case ACDifferentialLossless:
    m_ucScanStart = 0;  
    m_ucScanStop  = 0;  
    m_ucHighBit   = 0;  
    m_ucLowBit    = 0;  
    break;
  case JPEG_LS:
    m_ucScanStart = 0;  
    m_ucScanStop  = 0;  
    m_ucHighBit   = 0;  
    m_ucLowBit    = 0;  
    break;
  default:
    assert(!"unimplemented scan type");
    break;
  }
   
   
  m_ucComponent[0] = tags->GetTagData(JPGTAG_SCAN_COMPONENT0            ,0);
  m_ucComponent[1] = tags->GetTagData(JPGTAG_SCAN_COMPONENT1            ,1);
  m_ucComponent[2] = tags->GetTagData(JPGTAG_SCAN_COMPONENT2            ,2);  
  m_ucComponent[3] = tags->GetTagData(JPGTAG_SCAN_COMPONENT3            ,3);
  m_ucComponent[0] = tags->GetTagData(JPGTAG_SCAN_COMPONENT0 + tagoffset,m_ucComponent[0]);
  m_ucComponent[1] = tags->GetTagData(JPGTAG_SCAN_COMPONENT1 + tagoffset,m_ucComponent[1]);
  m_ucComponent[2] = tags->GetTagData(JPGTAG_SCAN_COMPONENT2 + tagoffset,m_ucComponent[2]);  
  m_ucComponent[3] = tags->GetTagData(JPGTAG_SCAN_COMPONENT3 + tagoffset,m_ucComponent[3]);
  m_ucHiddenBits   = m_pFrame->TablesOf()->HiddenDCTBitsOf();
   
   
   
  for(UBYTE i = 0;i < depth;i++) {
    UBYTE c = m_ucComponent[i];  

    if (  colortrafo) {
      m_ucDCTable[i] = (c == 0)?(0):(1);
    } else {
      m_ucDCTable[i] = 0;
    }
     
     
    if (  !ispredictive && colortrafo) {
      m_ucACTable[i] = (c == 0)?(0):(1);
    } else {
      m_ucACTable[i] = 0;
    }
  } 
   
   
  switch(type) {
  case Progressive:
  case ACProgressive:
  case DifferentialProgressive:
  case ACDifferentialProgressive:
  case ResidualProgressive:
  case ACResidualProgressive:
    m_ucScanStart    = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_START            ,m_ucScanStart);
    m_ucScanStop     = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_STOP             ,m_ucScanStop);    
    m_ucScanStart    = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_START + tagoffset,m_ucScanStart);
    m_ucScanStop     = tags->GetTagData(JPGTAG_SCAN_SPECTRUM_STOP  + tagoffset,m_ucScanStop);
     
    if (type != ResidualProgressive && type != ACResidualProgressive) {
      if (m_ucScanStart == 0 && m_ucScanStop)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "DC coefficients must be in a separate scan in the progressive mode");
      if (m_ucScanStart && m_ucScanStop < m_ucScanStart)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "Spectral selection stop must be larger or equal than spectral selection start");
      if (m_ucScanStart && m_ucCount > 1)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "In the progressive mode, the AC components must be coded in all separate scans");
    } else {
      if (m_ucScanStop < m_ucScanStart)
        JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                  "Spectral selection stop must be larger or equal than spectral selection start");
    }
    if (m_ucScanStop >= 64)
      JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
                "Spectral selection stop is out of range, must be <= 63");

    m_ucHighBit      = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_HI            ,m_ucHighBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_LO            ,m_ucLowBit);
    m_ucHighBit      = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_HI + tagoffset,m_ucHighBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_APPROXIMATION_LO + tagoffset,m_ucLowBit);
    if (m_ucHighBit > 0 && m_ucHighBit != m_ucLowBit + 1)
      JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                "Successive approximation refinement must include only a single bitplane");
     
    break;
  case JPEG_LS:
     
    m_ucScanStart = tags->GetTagData(JPGTAG_IMAGE_ERRORBOUND,0);
    switch(tags->GetTagData(JPGTAG_SCAN_LS_INTERLEAVING)) {
    case JPGFLAG_SCAN_LS_INTERLEAVING_NONE:
      m_ucScanStop = 0;
      break;
    case JPGFLAG_SCAN_LS_INTERLEAVING_LINE:
      m_ucScanStop = 1;
      break;
    case JPGFLAG_SCAN_LS_INTERLEAVING_SAMPLE:
      m_ucScanStop = 2;
      break;
     default:
      JPG_THROW(INVALID_PARAMETER,"Scan::InstallDefaults",
                "Invalid component interleaving mode for JPEG LS scans");
      break;
    }
     
  case Lossless:
  case ACLossless:
  case DifferentialLossless:
  case ACDifferentialLossless:
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_POINTTRANSFORM            ,m_ucLowBit);
    m_ucLowBit       = tags->GetTagData(JPGTAG_SCAN_POINTTRANSFORM + tagoffset,m_ucLowBit);
    if (m_ucLowBit >= m_pFrame->PrecisionOf())
      JPG_THROW(OVERFLOW_PARAMETER,"Scan::InstallDefaults",
                "Point transformation removes more bits than available in the source data");
  default:
    break;
  }

  if (m_pParser)
    JPG_THROW(OBJECT_EXISTS,"Scan::CompleteSettings",
              "Settings are already installed and active");
  
  CreateParser();
}