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

📄 jpgencodercomponent.cpp

📁 Jpeg编解码器的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }
    (this->*acfunction)(ssss << 4, bits, ssss) ;

    // Now that we have output the EOB run we need to refine each coefficient
    // that we skipped that had previously been non-zero.
    unsigned int  eobcounter = 0 ;
    unsigned int row = eob_start_du_row ;
    unsigned int col = eob_start_du_col ;
    while (eobcounter < eob_run)
    {
      JpegCoefficientBlock &du
        = dct_coefficients [row * du_cols + col] ;
      for (unsigned int kk = eob_start_position ;
           kk <= sse ;
           ++ kk)
      {
        int value = du [JpegZigZagInputOrder (kk)] / (1<< ssa) ;
        if (value < 0)
          value = - value ;
        if (value > 1)
        {
          (this->*acfunction)(-1, (value & 0x1), 1) ;
        }
      }
      // Except for the first data unit we go to the first spectral value
      // in the scan.
      eob_start_position = sss ;

      ++ eobcounter ;
      ++ col ;
      if (col == du_cols)
      {
        col = 0 ;
        ++ row ;
        ASSERT (row < du_cols || eobcounter == eob_run) ; // EOB run extends past last row
      }
    }

    // Some values that are certain to cause errors if improperly used.
    eob_start_position = JPEGSAMPLESIZE ;
    eob_start_du_row = du_cols * du_rows ;
    eob_start_du_col = du_cols * du_rows ;

    eob_run = 0 ; // Reset the counter.
  }

  return ;
}

//
//  Description
//
//    This function sets the horizontal sampling frequency for the
//    component.
//
//  Parameters:
//    value:  The new sampling frequency.
//
void JpegEncoderComponent::setHorizontalFrequency (unsigned int value)
{
  CHECKARGUMENT (value <= JPEGMAXSAMPLINGFREQUENCY && value >= JPEGMINSAMPLINGFREQUENCY) ;
  h_frequency = value ;
  return ;
}

//
//  Description
//
//    This function sets the vertical sampling frequency for the
//    component.
//
//  Parameters:
//    value:  The new sampling frequency.
//
void JpegEncoderComponent::setVerticalFrequency (unsigned int value)
{
  CHECKARGUMENT (value <= JPEGMAXSAMPLINGFREQUENCY && value >= JPEGMINSAMPLINGFREQUENCY) ;

  v_frequency = value ;
  return ;
}

void JpegEncoderComponent::rgbConvert (Colosseum::JpegEncoder &encoder, 
                                       const BitmapImage &image, 
                                       unsigned int maxhf, unsigned int maxvf,
                                       JpegEncoderComponent &ycomponent,
                                       JpegEncoderComponent &cbcomponent,
                                       JpegEncoderComponent &crcomponent) 
{
  const int progressscale = 8 ;
  unsigned int progress = 0 ;
  unsigned int progressincrement = (100 << progressscale) / image.getHeight () ;

  // Image dimensions rounded up to a multiple of JpegSampleWidth x Max Sampling Frequency

  unsigned int columns = NoninterleavedColumns (image.getWidth (), maxhf) ;
  unsigned int rows = NoninterleavedRows (image.getHeight (), maxvf) ;
  ycomponent.allocateComponentBuffer (image.getWidth (), image.getHeight (), maxhf, maxvf) ;
  cbcomponent.allocateComponentBuffer (image.getWidth (), image.getHeight (), maxhf, maxvf) ;
  crcomponent.allocateComponentBuffer (image.getWidth (), image.getHeight (), maxhf, maxvf) ;

  JPEGSAMPLE *ypointer = ycomponent.component_buffer ;
  JPEGSAMPLE *cbpointer = cbcomponent.component_buffer ;
  JPEGSAMPLE *crpointer = crcomponent.component_buffer ;
  unsigned int ii ; // Loop counters are declared here
  unsigned int jj ; // because they are used outside the loops/
  const BitmapImage::Pixel *pixel = &image [0] ;
  for (ii = 0 ; ii < image.getHeight () ; ++ ii)
  {
    JPEGSAMPLE yvalue ;
    JPEGSAMPLE cbvalue ;
    JPEGSAMPLE crvalue ;
    for (jj = 0 ; jj < image.getWidth () ; ++ jj, ++ pixel)
    {
      yvalue = RgbToY (pixel->red, pixel->green, pixel->blue) ;
      cbvalue = RgbToCb (pixel->red, pixel->green, pixel->blue) ;
      crvalue = RgbToCr (pixel->red, pixel->green, pixel->blue) ;
      *ypointer = yvalue ; ++ ypointer ;
      *cbpointer = cbvalue ; ++ cbpointer ;
      *crpointer = crvalue ; ++ crpointer ;
    }
    // Extend the last row
    for ( ; jj < columns ; ++ jj)
    {
      *ypointer = yvalue ; ++ ypointer ;
      *cbpointer = cbvalue ; ++ cbpointer ;
      *crpointer = crvalue ; ++ crpointer ;
    }
    progress += progressincrement ;
    encoder.callProgressFunction (progress >> progressscale) ;
  }
  for ( ; ii < rows ; ++ ii)
  {
    // Copy from the previous row
    *ypointer = ypointer [-columns] ; ++ ypointer ;
    *cbpointer = crpointer [-columns] ; ++ cbpointer ;
    *crpointer = crpointer [-columns] ; ++ crpointer ;
  }
  encoder.callProgressFunction (100) ;
  return ;
}

void JpegEncoderComponent::grayScaleConvert (Colosseum::JpegEncoder &encoder,
                                             const Colosseum::BitmapImage &image, 
                                             JpegEncoderComponent &ycomponent) 
{
  ycomponent.du_rows = (image.getHeight () + JPEGSAMPLEWIDTH - 1) / JPEGSAMPLEWIDTH ;
  ycomponent.du_cols = (image.getWidth () + JPEGSAMPLEWIDTH - 1) / JPEGSAMPLEWIDTH ;

  ycomponent.dct_coefficients = new JpegCoefficientBlock [ycomponent.du_cols * ycomponent.du_rows] ;

  const int progressscale = 8 ;
  unsigned int progress = 0 ;
  unsigned int progressincrement = (100 << progressscale) / (ycomponent.du_rows) ;

  JpegEncoderDataUnit data ;
  unsigned int index = 0 ;

  for (unsigned int ii = 0 ; ii < ycomponent.du_rows ; ++ ii)
  {
    for (unsigned int jj = 0 ; jj < ycomponent.du_cols ; ++ jj)
    {
      for (unsigned int kk = 0 ; kk < JPEGSAMPLEWIDTH ; ++ kk)
      {
        for (unsigned int ll = 0 ; ll < JPEGSAMPLEWIDTH ; ++ ll)
        {
          unsigned int row = ii * JPEGSAMPLEWIDTH + kk ;
          unsigned int column = jj * JPEGSAMPLEWIDTH + ll ;
          if (row < image.getHeight () && column < image.getWidth ()) 
          {
            const BitmapImage::Pixel *pixel = &image [row * image.getWidth () + column] ;
            JPEGSAMPLE yvalue = RgbToY (pixel->red, pixel->green, pixel->blue) ;
            data [kk][ll] = yvalue ;
          }
          else
          {
            data [kk][ll] = JPEGMIDPOINTSAMPLEVALUE ;
          }
        }
      }

      data.ForwardDct (*ycomponent.quantization_table, ycomponent.dct_coefficients [index]) ; 
      ++ index ;
    }
    progress += progressincrement ;
    encoder.callProgressFunction (progress >> progressscale) ;
  }
  encoder.callProgressFunction (100) ;
  return ;
}


void JpegEncoderComponent::sample1to1Component (Colosseum::JpegEncoder &encoder)
{
  const int progressscale = 8 ;
  unsigned int progress = 0 ;
  unsigned int progressincrement = (100 << progressscale) / (du_rows) ;

  JpegEncoderDataUnit data ;
  unsigned int index = 0 ;
  JPEGSAMPLE *row0 = &component_buffer [0] ;
  JPEGSAMPLE *row1 = &component_buffer [component_buffer_columns] ;
  JPEGSAMPLE *row2 = &component_buffer [component_buffer_columns*2] ;
  JPEGSAMPLE *row3 = &component_buffer [component_buffer_columns*3] ;
  JPEGSAMPLE *row4 = &component_buffer [component_buffer_columns*4] ;
  JPEGSAMPLE *row5 = &component_buffer [component_buffer_columns*5] ;
  JPEGSAMPLE *row6 = &component_buffer [component_buffer_columns*6] ;
  JPEGSAMPLE *row7 = &component_buffer [component_buffer_columns*7] ;

  for (unsigned int ii = 0 ; ii < du_rows ; ++ ii)
  {
    for (unsigned int jj = 0 ; jj < du_cols ; ++ jj)
    {
      for (unsigned int kk = 0 ; kk < JPEGSAMPLEWIDTH ; ++ kk)
      {
        data [0][kk] = *row0 ; ++ row0 ;
        data [1][kk] = *row1 ; ++ row1 ;
        data [2][kk] = *row2 ; ++ row2 ;
        data [3][kk] = *row3 ; ++ row3 ;
        data [4][kk] = *row4 ; ++ row4 ;
        data [5][kk] = *row5 ; ++ row5 ;
        data [6][kk] = *row6 ; ++ row6 ;
        data [7][kk] = *row7 ; ++ row7 ;
      }

      data.ForwardDct (*quantization_table, dct_coefficients [index]) ;
      ++ index ;
    }
    row0 = row7 ;
    row1 = &row0 [component_buffer_columns] ;
    row2 = &row1 [component_buffer_columns] ;
    row3 = &row2 [component_buffer_columns] ;
    row4 = &row3 [component_buffer_columns] ;
    row5 = &row4 [component_buffer_columns] ;
    row6 = &row5 [component_buffer_columns] ;
    row7 = &row6 [component_buffer_columns] ;

    progress += progressincrement ;
    encoder.callProgressFunction (progress >> progressscale) ;
  }
  encoder.callProgressFunction (100) ;
  return ;
}


void JpegEncoderComponent::sampleNtoNComponent (Colosseum::JpegEncoder &encoder,
                                                unsigned int maxhf,
                                                unsigned int maxvf)
{
  unsigned int vperiod = maxvf / v_frequency ;
  unsigned int hperiod = maxhf / h_frequency ;



  JpegEncoderDataUnit data ;
  unsigned int index = 0 ;

  const int progressscale = 8 ;
  unsigned int progress = 0 ;
  unsigned int progressincrement = (100 << progressscale) / (du_rows) ;

  for (unsigned int durow = 0 ; durow < du_rows ; ++ durow)
  {
    // Offset of the upper left corner of the MCU from the start of the image.
    unsigned int mcuoffset = durow * component_buffer_columns * vperiod * JPEGSAMPLEWIDTH ;
    for (unsigned int ducol = 0 ; ducol < du_cols  ; ++ ducol)
    {
      unsigned int sums [JPEGSAMPLEWIDTH][JPEGSAMPLEWIDTH] ;
      memset (sums, 0, sizeof (sums)) ;

      JPEGSAMPLE *rowbuffer =&component_buffer [mcuoffset] ;
      for (unsigned int mcurow = 0 ; mcurow  < JPEGSAMPLEWIDTH ; ++ mcurow)
      {
        for (unsigned int ii = 0 ; ii < vperiod ; ++ ii)
        {
          unsigned int offset  = 0 ;
          for (unsigned int mcucol = 0 ; mcucol < JPEGSAMPLEWIDTH ; ++ mcucol)
          {
            for (unsigned int jj = 0 ; jj < hperiod ; ++ jj, ++ offset)
            {
              sums [mcurow][mcucol] += rowbuffer [offset] ;
            }
          }
          rowbuffer += component_buffer_columns ;
        }
      }
      for (unsigned int ii = 0 ; ii < JPEGSAMPLEWIDTH ; ++ ii)
      {
        for (unsigned int jj = 0 ; jj < JPEGSAMPLEWIDTH ; ++ jj)
        {
          data [ii][jj] = sums [ii][jj] / (vperiod * hperiod) ;
        }
      }

      data.ForwardDct (*quantization_table, dct_coefficients [index]) ;
      mcuoffset += JPEGSAMPLEWIDTH * hperiod ;
      ++ index ;
    }
    progress += progressincrement ;
    encoder.callProgressFunction (progress >> progressscale) ;
  }
  encoder.callProgressFunction (100) ;
  return ;
}


void JpegEncoderComponent::sampleComponent (Colosseum::JpegEncoder &encoder,
                                            unsigned int maxhf,
                                            unsigned int maxvf)
{
  ASSERT (component_buffer_rows % JPEGSAMPLEWIDTH == 0) ;
  ASSERT (component_buffer_columns % JPEGSAMPLEWIDTH == 0) ;

  du_rows = v_frequency * component_buffer_rows / JPEGSAMPLEWIDTH / maxvf ;
  du_cols = h_frequency * component_buffer_columns / JPEGSAMPLEWIDTH / maxvf ;

  dct_coefficients = new JpegCoefficientBlock [du_cols * du_rows] ;

  if (h_frequency == maxhf && v_frequency == maxvf)
    sample1to1Component (encoder) ;
  else
    sampleNtoNComponent (encoder, maxhf, maxvf) ;


  delete [] component_buffer ; component_buffer = 0 ;
  return ;

}

void JpegEncoderComponent::allocateComponentBuffer (
                                unsigned int imagewidth,
                                unsigned int imageheight,
                                unsigned int maxhf,
                                unsigned int maxvf)
{
  unsigned int columns = NoninterleavedColumns (imagewidth, maxhf) ;
  unsigned int rows = NoninterleavedRows (imageheight, maxvf) ;

  ASSERT (rows % JPEGSAMPLEWIDTH == 0)
  ASSERT (columns % JPEGSAMPLEWIDTH == 0)

  delete [] component_buffer ;
  component_buffer = new JPEGSAMPLE [rows * columns] ;

  component_buffer_columns = columns ;
  component_buffer_rows = rows ;

  noninterleaved_du_rows
     = (imageheight * maxvf
        + v_frequency * JPEGSAMPLEWIDTH - 1) // Rounding
     / (v_frequency * JPEGSAMPLEWIDTH);
  noninterleaved_du_colummns
     = (imagewidth * maxhf
        + h_frequency * JPEGSAMPLEWIDTH - 1) // Rounding
     / (h_frequency * JPEGSAMPLEWIDTH);

  return ;
}


} // End Namespace Colosseum Private

⌨️ 快捷键说明

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