📄 jpgencodercomponent.cpp
字号:
//
// 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 + -