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

📄 jpgencoder.~cpp

📁 Jpeg编解码器的源代码
💻 ~CPP
📖 第 1 页 / 共 5 页
字号:
          0, 0,
          scan.successive_approximation_low) ;
  }
  outputstream.exitBitMode () ;
  return ;
}

//
//  Description:
//
//    This function outputs the data for a refining DC scan. This type of
//    scan is unique in that it does use Huffman encoding.
//
//
//  Parameters:
//    scan:  The structure that contains the scan parameters.
//
void JpegEncoder::printDcRefine (JpegOutputStream &outputstream, const Scan &scan)
{
  // Output the scan header.
  // Section B.2.3
  outputMarker (outputstream, SOS) ;
  outputstream.writeBigEndianWord (6 + 2 * scan_component_count) ;  // Length
  outputstream.writeByte (scan_component_count) ;


  if ((scan.component_mask & (1 << YCOMPONENT)) != 0)
  {
    outputstream.writeByte (YCOMPONENT) ;
    outputstream.writeByte (0) ; // No Huffman table is used.
  }
  if (! gray_scale)
  {
    if ((scan.component_mask & (1 << CBCOMPONENT)) != 0)
    {
      outputstream.writeByte (CBCOMPONENT) ;
      outputstream.writeByte (0) ; // No Huffman table is used.
    }
    if ((scan.component_mask & (1 << CRCOMPONENT)) != 0)
    {
      outputstream.writeByte (CRCOMPONENT) ;
      outputstream.writeByte (0) ; // No Huffman table is used.
    }
  }

  outputstream.writeByte (0) ; // Spectral Selection Start
  outputstream.writeByte (0) ; // Spectral Selection End

  int value = (scan.successive_approximation_high << 4)
            | scan.successive_approximation_low ;
  outputstream.writeByte (value) ;

  // Output the scan data.
  outputstream.enterBitMode (CHAR_BIT) ;
  if (scan_component_count != 1)
  {
    interleavedPass (
          outputstream,
          true,
          &JpegEncoderComponent::progressiveDcRefine,
          0, 0,
          0, 0,
          scan.successive_approximation_low) ;
  }
  else
  {
    noninterleavedPass (
          outputstream,
          true,
          &JpegEncoderComponent::progressiveDcRefine,
          0, 0,
          0, 0,
          scan.successive_approximation_low) ;
  }
  outputstream.exitBitMode () ;
  return ;
}

//
//  Description:
//
//    This function outputs a scan that is the first pass for a set of AC
//    coefficients.
//
//    Even though AC progressive scans cannot be interleaved, we follow the
//    convention of using Huffman Table #0 for the Y component and #1 for
//    the Cb and Cr components.
//
//
//  Parameters:
//    scan:  The structure that contains the scan parameters.
//
void JpegEncoder::printAcFirst (JpegOutputStream &outputstream, const Scan &scan)
{
  // Reset the Huffman statistics counters.
  if ((scan.component_mask & (1<<YCOMPONENT)) != 0)
  {
    ac_tables [0].reset () ;
  }
  else
  {
    ac_tables [1].reset () ;
  }

  outputRestartInterval (outputstream, restart_interval) ;

  // Gather the Huffman statistics
  firstAcData (outputstream, scan, false, &JpegEncoderComponent::gatherAcData) ;

  // Generate the Huffman statistics
  if ((scan.component_mask & (1<<YCOMPONENT)) != 0)
  {
    ac_tables [0].buildTable () ;
  }
  else
  {
    ac_tables [1].buildTable () ;
  }

  printHuffmanTables (outputstream, scan, false, true) ;

  // Section B.2.3
  outputMarker (outputstream, SOS) ;
  outputstream.writeBigEndianWord (6 + 2 * scan_component_count) ;  // Length
  outputstream.writeByte (scan_component_count) ;  // Component Count

  if ((scan.component_mask & (1<<YCOMPONENT)) != 0)
  {
    outputstream.writeByte (YCOMPONENT) ;
    outputstream.writeByte (0x00) ; // Entropy Table
  }
  else if ((scan.component_mask & (1<<CBCOMPONENT)) != 0)
  {
    outputstream.writeByte (CBCOMPONENT) ;
    outputstream.writeByte (0x11) ; // Entropy Tables
  }
  else if ((scan.component_mask & (1<<CRCOMPONENT)) != 0)
  {
    outputstream.writeByte (CRCOMPONENT) ;
    outputstream.writeByte (0x11) ; // Entropy Tables
  }

  outputstream.writeByte (scan.spectral_selection_start) ; // Spectral Selection Start
  outputstream.writeByte (scan.spectral_selection_end) ; // Spectral Selection End
  int value = (scan.successive_approximation_high << 4)
            | scan.successive_approximation_low ;
  outputstream.writeByte (value) ; // Successive Approximation

  outputstream.enterBitMode (CHAR_BIT) ;
  firstAcData (outputstream, scan, true, &JpegEncoderComponent::printAcData) ;
  outputstream.exitBitMode () ;
  return ;
}

//
//  Descriptio:
//
//    This function outputs the data for a scan that refines AC coefficients
//    through successive approximation.
//
//
//  Parameters:
//    scan:  The structure that contains the scan parameters.
//
void JpegEncoder::printAcRefine (JpegOutputStream &outputstream, const Scan &scan)
{
  // Reset the Huffman statistics counters.
  if ((scan.component_mask & (1<<YCOMPONENT)) != 0)
    ac_tables [0].reset () ;
  else
    ac_tables [1].reset () ;

  outputRestartInterval (outputstream, restart_interval) ;
  // Gather the Huffman statistics.
  refineAcData (outputstream, scan, false, &JpegEncoderComponent::gatherAcData) ;

  // Create the Huffman Table.
  if ((scan.component_mask & (1 <<YCOMPONENT)) != 0)
  {
    ac_tables [0].buildTable () ;
  }
  else
  {
    ac_tables [1].buildTable () ;
  }

  printHuffmanTables (outputstream, scan, false, true) ;  // Only output the AC table.

  // Create the scan header.
  // Section B.2.3
  outputMarker (outputstream, SOS) ;
  outputstream.writeBigEndianWord (6 + 2 * scan_component_count) ;  // Length
  outputstream.writeByte (scan_component_count) ;  // Component Count

  if ((scan.component_mask & (1<<YCOMPONENT)) != 0)
  {
    outputstream.writeByte (YCOMPONENT) ;
    outputstream.writeByte (0x00) ; // Entropy Tables
  }
  if ((scan.component_mask & (1<<CBCOMPONENT)) != 0)
  {
    outputstream.writeByte (CBCOMPONENT) ;
    outputstream.writeByte (0x11) ; // Entropy Tables
  }
  if ((scan.component_mask & (1<<CRCOMPONENT)) != 0)
  {
    outputstream.writeByte (CRCOMPONENT) ;
    outputstream.writeByte (0x11) ; // Entropy Tables
  }

  outputstream.writeByte (scan.spectral_selection_start) ; // Spectral Selection Start
  outputstream.writeByte (scan.spectral_selection_end) ; // Spectral Selection End
  int value = (scan.successive_approximation_high << 4)
            | scan.successive_approximation_low ;
  outputstream.writeByte (value) ; // Successive Approximation

  // Output the scan data.
  outputstream.enterBitMode (CHAR_BIT) ;
  refineAcData (outputstream, scan, true, &JpegEncoderComponent::printAcData) ;
  outputstream.exitBitMode () ;

  return ;
}

//
//  Description:
//
//    This function loops through the data in an initial AC scan. For
//    all scans other than AC progressive ones we use the same function for
//    this purpose. Due to the excessive complexity of AC progressive scans
//    we use a specialized function.
//
//    This function gets called twice for each scan. The first pass is used
//    to gather Huffman statistics. The second pass is to output the scan.
//    Having a common function ensures that Huffman statistics are gathered
//    in the exact same manner as the scan data is output.
//
//  Parameters:
//    scan:  The structure that contains the scan parameters.
//    outputrestarts: flag to indicate if restart markers are to be output
//    acfunction: The member function to process a data unit
//
void JpegEncoder::firstAcData (
                        JpegOutputStream &outputstream, 
                        const Scan &scan,
                        bool outputrestarts,
                        JpegEncoderComponent::ACOUTPUTFUNCTION acfunction)
{
  // We use a scale integer to keep trake of progress to lessen the
  // change that the progress increment will be zero.
  const int progressscale = 8 ;
  unsigned int progress ;
  unsigned int progressincrement ;
  if (outputrestarts)
    progress = 50 << progressscale ;
  else
    progress = 0 ;
  progressincrement = (100 << progressscale)
                    / (2 * scan_components [0]->dataUnitRows ()) ;

  scan_components [0]->resetEobRun () ;

  unsigned int intervalcount = 0 ;  // Count between restarts
  unsigned int restartmarker = 0 ;  // Value 0..7
  for (unsigned int row = 0 ;
       row < scan_components [0]->dataUnitRows () ;
       ++ row)
  {
    for (unsigned int col = 0 ;
         col < scan_components [0]->dataUnitCols () ;
         ++ col, ++ intervalcount)
    {
      // See if we are using restart markers.
      if (restart_interval != 0)
      {
        // Is a restart marker needed.
        if (intervalcount == restart_interval)
        {
          // If there are any outstanding EOB runs we flush them before the
          // restart marker. This is not explicitly stated in the JPEG
          // standard. The definition of "Restart Interval" in section 4.1
          // states that restart markers separate independent sequences,
          // something we would not have if we did not output the EOB run
          // here.
          scan_components [0]->printEobRun (acfunction) ;
          // Here we rely on the relationship RST0|n = RSTn [n = 0..7]
          // Section E.1.4
          if (outputrestarts)
            outputRestartMarker (outputstream, restartmarker) ;
          ++ restartmarker ;
          restartmarker %= 8 ;
          intervalcount = 0 ;
        }
      }

      // Process the data unit
      scan_components [0]->progressiveAcFirst (
                                row,
                                col,
                                acfunction,
                                scan.spectral_selection_start,
                                scan.spectral_selection_end,
                                scan.successive_approximation_low) ;
    }
    progress += progressincrement ;
    callProgressFunction (progress >> progressscale) ;
  }
  // If there is a final end of band run then write it out.
  scan_components [0]->printEobRun (acfunction) ;
  if (outputrestarts)
    callProgressFunction (100) ;
  else
    callProgressFunction (50) ;
  return ;
}

//
//  Description
//
//    This function loops through the DC using in a refining AC scan. For
//    all scans other than AC progressive ones we use the same function for
//    this purpose. Due to the excessive complexity of AC progressive scans
//    we use a specialized function.
//
//    This function gets called twice for each scan. The first pass is used
//    to gather Huffman statistics. The second pass is to output the scan.
//    Having a common function ensures that Huffman statistics are gathered
//    in the exact same manner as the scan data is output.
//
//  Parameters:
//    scan:  The structure that contains the scan parameters.
//    outputrestarts: flag to indicate if restart markers are to be output
//    acfunction: The member function to process a data unit
//
void JpegEncoder::refineAcData (
                      JpegOutputStream &outputstream, 
                      const Scan &scan,
                      bool outputrestarts,
                      JpegEncoderComponent::ACOUTPUTFUNCTION acfunction)
{
  // We use a scale integer to keep trake of progress to lessen the
  // change that the progress increment will be zero.
  const int progressscale = 8 ;
  unsigned int progress ;
  unsigned int progressincrement ;
  if (outputrestarts)
    progress = 50 << progressscale ;
  else
    progress = 0 ;
  progressincrement = (100 << progressscale)
                    / (2 * scan_components [0]->dataUnitRows ()) ;

  scan_components [0]->resetEobRun () ;

  unsigned int intervalcount = 0 ;  // Count between restart markers
  unsigned int restartmarker = 0 ;  // 0..7 => RST0..RST7
  for (unsigned int row = 0 ;
       row < scan_components [0]->dataUnitRows () ;
       ++ row)
  {
    for (unsigned int col = 0 ;
         col < scan_components [0]->dataUnitCols () ;
         ++ col, ++ intervalcount)
    {
      // Are we using restart markers?
      if (restart_interval != 0)
      {
        // Do we need to output a restart marker?
        if (intervalcount == restart_interval)
        {
          // If there are any outstanding EOB runs we flush them before the
          // restart marker. This is not explicitly stated in the JPEG
          // standard. The definition of "Restart Interval" in section 4.1
          // states that restart markers separate independent sequences,
          // something we would not have if we did not output the EOB run
          // here.
          scan_components [0]->printRefineEobRun (
                                    acfunction,
                                    scan.spectral_selection_start,
                                    scan.spectral_selection_end,
                                    scan.successive_approximation_low) ;
          // Section E.1.4
          if (outputrestarts)
            outputRestartMarker (outputstream, restartmarker) ;
          ++ restartmarker ;
          restartmarker %= 8 ;
          intervalcount = 0 ;
        }
      }
      scan_components [0]->progressiveAcRefine (
                                row,
                                col,
                                acfunction,
                                scan.spectral_selection_start,
                                scan.spectral_selection_end,
                                scan.successive_approximation_low

⌨️ 快捷键说明

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