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