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

📄 jpgencoder.~cpp

📁 Jpeg编解码器的源代码
💻 ~CPP
📖 第 1 页 / 共 5 页
字号:
      {
        // Cb Component Validation
        if ((image_scans [scan_count].component_mask & (1<<CBCOMPONENT)) != 0)
        {
          if (image_scans [scan_count].spectral_selection_end == 0)
          {
            if (lastcb != -1)
              throw JpegError ("Duplicate Cb Component Scan") ;

            image_scans [scan_count].spectral_selection_start = 0 ;
            lastcb = 0 ;
          }
          else
          {
            if (image_scans [scan_count].component_mask != (1<<CBCOMPONENT))
              throw JpegError ("Multiple Components in AC Scan") ;

            if (image_scans [scan_count].spectral_selection_end != 0 && lastcb == -1)
              throw JpegError ("AC Scan specified before DC scan for cb Component") ;

            if (image_scans [scan_count].spectral_selection_end <= lastcb)
            {
              throw JpegError (
              "Duplicate or overlapping spectral selection for Cb Component") ;
            }

            image_scans [scan_count].spectral_selection_start = lastcb + 1 ;
            lastcb = image_scans [scan_count].spectral_selection_end ;
          }
        }

        // Cr Component Validation
        if ((image_scans [scan_count].component_mask & (1<<CRCOMPONENT)) != 0)
        {
          if (image_scans [scan_count].spectral_selection_end == 0)
          {
            if (lastcr != -1)
              throw JpegError ("Duplicate Cr Component Scan") ;

            image_scans [scan_count].spectral_selection_start = 0 ;
            lastcr = 0 ;
          }
          else
          {
            if (image_scans [scan_count].component_mask != (1<<CRCOMPONENT))
              throw JpegError ("Multiple Components in AC Scan") ;

            if (image_scans [scan_count].spectral_selection_end != 0
                && lastcr== -1)
            {
              throw JpegError (
                      "AC Scan specified before DC scan for Cr Component") ;
            }

            if (image_scans [scan_count].spectral_selection_end <= lastcr)
            {
              throw JpegError (
             "Duplicate or overlapping spectral selection for Cr Component") ;
            }
            image_scans [scan_count].spectral_selection_start = lastcr + 1 ;
            lastcr = image_scans [scan_count].spectral_selection_end ;
          }
        }
      }
    }
    if (lasty != 63)
      throw JpegError ("Y Component not completely defined by scans") ;
    if (! gray_scale)
    {
      if (lastcb != 63)
        throw JpegError ("Cb Component not completely defined by scans") ;
      if (lastcr != 63)
        throw JpegError ("Cr Component not completely defined by scans") ;
    }
  }
  else
  {
    if (! gray_scale)
    {
      if ((image_scans [0].component_mask
          |image_scans [1].component_mask
          |image_scans [2].component_mask)
          != ALL)
      {
        throw JpegError ("Not all components specified in scans") ;
      }
      if ((image_scans [0].component_mask
           +image_scans [1].component_mask
           +image_scans [2].component_mask)
          != ALL)
      {
        throw JpegError ("Component in more than one scan") ;
      }
      if (image_scans [2].component_mask != 0)
        scan_count = 3 ;
      else if (image_scans [1].component_mask != 0)
        scan_count = 2 ;
      else
        scan_count = 1 ;
    }
    else
    {
      scan_count = 1 ;
    }
  }

  // Enforce the MCU size limitation in Section B.2.3
  //
  // I am not certain why this limitation of 10 data units per MCU even
  // exists. It seems to be an silly arbitrary limit. Maybe its to set
  // a maximum upper size for an MCU decoding buffer. In any event we
  // must abide by it.
  if (! gray_scale)
  {
    for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
    {
      unsigned int dataunits = 0 ;
      unsigned int componentcount = 0 ;
      if ((image_scans [ii].component_mask & (1<<YCOMPONENT)) != 0)
      {
        dataunits += image_components [YCOMPONENT].getHorizontalFrequency ()
                     * image_components [YCOMPONENT].getVerticalFrequency () ;
        ++ componentcount ;
      }
      if ((image_scans [ii].component_mask & (1<<CBCOMPONENT)) != 0)
      {
        dataunits += image_components [CBCOMPONENT].getHorizontalFrequency ()
                  * image_components [CBCOMPONENT].getVerticalFrequency () ;
        ++ componentcount ;
      }
      if ((image_scans [ii].component_mask & (1<<CRCOMPONENT)) != 0)
      {
        dataunits += image_components [CRCOMPONENT].getHorizontalFrequency ()
                  * image_components [CRCOMPONENT].getVerticalFrequency () ;
        ++ componentcount ;
      }
      if (dataunits > JPEGMAXDATAUNITSPERMCU && componentcount > 1)
        throw JpegError ("Data units in MCU exceeds 10") ;
    }
  }
  return ;
}
//
//  描述:
//
//    This function writes a comment marker to the output stream.
//
//  Parameters:
//    str:  The comment string
//
void JpegEncoder::printComment (JpegOutputStream &outputstream, const std::string &str)
{
  unsigned int length = sizeof (UBYTE2) + str.length () + 1 ;
  outputMarker (outputstream, COM) ;
  outputstream.writeBigEndianWord (length) ;
  outputstream.write (str.c_str (), str.length ()) ;
  outputstream.writeByte (0) ; // Terminator
  return ;
}


//
//  Description:
//
//    This function writes the quantization tables to the output stream.
//
void JpegEncoder::printQuantizationTables (JpegOutputStream &outputstream)
{
  const int precision = 0 ; // Byte Precision
  UBYTE1 pqtq ;

  // Count the number of quantization tables needed by the frame and
  // create the scaled version of the table used in the DCT.
  unsigned int tablecount = 0 ;
  for (unsigned int ii = 0 ; ii < JPEGMAXQUANTIZATIONTABLES ; ++ ii)
  {
    if (quantization_tables [ii].isUsed ())
      ++ tablecount ;
  }

  // Section B.2.4.1
  outputMarker (outputstream, DQT) ;
  outputstream.writeBigEndianWord (sizeof(UBYTE2) + tablecount * (sizeof (pqtq) + JPEGSAMPLESIZE)) ;

BILLSELLSPOOP
  for (unsigned int ii = 0 ; ii < JPEGMAXQUANTIZATIONTABLES ; ++ ii)
  {
    if (quantization_tables [ii].isUsed ())
    {
      pqtq = (precision << 4) | ii ;
      outputstream.writeByte (pqtq) ;
      for (unsigned int jj = 0 ; jj < JPEGSAMPLESIZE ; ++ jj)
        outputstream.writeByte (quantization_tables [ii][JpegZigZagInputOrder (jj)]) ;
    }
  }
ENDBILLSELLSPOOP
  return ;
}

//
//  Description:
//
//    This function is called by a scan to write a restart interval to the
//    output stream. We do not output a Define Restart Interval marker if
//    the restart interval is not changing.
//
//  Parameters:
//    restartinterval: The new restart interval
//
void JpegEncoder::outputRestartInterval (JpegOutputStream &outputstream,
                                         unsigned int restartinterval)
{
  if (restartinterval == restart_interval)
    return ;
  restart_interval =  restartinterval ;

  // B.2.4.4
  outputMarker (outputstream, DRI) ;
  outputstream.writeBigEndianWord (4) ;
  outputstream.writeBigEndianWord (restartinterval) ;
  return ;
}


//
//  Description:
//
//    This function writes a sequential frame to the output stream. We create
//    frames with either one (black & white) or three (color) components.
//
//  Parameters:
//    image: The image to be written in the frame
//
void JpegEncoder::printSequentialFrame (JpegOutputStream &outputstream,
                                        const BitmapImage &image)
{
  // Sample the components
  if (gray_scale)
  {
    ++ current_pass ;
    ++ current_pass ;
    JpegEncoderComponent::grayScaleConvert (*this,
                                            image, 
                                            image_components [YCOMPONENT]) ;
  }
  else
  {
    ++ current_pass ;
    JpegEncoderComponent::rgbConvert (*this,
                                      image, 
                                      max_horizontal_frequency,
                                      max_vertical_frequency,
                                      image_components [YCOMPONENT], 
                                      image_components [CBCOMPONENT], 
                                      image_components [CRCOMPONENT]) ;
    ++ current_pass ;
    image_components [YCOMPONENT].sampleComponent (*this,
                                                    max_horizontal_frequency,
                                                    max_vertical_frequency) ;
    ++ current_pass ;
    image_components [CBCOMPONENT].sampleComponent (*this,
                                                    max_horizontal_frequency,
                                                    max_vertical_frequency) ;
    ++ current_pass ;
    image_components [CRCOMPONENT].sampleComponent (*this,
                                                    max_horizontal_frequency,
                                                    max_vertical_frequency) ;
  }

  // Write the Frame Header
  // Section B.2.2

  outputMarker (outputstream, SOF0) ;
  if (gray_scale)  // Length
    outputstream.writeBigEndianWord (8 + 3) ;
  else
    outputstream.writeBigEndianWord (8 + 3 * 3) ;

  outputstream.writeByte (8) ; // Precision
  outputstream.writeBigEndianWord (image.getHeight ()) ;
  outputstream.writeBigEndianWord (image.getWidth ()) ;

  if (gray_scale)
  {
    outputstream.writeByte (1) ;  // Component Count
    outputstream.writeByte(YCOMPONENT) ;
    outputstream.writeByte (
        (image_components [YCOMPONENT].getHorizontalFrequency () << 4)
        | image_components [YCOMPONENT].getVerticalFrequency ()) ;
    outputstream.writeByte (quantization_table_assignments [YCOMPONENT]) ;


    printQuantizationTables (outputstream) ;
    scan_component_count = 1 ;
    scan_components [0] = &image_components [YCOMPONENT] ;
    ++ current_pass ;
    printSequentialScan (outputstream, image_scans [0]) ;
  }
  else
  {
    outputstream.writeByte (3) ;  // Component Count
    outputstream.writeByte(YCOMPONENT) ;
    outputstream.writeByte (
        (image_components [YCOMPONENT].getHorizontalFrequency () << 4)
        | image_components [YCOMPONENT].getVerticalFrequency ()) ;
    outputstream.writeByte (quantization_table_assignments [YCOMPONENT]) ;

    outputstream.writeByte(CBCOMPONENT) ;
    outputstream.writeByte (
        (image_components [CBCOMPONENT].getHorizontalFrequency () << 4)
        | image_components [CBCOMPONENT].getVerticalFrequency ()) ;
    outputstream.writeByte (quantization_table_assignments [CBCOMPONENT]) ;

    outputstream.writeByte(CRCOMPONENT) ;
    outputstream.writeByte (
        (image_components [CRCOMPONENT].getHorizontalFrequency () << 4)
        | image_components [CRCOMPONENT].getVerticalFrequency ()) ;
    outputstream.writeByte (quantization_table_assignments [CRCOMPONENT]) ;

    printQuantizationTables (outputstream) ;

    // Print the scans that make up the frame.
    for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
    {
      ++ current_pass ;
      if (image_scans [ii].component_mask != 0)
      {
        findComponentsInScan (image_scans [ii]) ;
        printSequentialScan (outputstream, image_scans [ii]) ;
      }
    }
  }

  return ;
}

//
//  Description:
//
//    This function writes a progressive frame to the output stream.
//
//  Parameters:
//    image: The image to be written in the frame
//
void JpegEncoder::printProgressiveFrame (JpegOutputStream &outputstream,
                                         const BitmapImage &image)
{
  if (gray_scale)
  {
    ++ current_pass ;
    JpegEncoderComponent::grayScaleConvert (*this,
                                            image, 
                                            image_components [YCOMPONENT]) ;
    // Output JPEG SOF Marker
    // Section B.2.2
    outputMarker (outputstream, SOF2) ;
    outputstream.writeBigEndianWord (8 + 3) ;  

    outputstream.writeByte (8) ; // Precision
    outputstream.writeBigEndianWord (image.getHeight ()) ;
    outputstream.writeBigEndianWord (image.getWidth ()) ;

    outputstream.writeByte (1) ;  // Component Count
    outputstream.writeByte(YCOMPONENT) ;
    outputstream.writeByte (
        (image_components [YCOMPONENT].getHorizontalFrequency () << 4)
        | image_components [YCOMPONENT].getVerticalFrequency ()) ;
    outputstream.writeByte (quantization_table_assignments [YCOMPONENT]) ;

    printQuantizationTables (outputstream) ;

    scan_component_count = 1 ;
    scan_components [0] = &image_components [YCOMPONENT] ;

    bool doingwork ;
    do
    {
      doingwork = false ;
      for (unsigned int ii = 0 ; ii < scan_count ; ++ ii)
      {
        if ((image_scans [ii].component_mask & (1<<YCOMPONENT)) != 0
             && image_scans [ii].successive_approximation_low >= 0)
        {
          ++ current_pass ;
          printProgressiveScan (outputstream, image_scans [ii]) ;
          doingwork = true ;
          image_scans [ii].successive_approximation_high
            = image_scans [ii].successive_approximation_low ;
          -- image_scans [ii].successive_approximation_low ;
        }
      }
    } while (doingwork) ;
  }
  else
  {
    ++ current_pass ;
    JpegEncoderComponent::rgbConvert (*this,
                                      image, 
                                      max_horizontal_frequency,

⌨️ 快捷键说明

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