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

📄 jpgencodercomponent.cpp

📁 Jpeg编解码器的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// JPEG Encoder Library.
//
// Title:JpegEncoderComponent Class Implementation
//
//

#include "jpgencoder.h"
#include "jpgencodercomponent.h"
#include "jfif.h"
#include "jpgcoefficient.h"
#include "jpgencoderdataunit.h"
#include "jpghuffmanencoder.h"
#include "jpgoutputstream.h"
#include "checks.h"

using namespace Colosseum ;

namespace
{
using namespace ColosseumPrivate ;

//
//   描述:
//
//    返回一个成分的要编码的像素行数目
//    in an interleaved scan. This number is at least as large as the image
//    height. However, since it takes into account sampling frequencies,
//    it can be larger if the height is not evenly divisible by the number
//    sample rows in an MCU.
//
//  Parameters:
//
//    imageheight : The image width
//    maxvf: The maximum horizontal sampling frequency among all components.
//
//  Return Value:
//
//    The number of pixel rows to be encoded.
//
unsigned int NoninterleavedRows (unsigned int imageheight, unsigned int maxvf)
{
  unsigned int heightmask = JPEGSAMPLEWIDTH * maxvf - 1 ;
  unsigned int rows = (imageheight + heightmask) & ~heightmask ;
  return rows ;
}
//
//  Description:
//
//    This function returns the number of pixel columns encoded for a component
//    in an interleaved scan. This number is at least as large as the image
//    width. However, since it takes into account sampling frequencies,
//    it can be larger if the width is not evenly divisible by the number
//    sample columns in an MCU.
//
//  Parameters:
//
//    imagewidth : The image height
//    maxhf: The maximum vertical sampling frequency among all components.
//
//  Return Value:
//
//    The number of pixel columns to be encoded.
//
unsigned int NoninterleavedColumns (unsigned int imagewidth, unsigned int maxhf)
{
  unsigned int widthmask = JPEGSAMPLEWIDTH * maxhf - 1 ;
  unsigned int columns = (imagewidth + widthmask) & ~widthmask ;
  return columns ;
}

}

namespace ColosseumPrivate
{

//
//  Description:
//
//    Class Default Constructor
//

JpegEncoderComponent::JpegEncoderComponent ()
: output_stream (0),
  dct_coefficients (0),
  du_rows (0),
  du_cols (0),
  eob_run (0),
  eob_start_du_row (0),
  eob_start_du_col (0),
  eob_start_position (0),
  v_frequency (1),
  h_frequency (1),
  ac_table (0),
  dc_table (0),
  component_buffer (0)
{
  return ;
}

//
//  Description:
//
//    Class Destructor
//
JpegEncoderComponent::~JpegEncoderComponent ()
{
  freeDynamicStorage () ;
  return ;
}

//
//  Description:
//
//    This function gets rid of all the memory allocated by the component.
//    This allows the encoder to free memory after each image is written
//    rather than waiting until the decoder is deleted.
//
void JpegEncoderComponent::freeDynamicStorage ()
{
  delete [] dct_coefficients ; dct_coefficients = 0 ;
  return ;
}

//
//  Description:
//
//    This function is use to gather Huffman statistics for DC coefficients.
//    The calling sequences is idential to PrintDcData (). Only the huffvalue
//    parameter is used here.
//
//  Parameters:
//    huffvalue:  The Huffman value (not code) to process.
//
void JpegEncoderComponent::gatherDcData (int huffvalue, int)
{
  dc_table->incrementFrequency (huffvalue) ;
  return ;
}

//
//  Description:
//
//    This function is use to gather Huffman statistics for AC coefficients.
//    The calling sequences is idential to PrintAcData (). Only the huffvalue
//    parameter is used here.
//
//    If huffval==-1 then an unencoded bit string would be output by
//    PrintAcData (). In that situation this function does nothing.
//
//  Parameters:
//    huffvalue:  The Huffman value (not code) to process
//
void JpegEncoderComponent::gatherAcData (int huffvalue, int, int)
{
  if (huffvalue >= 0)
  {
    ac_table->incrementFrequency (huffvalue) ;
  }
  return ;
}

//
//  Description:
//
//    This function is use to output Huffman-encoded data for a DC value.
//
//  Parameters:
//    huffvalue:  The Huffman value
//    bits: The additional data bits
//
//    8-bit DC values are in the range 0..11. The value specifies the number
//    of additional bits of refining data (bits).
//

void JpegEncoderComponent::printDcData (int huffvalue, int bits)
{
  UBYTE2 huffcode ;
  UBYTE1 huffsize ;

  // Section F.1.2.1
  dc_table->encode (huffvalue, huffcode, huffsize) ;
  output_stream->outputBits (huffcode, huffsize) ;
  if (huffvalue != 0)
    output_stream->outputBits (bits, huffvalue) ;
  return ;
}

//
//  Description:
//
//    This function is use to output Huffman-encoded data for an AC value.
//
//  Parameters:
//    huffvalue:  The Huffman value
//    value: The additional data bits
//    size: The number of additional data bits.
//
//    When huffvalue==-1 this function is also used to output unencoded bit
//    strings.
//

void JpegEncoderComponent::printAcData (int huffvalue, int value, int size)
{
  UBYTE2 huffcode ;
  UBYTE1 huffsize ;

  // Section F.1.2.2.1
  if (huffvalue >= 0)
  {
    ac_table->encode (huffvalue, huffcode, huffsize) ;
    output_stream->outputBits (huffcode, huffsize) ;
  }
  if (size != 0)
    output_stream->outputBits (value, size) ;
  return ;
}
//
//  Description:
//
//    This function is used for two purposes in a sequential scan:
//
//      o To gather statistics for generating Huffman Tables
//      o To encode and output a data unit.
//
//    The dcfunction and acfunction arguments are determine which of these
//    actions are performed. If these arguments are PrintDcData () and
//    PrintAcData () the data unit is encoded and written to the output
//    stream.  If the arguments are GatherDcData () and GatherAcData ()
//    usage statistics are gathered.
//
//    While creating a separate function for each purpose may have been clearer,
//    it would create maintenance problems because they would have to be kept
//    in strict synchronization with each other.
//
//  Parameters:
//    row,col: Data unit position
//    dcfunction: Function for outputting DC coefficient values.
//    acfunction: Function for outputting AC coefficient values.
//
//    This function is of the type COMPONENTPASSFUNCTION.
//
void JpegEncoderComponent::encodeSequential (
                            unsigned int row, unsigned int col,
                            DCOUTPUTFUNCTION dcfunction,
                            ACOUTPUTFUNCTION acfunction,
                            unsigned int, unsigned int, unsigned int)
{
  JpegCoefficientBlock &du = dct_coefficients [row * du_cols + col] ;

  // DC value calculation
  // Section F.1.2.1.3
  int diff = du [0] - last_dc_value ;
  last_dc_value = du [0] ;

  // Break the DC coefficient into a category (Table F.12) and
  // additional bits.
  int bits ;
  if (diff >= 0)
  {
    bits = diff ;
  }
  else
  {
    diff = -diff ;
    bits = ~diff ;
  }
  int ssss = 0 ;  // Category
  while (diff != 0)
  {
    ++ ssss ;
    diff >>= 1 ;
  }
  (this->*dcfunction) (ssss, bits) ;

  // AC coefficient coding
  // F.1.2.2.3 Figure F.2
  int zerorun = 0 ; // Called rrrr in the specification.
  for (unsigned int index = 1 ; index < JPEGSAMPLESIZE ; ++ index)
  {
    if (du [JpegZigZagInputOrder (index)] != 0)
    {
      // 16 is the longest run of zeros that can be encoded except for the
      // final EOB code.
      while (zerorun >= 16)
      {
        // 0xF0 is the code to skip 16 zeros (Figure F.1)
        (this->*acfunction) (0xF0, 0, 0) ;
        zerorun -= 16 ;
      }

      // Non-zero AC coefficients are encoded with
      // 8-bit Huffman-encoded values of the form rrrrssss followed by
      // 1..10 additional bits of data. rrrr is the number of zero values
      // to skip (0..15). ssss is the category (1..10) which specifies the
      // number of additional raw bits to follow. (Figure F.1)
      int value = du [JpegZigZagInputOrder (index)] ;
      int bits ;
      if (value >= 0)
      {
        bits = value ;
      }
      else
      {
        value = -value ;
        bits = ~value ;
      }
      int ssss = 0 ;
      while (value != 0)
      {
        value >>= 1 ;
        ++ ssss ;
      }

      int rrrrssss = (zerorun << 4) | ssss ;
      (this->*acfunction) (rrrrssss, bits, ssss) ;
      zerorun = 0 ;
    }
    else
    {
      ++ zerorun ;
    }
  }
  // The code 0x00 indicates all remaining AC coefficients are zero.
  if (zerorun > 0)
  {
    (this->*acfunction) (0, 0, 0) ;
  }

  return ;
}

//
//  Description:
//
//    This function outputs an End of Band run in an initial AC coefficient
//    scan of a progressive frame.
//
//  Parameters:
//    acfunction: Function for outputting AC coefficient values
//
void JpegEncoderComponent::printEobRun (ACOUTPUTFUNCTION acfunction)
{
  // Figure G.4
  if (eob_run != 0)
  {
    unsigned int bits = eob_run ;
    unsigned int value = bits >> 1 ;
    unsigned int ssss = 0 ; // Category (Table G.1)
    while (value != 0)
    {
      value >>= 1 ;
      ++ ssss ;
    }
    (this->*acfunction)(ssss << 4, bits, ssss) ;
    eob_run = 0 ;
  }

  return ;
}                               

//

⌨️ 快捷键说明

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