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