⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpgdecoder.~cpp

📁 Jpeg编解码器的源代码
💻 ~CPP
📖 第 1 页 / 共 3 页
字号:

  unsigned int restartcount = 0 ;
  for (unsigned int row = 0 ;
       row < scan_components [0]->noninterleavedRows () ;
       ++ row)
  {
    callProgressFunction (row * 100 / scan_components [0]->noninterleavedRows ()) ;
    for (unsigned int col = 0 ;
         col < scan_components [0]->noninterleavedCols () ;
         ++ col, ++restartcount)
    {
      if (restart_interval != 0 && restart_interval == restartcount)
      {
        resetDcDifferences () ;
        processRestartMarker (inputstream) ;
        restartcount = 0 ;
      }
      scan_components [0]->decodeAcRefine (inputstream,
                                           row, col,
                                           sss, sse,
                                           ssa) ;
    }
  }
  return ;
}

//
//  描述:
//
//    读顺序扫描的扫描数据. All
//    we do here is determine whether or not we have an interleaved
//    or non-interleaved scan then call a function that handles
//    the scan type.

void JpegDecoder::readSequentialScanData (JpegInputStream &inputstream)
{
  expected_restart = 0 ;
  if (scanIsInterleaved ())
  {
    readSequentialInterleavedScan (inputstream) ;
  }
  else
  {
    readSequentialNonInterleavedScan (inputstream) ;
  }
  return ;
}

//
//  描述:
//
//    读交叉扫描数据.
//

void JpegDecoder::readSequentialInterleavedScan (JpegInputStream &inputstream)
{
  resetDcDifferences () ;

  unsigned int restartcount = 0 ;
  for (unsigned int mcurow = 0 ; mcurow < mcu_rows ; ++ mcurow)
  {
    callProgressFunction (mcurow * 100 / mcu_rows) ;
    for (unsigned int mcucol = 0 ; mcucol < mcu_cols ;
         ++ mcucol, ++restartcount)
    {
      if (restart_interval != 0 && restart_interval == restartcount)
      {
        processRestartMarker (inputstream) ;
        restartcount = 0 ;
      }
      for (unsigned int cc = 0 ; cc < scan_component_count ; ++ cc)
      {
        for (unsigned int cy = 0 ;
             cy < scan_components [cc]->verticalFrequency () ;
             ++ cy)
        {
          unsigned int durow = scan_components [cc]->verticalFrequency ()
                               * mcurow + cy ;
          for (unsigned int cx = 0 ;
               cx < scan_components [cc]->horizontalFrequency () ;
               ++ cx)
          {
            unsigned int ducol =
                   scan_components [cc]->horizontalFrequency ()
                   * mcucol + cx ;

            scan_components [cc]->decodeSequential (
                                      inputstream,
                                      durow,
                                      ducol) ;
          }
        }
      }
    }
  }
  return ;
}

//
//  描述:
//
//    读非交叉扫描数据
//

void JpegDecoder::readSequentialNonInterleavedScan (JpegInputStream &inputstream)
{
  resetDcDifferences () ;

  unsigned int restartcount = 0 ;
  for (unsigned int row = 0 ;
       row < scan_components [0]->noninterleavedRows () ;
       ++ row)
  {
    callProgressFunction (row * 100 / scan_components [0]->noninterleavedRows ()) ;
    for (unsigned int col = 0 ;
         col < scan_components [0]->noninterleavedCols () ;
         ++ col, ++ restartcount)
    {
      if (restart_interval != 0
          && restart_interval == restartcount)
      {
        processRestartMarker (inputstream) ;
        restartcount = 0 ;
      }
      scan_components [0]->decodeSequential (inputstream, row, col) ;
    }
  }
  return ;
}

//
//  描述:
//
//    This function resets the DC difference values for all components
//    for the current scan.
//
//    This function gets called before each scan is processed and
//    whenever a restart marker is read.
//

void JpegDecoder::resetDcDifferences ()
{
  for (unsigned int ii = 0 ; ii < scan_component_count ; ++ ii)
    scan_components [ii]->resetDcDifference () ;
  return ;
}

//
//  描述:
//
//    读一个重启动标志.
//    It gets called byte functions that read scan data whenever
//    a restart marker is expected. An exception is raise if the
//    correct restart marker is not next in the input stream.
//
void JpegDecoder::processRestartMarker (JpegInputStream &inputstream)
{
  inputstream.exitBitMode () ;
  UBYTE1 data = inputstream.getByte () ;
  if (data != 0xFF)
    throw JpegBadStream ("Missing Restart Marker") ;
  // According to E.1.2 0xFF can be used as a fill character
  // before the marker.
  while (data == 0xFF)
    data = inputstream.getByte () ;
  if (data < RST0 || data > RST7)
    throw JpegBadStream ("Missing Restart Marker") ;

  // Restart markers RST0..RST7 should come in sequence.
  if ((0x0F & data) != expected_restart)
    throw JpegBadStream ("Incorrect Restart Marker") ;

  // Move the counter to the next restart marker
  ++ expected_restart ;
  expected_restart %= 8 ;

  // Reset the DC coefficent differences to zero.
  resetDcDifferences () ;
  inputstream.enterBitMode (CHAR_BIT) ;
  return ;
}

//
//  描述:
//
//    This function reads an image from a JPEG stream. The
//    stream needs to have been opened in binary mode.
//
//  Parameters:
//    istrm: Input stream
//    image: The output image
//

void JpegDecoder::readImage (JpegInputStream &inputstream,
                             BitmapImage &image)
{
  unsigned char data ;

  current_scan = 0 ;
  scan_count = 0 ;
  current_image = &image ;

  if (progress_function != 0)
    getScanCount (inputstream) ;

  restart_interval = 0 ;  // Clear the restart interval ;
  try
  {
    processing_image = true ;
    current_image->clearImage () ;
    eoi_found = false ;
    sof_found = false ;

    // Read the required SOI and APP0 markers at the start of the image.
    readStreamHeader (inputstream) ;

    data = inputstream.getByte () ;
    while (inputstream.moreData () && ! eoi_found)
    {
      if (data == SOB)
      {
        readMarker (inputstream) ;
        if (eoi_found)
          break ;
      }
      data = inputstream.getByte () ;
      if (! inputstream.moreData ())
        throw JpegBadStream ("Premature end of file") ;
    }
  }
  catch (GraphicsAbort)
  {
    freeAllocatedResources () ;
    current_image = 0 ;
  }
  catch (...)
  {
    updateImage () ;
    freeAllocatedResources () ;
    current_image = 0 ;
    processing_image = false ;
    throw ;
  }
  updateImage () ;
  processing_image = false ;

  // Some people say we should not have this check here. If it bothers you
  // remove it.
  if (! eoi_found)
  {
    throw JpegBadStream("End of Image Marker Not Found") ;
  }
  // We do no want an exception so do not call ReadByte ()
  // Sometimes there can be trailing end of record markers.
  inputstream.read ((char *) &data, sizeof (data)) ;
  while ((data == '\r' || data == '\n') && inputstream.moreData ())
    inputstream.read ((char *) &data, sizeof (data)) ;
  if (inputstream.moreData ())
  {
    throw JpegBadStream ("Extra Data After End of Image Marker") ;
  }

  freeAllocatedResources () ;
  current_image = 0 ;
  return ;
}

//
//  描述:
//    扫描,统计扫描数目
//    This function scans a stream and counts the number of scans.  This
//    allows an exact count for a progress function.
//
void JpegDecoder::getScanCount (JpegInputStream &inputstream)
{
  // Save the stream position so we can go back
  // when we are finished.
  InputByteStream::POSITIONTYPE startpos = inputstream.tellg () ;

  // Count the number of SOS markers.
  scan_count = 0 ;
  while (inputstream.moreData ())
  {
    UBYTE1 data = inputstream.getByte () ;
    if (data == SOB)
    {
      while (data == SOB)
      {
        data = inputstream.getByte () ;
      }
      if (data == SOS)
        ++ scan_count ;
      else if (data == EOI)
        break ;
    }
  }
  // Go back to where we were in the stream.
  inputstream.seekg (startpos) ;
  return ;
}

//
//  描述:
//
//    This function writes the image data that has been read so
//    far to the image. This function gets called after reading
//    the entire image stream.  The user can also call this function
//    from a progress function to display progressive images,
//    multi-scan sequential images, or just to display the image
//    as it is being read (slow).
//

void JpegDecoder::updateImage ()
{
  if (current_image == 0)
    throw JpegError ("Not reading an image") ;

  if (current_scan > 0)
  {
    if (progressive_frame)
    {
      for (unsigned int ii = 0 ; ii < component_count ; ++ ii)
      {
        components [component_indices [ii]].progressiveInverseDct () ;
        components [component_indices [ii]].upsampleImage (use_filters) ;
      }
    }
    else
    {
      for (int ii = 0 ; ii < component_count ; ++ ii)
      {
        components [component_indices [ii]].upsampleImage (use_filters) ;
      }
    }

    switch (component_count)
    {
    case 3:
      JpegDecoderComponent::convertRgb (components [component_indices [0]],
                                        components [component_indices [1]],
                                        components [component_indices [2]],
                                        *current_image) ;
      break ;
    case 1:
      JpegDecoderComponent::convertGrayscale (
                               components [component_indices [0]],
                               *current_image) ;
      break ;
    }
  }
  return ;
}

//
//  描述:
//
//    This function frees all the memory dynamically allocated
//    during the image decoding process.
//
void JpegDecoder::freeAllocatedResources ()
{
  if (current_scan > 0)
  {
    for (unsigned int ii = 0 ; ii < component_count ; ++ ii)
    {
      components [component_indices [ii]].freeComponentBuffers () ;
    }
  }
  return ;
}

//
//  Description:
//
//    This function is only used in progressive images. It refines
//    a non-zero AC coefficient. It is called at various times while
//    processing a progressive scan that refines AC coefficients.
//
//  Parameters:
//    value: (in/out) The value to refine
//    ssa: The succesive approximation for the scan.
//    decoder: The JPEG decoder
//

void JpegDecoder::refineAcCoefficient (JpegInputStream &inputstream,
                                       BYTE2 &value,
                                       unsigned int ssa)
{
  // Section G.1.2.3
  if (value > 0)
  {
    if (inputstream.nextBit () != 0)
    {
      value += (1 << ssa) ;
    }
  }
  else if (value < 0)
  {
    if (inputstream.nextBit () != 0)
    {
      value += (-1 << ssa) ;
    }
  }
  return ;
}

void JpegDecoder::readImageFile (const std::string &filename, BitmapImage &image)
{
#if ! defined (USEMAP)
  JpegInputFileStream inputstream ;
#else
  JpegInputMapStream inputstream ;
#endif
  const char *name = filename.c_str () ;
  inputstream.open (name) ;
  if (! inputstream)
    throw JpegError ("Can't open input file") ;
  try
  {
    readImage (inputstream, image) ;
  }
  catch (InputByteStream::StreamError &error)
  {
    // Convert input stream errors to JPEG errors.
    throw JpegError (error.what ()) ;
  }
  return ;
}

bool JpegDecoder::isProgressive () const
{
  return progressive_frame ;
}

unsigned int JpegDecoder::mcuRows () const
{
  return mcu_rows ;
}

unsigned int JpegDecoder::mcuCols () const
{
  return mcu_cols ;
}

unsigned int JpegDecoder::restartInterval () const
{
  return restart_interval ;
}

unsigned int JpegDecoder::frameHeight () const
{
  return frame_height ;
}

unsigned int JpegDecoder::frameWidth () const
{
  return frame_width ;
}

unsigned int JpegDecoder::maxVFrequency () const
{
  return max_vertical_frequency ;
}

unsigned int JpegDecoder::maxHFrequency () const
{
  return max_horizontal_frequency ;
}

bool JpegDecoder::scanIsInterleaved () const
{
  if (scan_component_count != 1)
    return true ;
  else
    return false ;
}

bool JpegDecoder::getVerbose () const
{
  return verbose_flag ;
}

void JpegDecoder::setVerbose (bool value)
{
  verbose_flag = value ;
  return ;
}

bool JpegDecoder::getUseFilters () const
{
  return use_filters ;
}

void JpegDecoder::setUseFilters (bool value)
{
  use_filters = value ;
  return ;
}


} // End Namespace Colosseum

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -