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

📄 jpgdecodercomponent.~cpp

📁 Jpeg编解码器的源代码
💻 ~CPP
📖 第 1 页 / 共 4 页
字号:
//    components from YCbCr to RGB and writes it to an image.
//
//  Parameters:
//    c1: The component containing the Y data
//    c2: Ditto for Cb
//    c3: Ditto for Cr
//    image: The output image
//
void JpegDecoderComponent::convertRgb (JpegDecoderComponent &c1,
                                       JpegDecoderComponent &c2,
                                       JpegDecoderComponent &c3,
                                       BitmapImage &image)
{
  if (c1.upsample_data == 0
      || c2.upsample_data == 0
      || c3.upsample_data == 0)
  {
    // If we get here then do not yet have data for all components.
    return ;
  }

  unsigned int rowstart = 0 ;
  BitmapImage::Pixel *pixel = &image [0] ;
  for (unsigned int ii = 0 ; ii < image.getHeight () ; ++ ii)
  {
    unsigned int offset = rowstart ;
    for (unsigned int jj = 0 ; jj < image.getWidth () ; ++jj, ++ pixel)
    {
      JPEGSAMPLE yvalue = c1.upsample_data [offset] ;
      JPEGSAMPLE cbvalue = c2.upsample_data [offset] ;
      JPEGSAMPLE crvalue = c3.upsample_data [offset] ;
      pixel->red = YCbCrToR (yvalue, cbvalue, crvalue) ;
      pixel->green = YCbCrToG (yvalue, cbvalue, crvalue) ;
      pixel->blue = YCbCrToB (yvalue, cbvalue, crvalue) ;
      pixel->alpha = 0xFFU ;
      ++ offset ;
    }
    rowstart += c1.du_cols * c1.h_sampling * JPEGSAMPLEWIDTH ;
  }
  return ;
}

//
//  Description:
//
//    Progressive Only
//
//    This function decodes the DC coefficient for a data unit in the first
//    DC scan for the component.
//
//    According to G.2 "In order to avoid repetition, detail flow diagrams
//    of progressive decoder operation are not included. Decoder operation is
//    defined by reversing the function of each stop described in the encoder
//    flow charts, and performing the steps in reverse order."
//
//  Parameters:
//    decoder:  The JPEG decoder
//    row:  The data unit row
//    col:  The data unit column
//    ssa:  Successive Approximation
//
void JpegDecoderComponent::decodeDcFirst (JpegInputStream &inputstream,
                                          unsigned int row,
                                          unsigned int col,
                                          unsigned int ssa)
{
  // We decode the first DC coeffient that same way as in a sequential
  // scan except for the point transform according to G.1.2.1

  // Section F.2.2.1
  unsigned int count ; // called T in F.2.2.1
  count = dc_table->decode (inputstream) ;
  int bits = inputstream.getBits (count) ;
  int diff = Extend (bits, count) ;
  int value = diff + last_dc_value ;
  last_dc_value = value ;
  coefficient_blocks [row * du_cols + col][0] = (value << ssa) ;
  return ;
}

//
//  Description:
//
//    Progressive Only
//    
//    This function decodes the DC coefficient for a data unit in refining
//    DC scans for the component.
//
//    According to G.2 "In order to avoid repetition, detail flow diagrams
//    of progressive decoder operation are not included. Decoder operation is
//    defined by reversing the function of each stop described in the encoder
//    flow charts, and performing the steps in reverse order."
//
//  Parameters:
//    decoder:  The JPEG decoder
//    row:  The data unit row
//    col:  The data unit column
//    ssa:  Successive Approximation
//
void JpegDecoderComponent::decodeDcRefine (JpegInputStream &inputstream,
                                           unsigned int row,
                                           unsigned int col,
                                           unsigned int ssa)
{
  // Reversing G.1.2.1
  if (inputstream.nextBit() != 0)
  {
    coefficient_blocks [row * du_cols + col][0] |= (1 << ssa) ;
  }
  return ;
}

//
//  Description:
//
//    Progressive Only
//
//    This function decodes the AC coefficients for a data unit in the first
//    AC scans for a spectral range within the component.
//
//    According to G.2 "In order to avoid repetition, detail flow diagrams
//    of progressive decoder operation are not included. Decoder operation is
//    defined by reversing the function of each stop described in the encoder
//    flow charts, and performing the steps in reverse order."
//
//    This function comes from reversing the steps in Figures G.3-G.5.
//
//  Parameters:
//    decoder:  The JPEG decoder
//    row:  The data unit row
//    col:  The data unit column
//    sss:  Spectral Selection Start
//    sse:  Spectral Selection End
//    ssa:  Successive Approximation
//
void JpegDecoderComponent::decodeAcFirst (JpegInputStream &inputstream,
                                          unsigned int row,
                                          unsigned int col,
                                          unsigned int sss,
                                          unsigned int sse,
                                          unsigned int ssa)
{
  JpegCoefficientBlock &data =
  				coefficient_blocks [row * du_cols + col] ;
  if (eob_run > 0)
  {
    // If a previous call created a nonzero EOB run then we decrement the
    // counter and return.
    -- eob_run ;
  }
  else
  {
    for (unsigned int kk = sss ; kk <= sse ; )
    {
      // Decode the next value in the input stream.
      UBYTE2 rs = ac_table->decode (inputstream) ;
      UBYTE1 ssss = (UBYTE1) (rs & 0xF) ;
      UBYTE1 rrrr = (UBYTE1) (rs >> 0x4) ;

      if (ssss == 0)
      {
        if (rrrr == 15)
        {
          // A zero value ssss with rrrr == 15 means to skip
          // 16 zero coefficients.
            kk += 16 ;
        }
        else
        {
          // A zero value ssss with rrrr != 15 means to create
          // End of Band run.

          // The EOB run includes the current block. This is why we
          // do no processing for rrrr = 0 and substract one when
          // rrrrr != 0.
          if (rrrr != 0)
          {
            int bits = inputstream.getBits (rrrr) ;
            eob_run = (1 << rrrr) + bits - 1 ;
          }
          break ;
        }
      }
      else
      {
        // When ssss != 0, rrrr gives the number of zero elements to skip
        // before the next non-zero coefficient.
        kk += rrrr ;
        if (kk >= JPEGSAMPLESIZE)
          throw JpegDecoder::JpegBadStream ("Data out of range") ;

        // Extend the value and store.
        int bits = inputstream.getBits (ssss) ;
        int value = Extend (bits, ssss) ;
        data[JpegZigZagInputOrder (kk)] = (value << ssa) ;
        ++ kk ;
      }
    }
  }
  return ;
}

//
//  Description:
//
//    Progressive Only
//
//    This function decodes the AC coefficients for a data unit in the
//    refining AC scans for a spectral range within the component.
//
//    According to G.2 "In order to avoid repetition, detail flow diagrams
//    of progressive decoder operation are not included. Decoder operation is
//    defined by reversing the function of each stop described in the encoder
//    flow charts, and performing the steps in reverse order."
//
//    Section G.1.2.3 defines how to encode refining scans for AC
//    coefficients. Unfortunately this section is vague and
//    undecipherable. Reversing an undecipherable process results
//    in something unimaginable. This is a "best-guess" interpretation
//    that seems to work.
//
//    The basic process at work is that zero counts do not include nonzero
//    values. Whenever we skip a value due to zero count or End of Band runs
//    we have to read one bit to refine each non-zero value we skip. The
//    process is ugly and it means that data is encoding out of order.
//
//  Parameters:
//    decoder:  The JPEG decoder
//    row:  The data unit row
//    col:  The data unit column
//    sss:  Spectral Selection Start
//    sse:  Spectral Selection End
//    ssa:  Successive Approximation
//                                                            
void JpegDecoderComponent::decodeAcRefine (JpegInputStream &inputstream,
                                           unsigned int row,
                                           unsigned int col,
                                           unsigned int sss,
                                           unsigned int sse,
                                           unsigned int ssa)
{
  JpegCoefficientBlock &data =
  				coefficient_blocks [row * du_cols + col] ;
  // kk is incremented within the loop.
  for (unsigned int kk = sss ; kk <= sse ;)
  {
    if (eob_run != 0)
    {
      // An EOB run has caused us to skip entire data units. We need
      // to refine any previously non-zero coefficients.
      // Notice that we do not initialize kk here. We could be using
      // an EOB run to skip all the remaining coefficients in the current
      // one.

      for ( ; kk <= sse ; ++ kk)
      {
        if (data [JpegZigZagInputOrder (kk)] != 0)
        {
          RefineAcCoefficient (inputstream, 
                               ssa,
                               data [JpegZigZagInputOrder (kk)]) ;
        }
      }
      -- eob_run ;
    }
    else
    {
      UBYTE2 rs = ac_table->decode (inputstream) ;
      UBYTE1 ssss = (UBYTE1) (rs & 0xF) ;
      UBYTE1 rrrr = (UBYTE1) (rs >> 0x4) ;

      if (ssss == 0)
      {
        // ssss == 0 means that we either have an EOB run or we need to
        // 16 non-zero coefficients.

        if (rrrr == 15)
        {
          // ssss == 0 and rrrr == 15 => Skip over 16 zero coefficients
          for (unsigned int ii = 0 ;
              kk <= sse  && ii < 16 ;
              ++ kk)
          {
            if (kk >  sse)
              throw JpegDecoder::JpegBadStream ("Corrupt Scan Data") ;

            if (data [JpegZigZagInputOrder (kk)] != 0)
            {
              RefineAcCoefficient (inputstream, 
                                   ssa,
                                   data [JpegZigZagInputOrder (kk)]) ;
            }
              else
            {
              ++ ii ;
            }
          }
        }
        else
        {
          // We are reading an EOB run.
          if (rrrr == 0)
          {
            eob_run = 1 ;
          }
          else
          {
            int bits = inputstream.getBits (rrrr) ;
            eob_run = (1 << rrrr) + bits ;
          }
        }
      }
      else if (ssss == 1)
      {
        // ssss == 1 means that we are creating a new non-zero
        // coefficient. rrrr gives the number of zero coefficients to
        // skip before we reach this one.
        // Save the value for the new coefficient. Unfortunately the data
        // is stored out of order.
        int newvalue = inputstream.nextBit () ;

        // Skip the zero coefficients.
        for (unsigned int zerocount = 0 ;
             kk <  JPEGSAMPLESIZE
              && (zerocount < rrrr
                  || data [JpegZigZagInputOrder (kk)] != 0) ;
             ++ kk)
        {
          if (kk >  sse)
            throw JpegDecoder::JpegBadStream ("Error in progressive scan") ;

          if (data [JpegZigZagInputOrder (kk)] != 0)
          {
            RefineAcCoefficient (inputstream, 
                                 ssa,
                                 data [JpegZigZagInputOrder (kk)]) ;
          }
          else
          {
            ++ zerocount ;
          }
        }

        if (kk >  sse)
          throw JpegDecoder::JpegBadStream ("Error in progressive scan") ;

        if (newvalue)
        {
          data [JpegZigZagInputOrder (kk)] = (1 << ssa) ;
        }
        else
        {
          data [JpegZigZagInputOrder (kk)] = (-1 << ssa) ;
        }
        ++ kk ;
      }
      else
      {
        // The value of SSSS must be zero or one. Since we add data one
        // bit at at a time data values larger than 1 make no sense.
        throw JpegDecoder::JpegBadStream ("Invalid value in input stream") ;
      }
    }
  }
  return ;
}

//
//  Description:
//
//    Progressive Only
//
//    This function performs the IDCT on all the data in
//    coefficient_blocks and stores the result in data_units.
//
//    This function gets called whenever the image data is written
//    to the image.  For a sequential image the IDCT only needs to
//    performed once no matter how often the data gets updated in the
//    image but to continuously update the progressive image data
//    an update after each scan gives new results.
//
void JpegDecoderComponent::progressiveInverseDct ()
{
  // If UpdateImage gets called before the image is completely
  // decoded the these values may be 0.
  if (data_units == 0 || coefficient_blocks == 0)
    return ;

  unsigned int limit = du_cols * du_rows ;
  for (unsigned int ii = 0 ; ii < limit ; ++ ii)
  {
    data_units [ii].inverseDCT (coefficient_blocks [ii], *quantization_table) ;
  }
  return ;
}


//
//  This function performs pseudo"upsampling" for components that don't need to
//  be upsampled. For such components we just make a straight copy of the
//  upsample data.
//
void JpegDecoderComponent::upSample1To1 ()
{
  unsigned output = 0 ;
  unsigned int startdu = 0 ;
  for (unsigned int durow = 0 ; durow < du_rows ; ++ durow)
  {
    for (unsigned int ii = 0 ; ii < JPEGSAMPLEWIDTH ; ++ ii)
    {
      unsigned int du = startdu ;
	    for (unsigned int ducol = 0 ; ducol < du_cols ; ++ ducol)
      {
        JPEGSAMPLE *dataunits = data_units [du][ii] ;
        memcpy (&upsample_data [output], dataunits, sizeof (*dataunits) * JPEGSAMPLEWIDTH) ;
        output += JPEGSAMPLEWIDTH ;
        ++ du ;
    	}
    }
    startdu += du_cols ;

⌨️ 快捷键说明

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