Ejemplo n.º 1
0
/// Frame::ComputeMCUSizes
// Compute the MCU sizes of the components from the subsampling values
void Frame::ComputeMCUSizes(void)
{ 
  UBYTE i;
  UWORD maxx,maxy;
  
  // Compute the maximum MCU width and height.
  assert(m_ppComponent[0]);
  maxx = m_ppComponent[0]->SubXOf();
  maxy = m_ppComponent[0]->SubYOf();

  for(i = 1;i < m_ucDepth;i++) {
    assert(m_ppComponent[i]);
    maxx = m_ppComponent[i]->SubXOf() * maxx / gcd(m_ppComponent[i]->SubXOf(),maxx);
    maxy = m_ppComponent[i]->SubYOf() * maxy / gcd(m_ppComponent[i]->SubYOf(),maxy);
    if (maxx > MAX_UBYTE || maxy > MAX_UBYTE)
      JPG_THROW(OVERFLOW_PARAMETER,"Frame::ComputeMCUSizes",
		"the smallest common multiple of all subsampling factors must be smaller than 255");
  }
  
  m_ucMaxMCUWidth  = maxx;
  m_ucMaxMCUHeight = maxy;

  for(i = 0;i < m_ucDepth;i++) {
    m_ppComponent[i]->SetMCUSize(maxx,maxy);
  } 
  //
  // Check whether the scm is actually part of the MCU sizes written. If not,
  // then JPEG cannot support this subsampling setting. Wierd.
  for(i = 0;i < m_ucDepth;i++) {
    if (m_ppComponent[i]->SubXOf() != m_ucMaxMCUWidth  / m_ppComponent[i]->MCUWidthOf() ||
	m_ppComponent[i]->SubYOf() != m_ucMaxMCUHeight / m_ppComponent[i]->MCUHeightOf())
      JPG_THROW(INVALID_PARAMETER,"Frame::ComputeMCUSizes",
		"the given set of subsampling parameters is not supported by JPEG");
  }
}
Ejemplo n.º 2
0
/// HuffmanTemplate::ParseMarker
void HuffmanTemplate::ParseMarker(class ByteStream *io)
{
    ULONG i,total = 0;
    // A new decoder chain is required here.
    delete m_pDecoder;
    m_pDecoder = NULL;
    delete m_pEncoder;
    m_pEncoder = NULL;

    // Read the number of huffman codes of length i-1
    for(i = 0; i < 16U; i++) {
        LONG cnt = io->Get();
        if (cnt == ByteStream::EOF)
            JPG_THROW(MALFORMED_STREAM,"HuffmanTemplate::ParseMarker","huffman table marker run out of data");
        m_ucLengths[i] = cnt;
        total         += cnt;
    }

    m_ulCodewords = total;
    assert(m_pucValues == NULL);
    m_pucValues = (UBYTE *)m_pEnviron->AllocMem(sizeof(UBYTE) * total);

    for(i = 0; i < total; i++) {
        LONG v = io->Get();
        if (v == ByteStream::EOF)
            JPG_THROW(MALFORMED_STREAM,"HuffmanTemplate::ParseMarker","huffman table marker run out of data");
        m_pucValues[i] = v;
    }
}
Ejemplo n.º 3
0
/// Frame::DefineComponent
// Define a component for writing. Must be called exactly once per component for encoding.
// idx is the component index (not its label, which is generated automatically), and
// the component subsampling factors.
class Component *Frame::DefineComponent(UBYTE idx,UBYTE subx,UBYTE suby)
{
  if (m_ucDepth == 0)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::DefineComponent",
	      "Frame depth must be specified first before defining the component properties");

  if (m_ucPrecision == 0)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::DefineComponent",
	      "Frame precision must be specified first before defining the component properties");

  if (idx >= m_ucDepth)
    JPG_THROW(OVERFLOW_PARAMETER,"Frame::DefineComponent",
	      "component index is out of range, must be between 0 and depth-1");
  
  if (m_ppComponent == NULL) {
    m_ppComponent = (class Component **)m_pEnviron->AllocMem(sizeof(class Component *) * m_ucDepth);
    memset(m_ppComponent,0,sizeof(class Component *) * m_ucDepth);
  }

  if (m_ppComponent[idx])
    JPG_THROW(OBJECT_EXISTS,"Frame::DefineComponent",
	      "the indicated component is already defined");

  m_ppComponent[idx] = new(m_pEnviron) Component(m_pEnviron,idx,m_ucPrecision,subx,suby);

  return m_ppComponent[idx];
}
Ejemplo n.º 4
0
/// Tables::FindQuantizationTable
// Find the quantization table of the given index.
const UWORD *Tables::FindQuantizationTable(UBYTE idx) const
{
  const UWORD *t;
  
  if (m_pQuant == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Tables::FindQuantizationTable","DQT marker missing, no quantization table defined");

  t = m_pQuant->QuantizationTable(idx);
  if (t == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Tables::FindQuantizationTable","requested quantization matrix not defined");
  return t;
}
Ejemplo n.º 5
0
/// Tables::FindACHuffmanTable
// Find the AC huffman table of the indicated index.
class HuffmanTemplate *Tables::FindACHuffmanTable(UBYTE idx,ScanType type,UBYTE depth,UBYTE hidden,bool residual) const
{ 
  class HuffmanTemplate *t;

  if (m_pHuffman == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Tables::FindACHuffmanTable","DHT marker missing for huffman encoded scan");

  t = m_pHuffman->ACTemplateOf(idx,type,depth,hidden,residual);
  if (t == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Tables::FindACHuffmanTable","requested AC huffman coding table not defined");
  return t;
}
Ejemplo n.º 6
0
void BitStream<bitstuffing>::ReportError(void)
{
  class Environ *m_pEnviron = m_pIO->EnvironOf();
  
  if (m_bEOF)
    JPG_THROW(UNEXPECTED_EOF,"BitStream::ReportError",
              "invalid stream, found EOF within entropy coded segment");
  if (m_bMarker)
    JPG_THROW(UNEXPECTED_EOF,"BitStream::ReportError",
              "invalid stream, found marker in entropy coded segment");
  
  JPG_THROW(MALFORMED_STREAM,"BitStream::ReportError",
            "invalid stream, found invalid huffman code in entropy coded segment");
}
Ejemplo n.º 7
0
/// ACTemplate::ParseACMarker
// Parse off an AC conditioning parameter.
void ACTemplate::ParseACMarker(class ByteStream *io)
{ 
  LONG ac = io->Get();

  if (ac == ByteStream::EOF)
    JPG_THROW(MALFORMED_STREAM,"ACTemplate::ParseACMarker",
              "unexpected EOF while parsing off the AC conditioning parameters");

  if (ac < 1 || ac > 63)
    JPG_THROW(MALFORMED_STREAM,"ACTemplate::ParseACMarker",
              "AC conditoning parameter must be between 1 and 63");

  m_ucBlockEnd = ac;
}
Ejemplo n.º 8
0
/// PredictorBase::CreatePredictorChain
// Create a prediction chain for the given neutral value and
// the given prediction mode. The mode "none" is used to
// indicate the differential mode.
// This requires an array of four predictors to be used for
// life-time management. The first element is the initial predictor.
void PredictorBase::CreatePredictorChain(class Environ *m_pEnviron,class PredictorBase *chain[4],
                                         PredictionMode mode,UBYTE preshift,
                                         LONG neutral)
{
  if (preshift > 20)
    JPG_THROW(OVERFLOW_PARAMETER,"PredictorBase::CreatePredictorChain",
              "lossless predictive point transformation value is out of range, no code provisioned for it");
  
  assert(chain[0] == NULL && chain[1] == NULL && chain[2] == NULL && chain[3] == NULL);
  
  switch(mode) {
  case None:
    // This is differential. It only requires a single predictor.
    chain[0] = CreatePredictor(m_pEnviron,mode,preshift,0);
    assert(chain[0]);
    // This predictor stays the same no matter how we move.
    chain[0]->m_pNextRight = chain[0];
    chain[0]->m_pNextDown  = chain[0];
    break;
  case Left:
  case Top:
  case LeftTop:
  case Linear:
  case WeightA:
  case WeightB:
  case Diagonal:
    // It starts with the neutral predictor top left.
    chain[0] = CreatePredictor(m_pEnviron,Neutral,preshift,neutral);
    chain[1] = CreatePredictor(m_pEnviron,Left   ,preshift,0);
    chain[2] = CreatePredictor(m_pEnviron,Top    ,preshift,0);
    chain[3] = CreatePredictor(m_pEnviron,mode   ,preshift,0);
    assert(chain[0] && chain[1] && chain[2] && chain[3]);
    //
    // Now link them in.
    chain[0]->m_pNextRight = chain[1];
    chain[1]->m_pNextRight = chain[1];
    chain[0]->m_pNextDown  = chain[2];
    chain[1]->m_pNextDown  = chain[3];
    chain[2]->m_pNextRight = chain[3];
    chain[2]->m_pNextDown  = chain[2];
    chain[3]->m_pNextRight = chain[3];
    chain[3]->m_pNextDown  = chain[3];
    break;
  default:
    JPG_THROW(INVALID_PARAMETER,"PredictorBase::CreatePredictorChain",
              "unable to initiate a lossless predictive scan, invalid prediction mode specified");
    break;
  }
}
Ejemplo n.º 9
0
/// Frame::StartMeasureScan
// Start a measurement scan
class Scan *Frame::StartMeasureScan(void)
{
  if (m_pCurrent == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::StartMeasureScan",
	      "scan parameters have not been defined yet");
  if (m_pImage == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::StartMeasureScan",
	      "frame is currently not available for measurements");
  // 
  // Create a compatible image buffer and put it into BitmapCtrl,
  // or re-use it.
  m_pCurrent->StartMeasureScan(m_pImage);

  return m_pCurrent;
}
Ejemplo n.º 10
0
/// RestartIntervalMarker::ParseMarker
// Parse the marker from the stream.
void RestartIntervalMarker::ParseMarker(class ByteStream *io)
{
  LONG len = io->GetWord();

  if (len != 4)
    JPG_THROW(MALFORMED_STREAM,"RestartIntervalMarker::ParseMarker",
              "DRI restart interval definition marker size is invalid");

  len = io->GetWord();
  if (len == ByteStream::EOF)
    JPG_THROW(UNEXPECTED_EOF,"RestartIntervalMarker::ParseMarker",
              "DRI restart interval definition marker run out of data");

  m_usRestartInterval = UWORD(len);
}
Ejemplo n.º 11
0
/// NameSpace::AllocateMatrixID
// Allocate an ID for a nonlinarity.
UBYTE NameSpace::AllocateMatrixID(void) const
{ 
  UBYTE idx = MergingSpecBox::FreeForm;

  if (m_ppPrimaryList) {
    const class Box *box = *m_ppPrimaryList;
    while(box) {
      const class MatrixBox *matrix = dynamic_cast<const MatrixBox *>(box);
      if (matrix) {
        if (matrix->IdOf() >= idx)
          idx = matrix->IdOf() + 1;
      }
      box = box->NextOf();
    }
  }

  if (m_ppSecondaryList) {
    const class Box *box = *m_ppSecondaryList;
    while(box) {
      const class MatrixBox *matrix = dynamic_cast<const MatrixBox *>(box);
      if (matrix) {
        if (matrix->IdOf() >= idx)
          idx = matrix->IdOf() + 1;
      }
      box = box->NextOf();
    }
  }

  if (idx > 15)
    JPG_THROW(OVERFLOW_PARAMETER,"NameSpace::AllocateNonlinearityID",
              "cannot create more than 11 linear transformations");
  
  return idx;
}
Ejemplo n.º 12
0
/// NameSpace::AllocateNonlinearityID
// Allocate an ID for a nonlinarity.
UBYTE NameSpace::AllocateNonlinearityID(void) const
{
  UBYTE idx = 0;

  if (m_ppPrimaryList) {
    const class Box *box = *m_ppPrimaryList;
    while(box) {
      const class ToneMapperBox *tmo = dynamic_cast<const ToneMapperBox *>(box);
      if (tmo) {
        if (tmo->TableDestinationOf() >= idx)
          idx = tmo->TableDestinationOf() + 1;
      }
      box = box->NextOf();
    }
  }

  if (m_ppSecondaryList) {
    const class Box *box = *m_ppSecondaryList;
    while(box) {
      const class ToneMapperBox *tmo = dynamic_cast<const ToneMapperBox *>(box);
      if (tmo) {
        if (tmo->TableDestinationOf() >= idx)
          idx = tmo->TableDestinationOf() + 1;
      }
      box = box->NextOf();
    }
  }

  if (idx > 15)
    JPG_THROW(OVERFLOW_PARAMETER,"NameSpace::AllocateNonlinearityID",
              "cannot create more than 16 nonlinear point transformations");
  
  return idx;
}
Ejemplo n.º 13
0
/// ACRefinementScan::StartWriteScan
void ACRefinementScan::StartWriteScan(class ByteStream *io,class Checksum *chk,class BufferCtrl *ctrl)
{ 
#if ACCUSOFT_CODE
  int i;

  for(i = 0;i < m_ucCount;i++) {
    m_ulX[i]           = 0;
  }
  m_Context.Init();

  assert(!ctrl->isLineBased());
  m_pBlockCtrl = dynamic_cast<BlockCtrl *>(ctrl);
  m_pBlockCtrl->ResetToStartOfScan(m_pScan); 
  //
  // Actually, always:
  m_bMeasure = false;

  EntropyParser::StartWriteScan(io,chk,ctrl);

  m_pScan->WriteMarker(io);
  m_Coder.OpenForWrite(io,chk);
#else
  NOREF(io);
  NOREF(chk);
  NOREF(ctrl);
  JPG_THROW(NOT_IMPLEMENTED,"ACRefinementScan::StartWriteScan",
            "Lossless JPEG not available in your code release, please contact Accusoft for a full version");
#endif
}
Ejemplo n.º 14
0
/// LosslessScan::StartWriteScan
void LosslessScan::StartWriteScan(class ByteStream *io,class Checksum *chk,class BufferCtrl *ctrl)
{
#if ACCUSOFT_CODE
  int i;

  FindComponentDimensions();
  
  for(i = 0;i < m_ucCount;i++) {
    m_pDCCoder[i]       = m_pScan->DCHuffmanCoderOf(i);
    m_pDCStatistics[i]  = NULL;
  }
  
  assert(ctrl->isLineBased());
  m_pLineCtrl = dynamic_cast<LineBuffer *>(ctrl);
  m_pLineCtrl->ResetToStartOfScan(m_pScan); 

  EntropyParser::StartWriteScan(io,chk,ctrl);
  
  m_pScan->WriteMarker(io);
  m_Stream.OpenForWrite(io,chk); 

  m_bMeasure = false;
#else
  NOREF(io);
  NOREF(chk);
  NOREF(ctrl);
  JPG_THROW(NOT_IMPLEMENTED,"LosslessScan::StartWriteScan",
            "Lossless JPEG not available in your code release, please contact Accusoft for a full version");
#endif
}
Ejemplo n.º 15
0
/// Frame::BuildImage
// Build the image buffer type fitting to the frame type.
class BitmapCtrl *Frame::BuildImage(void)
{
  switch(m_Type) {
  case Baseline: // also sequential
  case Sequential:
  case Progressive:  
  case ACSequential:
  case ACProgressive: 
    {
      if (m_pTables->ResidualDataOf()) {
	m_pBlockHelper  = new(m_pEnviron) class ResidualBlockHelper(this);
      }
      class BlockBitmapRequester *bb = new(m_pEnviron) class BlockBitmapRequester(this); 
      bb->SetBlockHelper(m_pBlockHelper);
      return bb;
    }
  case Lossless:
  case ACLossless:
  case DifferentialLossless:
  case ACDifferentialLossless:
  case JPEG_LS:
    return new(m_pEnviron) class LineBitmapRequester(this);
  case Dimensions:
    return new(m_pEnviron) class HierarchicalBitmapRequester(this);
  default:
    break; // Everything else is part of a hierarchical scan and does not have a full image buffer by itself.
  }
  JPG_THROW(MALFORMED_STREAM,"Frame::BuildLineAdapter","found illegal or unsupported frame type");
  return NULL;
}
Ejemplo n.º 16
0
/// Frame::BuildLineAdapter
// Build the line adapter fitting to the frame type.
class LineAdapter *Frame::BuildLineAdapter(void)
{
  switch(m_Type) {
  case Baseline: // also sequential
  case Sequential:
  case Progressive:  
  case DifferentialSequential:
  case DifferentialProgressive:
  case ACSequential:
  case ACProgressive: 
  case ACDifferentialSequential:
  case ACDifferentialProgressive:
  case Residual:
  case ACResidual:
    return new(m_pEnviron) class BlockLineAdapter(this); // all block based.
  case Lossless:
  case ACLossless:
  case DifferentialLossless:
  case ACDifferentialLossless:
  case JPEG_LS:
    return new(m_pEnviron) class LineLineAdapter(this); // all line based.
  case Dimensions:
    break;
  }
  JPG_THROW(INVALID_PARAMETER,"Frame::BuildLineAdapter","found illegal or unsupported frame type");
  return NULL;
}
Ejemplo n.º 17
0
 // 
 // Buffer the original data unaltered. Required for residual coding, for some modes of
 // it at least.
 virtual void RGB2RGB(const RectAngle<LONG> &,const struct ImageBitMap *const *,
                      Buffer)
 {
   // This does not implement residual coding, code should not go here.
   JPG_THROW(INVALID_PARAMETER,"LSLosslessTrafo::RGB2RGB",
             "JPEG LS lossless color transformation does not allow residual coding");
 }
Ejemplo n.º 18
0
/// Frame::NextScan
class Scan *Frame::NextScan(void)
{
  if (m_pCurrent == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::NextScan","no scan iteration has been started, cannot advance the scan");

  return m_pCurrent = m_pCurrent->NextOf();
}
Ejemplo n.º 19
0
/// Frame::WriteFrameType
// Write the marker that identifies this type of frame, and all the scans within it.
void Frame::WriteFrameType(class ByteStream *io) const
{
  if (m_pScan == NULL)
    JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::WriteFrameType",
	      "frame parameters have not yet been installed, cannot write frame type");

  m_pScan->WriteFrameType(io);
}
Ejemplo n.º 20
0
/// ACRefinementScan::StartMeasureScan
// Measure scan statistics.
void ACRefinementScan::StartMeasureScan(class BufferCtrl *)
{ 
  //
  // This is not required.
  JPG_THROW(NOT_IMPLEMENTED,"ACRefinementScan::StartMeasureScan",
            "arithmetic coding is always adaptive and does not require "
            "to measure the statistics");
}
Ejemplo n.º 21
0
/// ACTemplate::ParseDCMarker
// Parse off DC conditioning parameters.
void ACTemplate::ParseDCMarker(class ByteStream *io)
{
  LONG dc = io->Get();
  UBYTE l,u;

  if (dc == ByteStream::EOF)
    JPG_THROW(MALFORMED_STREAM,"ACTemplate::ParseDCMarker",
              "unexpected EOF while parsing off the AC conditioning parameters");

  l = dc & 0x0f;
  u = dc >> 4;

  if (u < l)
    JPG_THROW(MALFORMED_STREAM,"ACTemplate::ParseDCMarker",
              "upper DC conditioning parameter must be larger or equal to the lower one");

  m_ucLower = l;
  m_ucUpper = u;
}
Ejemplo n.º 22
0
/// Thresholds::ParseMarker
// Parse the marker contents of a LSE marker.
void Thresholds::ParseMarker(class ByteStream *io,UWORD len)
{
  if (len != 13)
    JPG_THROW(MALFORMED_STREAM,"Thresholds::ParseMarker","LSE marker length is invalid");
  
  m_usMaxVal = io->GetWord();
  m_usT1     = io->GetWord();
  m_usT2     = io->GetWord();
  m_usT3     = io->GetWord();
  m_usReset  = io->GetWord();
}
Ejemplo n.º 23
0
/// Frame::FindComponent
// Find a component by a component identifier. Throws if the component does not exist.
class Component *Frame::FindComponent(UBYTE id) const
{
  int i;

  for(i = 0;i < m_ucDepth;i++) {
    if (m_ppComponent[i]->IDOf() == id)
      return m_ppComponent[i];
  }

  JPG_THROW(OBJECT_DOESNT_EXIST,"Frame::FindComponent","found a component ID that does not exist");
  return NULL; // dummy.
}
Ejemplo n.º 24
0
/// EXIFMarker::ParseMarker
// Parse the adobe marker from the stream
// This will throw in case the marker is not
// recognized. The caller will have to catch
// the exception.
void EXIFMarker::ParseMarker(class ByteStream *io,UWORD len)
{
  if (len < 2 + 4 + 2 + 2 + 2 + 4 + 2 + 4)
    JPG_THROW(MALFORMED_STREAM,"EXIFMarker::ParseMarker","misformed EXIF marker");

  //
  // The exif header has already been parsed off.
  len     -= 2 + 4 + 2;
  // Skip the rest of the marker.
  if (len > 0)
    io->SkipBytes(len);
}
Ejemplo n.º 25
0
/// EntropyParser::ParseDNLMarker
// Parse the DNL marker, update the frame height. If
// the result is true, the marker has been found.
bool EntropyParser::ParseDNLMarker(class ByteStream *io)
{
  LONG dt;

  if (m_bDNLFound)
    return true;
  
  dt = io->PeekWord();

  while(dt == 0xffff) {
    // A filler byte followed by the marker (hopefully). Skip the
    // filler and try again.
    io->Get();
    dt = io->PeekWord();
  }

  if (dt == 0xffdc) {
    dt = io->GetWord();
    dt = io->GetWord();
    if (dt != 4)
      JPG_THROW(MALFORMED_STREAM,"EntropyParser::ParseDNLMarker",
                "DNL marker size is out of range, must be exactly four bytes long");
    
    dt = io->GetWord();
    if (dt == ByteStream::EOF)
      JPG_THROW(UNEXPECTED_EOF,"EntropyParser::ParseDNLMarker",
                "stream is truncated, could not read the DNL marker");
    if (dt == 0)
      JPG_THROW(MALFORMED_STREAM,"EntropyParser::ParseDNLMarker",
                "frame height as indicated by the DNL marker is corrupt, must be > 0");
    
    m_pFrame->PostImageHeight(dt);

    m_bDNLFound = true;
    return true;
  } else {
    return false;
  }
}
Ejemplo n.º 26
0
/// BitmapCtrl::RequestUserData
// Request data from the user through the indicated bitmap hook
// for the given rectangle. The rectangle is first clipped to
// range (as appropriate, if the height is already known) and
// then the desired n'th component of the scan (not the component
// index) is requested.
void BitmapCtrl::RequestUserData(class BitMapHook *bmh,const RectAngle<LONG> &r,UBYTE comp)
{
  assert(comp < m_ucCount && bmh);

  bmh->RequestClientData(r,m_ppBitmap[comp],m_pFrame->ComponentOf(comp));

  if (m_ucPixelType == 0) { // Not yet defined
    m_ucPixelType = m_ppBitmap[comp]->ibm_ucPixelType;
  } else if (m_ppBitmap[comp]->ibm_ucPixelType) {
    if (m_ucPixelType != m_ppBitmap[comp]->ibm_ucPixelType) {
      JPG_THROW(INVALID_PARAMETER,"BitmapCtrl::RequestUserData","pixel types must be consistent accross components");
    }
  }
}
Ejemplo n.º 27
0
/// Component::ParseMarker
void Component::ParseMarker(class ByteStream *io)
{
  LONG data;

  data = io->Get();
  if (data == ByteStream::EOF)
    JPG_THROW(MALFORMED_STREAM,"Component::ParseMarker","frame marker incomplete, no component identifier found");

  m_ucID = data;

  data = io->Get();
  if (data == ByteStream::EOF)
    JPG_THROW(MALFORMED_STREAM,"Component::ParseMarker","frame marker incomplete, subsamling information missing");

  m_ucMCUWidth  = data >> 4;
  m_ucMCUHeight = data & 0x0f;

  data = io->Get();
  if (data < 0 || data > 3)
    JPG_THROW(MALFORMED_STREAM,"Component::ParseMarker","quantization table identifier corrupt, must be >= 0 and <= 3");

  m_ucQuantTable = data;
}
Ejemplo n.º 28
0
/// HuffmanTemplate::BuildDecoder
// Build the huffman decoder given the template data.
void HuffmanTemplate::BuildDecoder(void)
{
    class HuffmanDecoder *prev = NULL;
    ULONG i,lastbits = 0;
    UBYTE *values;
    ULONG code       = 0;

    assert(m_pDecoder == NULL);

    if (m_pucValues) {
        // If the decoder is not used, do not build it.
        assert(m_ucLengths);
        for(i = 0,values = m_pucValues; i < 16U; i++) {
            if (m_ucLengths[i]) {
                if (values + m_ucLengths[i] > m_pucValues + m_ulCodewords)
                    JPG_THROW(MALFORMED_STREAM,"HuffmanTemplate::ParseMarker","Huffman table marker depends on undefined data");
                // There are codes of this lengths.
                code += m_ucLengths[i];
                if (code >= 1UL << (i + 1))
                    JPG_THROW(MALFORMED_STREAM,"HuffmanTemplate::ParseMarker",
                              "Huffman table corrupt - entry depends on more bits than available for the bit length");
                class HuffmanDecoder *huff = new(m_pEnviron) class HuffmanDecoder(values,i+1-lastbits,
                                m_ucLengths[i]);
                if (prev) {
                    prev->ExtendBy(huff);
                } else {
                    assert(m_pDecoder == NULL);
                    m_pDecoder = huff;
                }
                prev     = huff;
                values  += m_ucLengths[i];
                lastbits = i+1;
            }
            code <<= 1;
        }
    }
}
Ejemplo n.º 29
0
/// Frame::PostImageHeight
// Define the image size if it is not yet known here. This is
// called whenever the DNL marker is parsed in.
void Frame::PostImageHeight(ULONG height)
{
  assert(height > 0 && m_pImage);
  
  if (m_ulHeight == 0) {
    m_ulHeight = height;
    m_pImage->PostImageHeight(height);
  } else if (m_ulHeight == height) {
    JPG_WARN(MALFORMED_STREAM,"Frame::PostImageHeight",
	     "found a double DNL marker for a frame, frame size is known already");
  } else {
    JPG_THROW(MALFORMED_STREAM,"Frame::PostImageHeight",
	      "found a double DNL marker for a frame, indicating an inconsistent frame height");
  }
}
Ejemplo n.º 30
0
/// ChecksumBox::ParseBoxContent
// Second level parsing stage: This is called from the first level
// parser as soon as the data is complete. Must be implemented
// by the concrete box. Returns true in case the contents is
// parsed and the stream can go away.
bool ChecksumBox::ParseBoxContent(class ByteStream *stream,UQUAD boxsize)
{
  LONG pack1,pack2;
  
  if (boxsize != 4)
    JPG_THROW(MALFORMED_STREAM,"ChecksumBox::ParseBoxContent",
              "Malformed JPEG stream, the checksum box size is invalid");
  
  pack1 = stream->GetWord();
  pack2 = stream->GetWord();
  
  m_ulCheck = ULONG(pack1 << 16) | ULONG(pack2);

  return true;
}