📄 jpgdecoder.~cpp
字号:
{
unsigned int ID = inputstream.getByte () ; // Ci in standard
unsigned int qtable ;
// While JPEG does not put these restrictions on component IDs
// the JFIF standard does.
if (strict_jfif)
{
if (component_count == 1 && ID != 1)
throw JpegBadStream ("Component ID not 1") ;
else if (ID != ii + 1)
throw JpegBadStream ("Invalid Component ID or ID out of order") ;
}
component_indices [ii] = ID ;
UBYTE1 data = inputstream.getByte () ;
components [ID].horizontalFrequency (data >> 4) ; // Hi in standard
components [ID].verticalFrequency (data & 0xF) ; // Vi in standard
qtable= inputstream.getByte () ; // Tqi in standard
if (qtable >= JPEGMAXQUANTIZATIONTABLES)
throw JpegBadStream ("Bad Quantization Table Index") ;
components [ID].setQuantizationTable (quantization_tables [qtable]) ;
// Keep track of the largest values for horizontal and vertical
// frequency.
if (components [ID].horizontalFrequency ()
> max_horizontal_frequency)
{
max_horizontal_frequency =
components [ID].horizontalFrequency () ;
}
if (components [ID].verticalFrequency ()
> max_vertical_frequency)
{
max_vertical_frequency =
components [ID].verticalFrequency () ;
}
if (verbose_flag)
{
cout << " Component " << ID << endl ;
cout << " Horizontal Frequency: "
<< components [ID].horizontalFrequency () << endl ;
cout << " Vertical Frequency: "
<< components [ID].verticalFrequency () << endl ;
cout << " Quantization Table: "
<< qtable << endl ;
}
}
calculateMcuDimensions () ;
// Allocate storage for the image.
current_image->setSize (frame_width, frame_height) ;
if (verbose_flag)
cout << "}" << endl ;
sof_found = true ;
return ;
}
//
// 描述:
//
// 读SOS标记和接着的扫描数据
//
void JpegDecoder::readStartOfScan (JpegInputStream &inputstream)
{
unsigned int ii ;
if (! sof_found)
throw JpegBadStream ("Scan found before frame defined") ;
// Section B.2.3
UBYTE2 length = inputstream.getBigEndianWord () ;
if (verbose_flag)
{
cout << "{ Start Of Scan " << endl ;
cout << " Length: " << dec << length << endl ;
}
scan_component_count = inputstream.getByte () ; // Ns in standard
// Right now we can only handle up to three components.
if (scan_component_count > 3 || scan_component_count < 1)
throw JpegBadStream ("Invalid component count in scan") ;
for (ii = 0 ; ii < scan_component_count ; ++ ii)
{
UBYTE1 componentID = inputstream.getByte () ; // Csi in standard
scan_components [ii] = &components [componentID] ;
// If the horizontal frequency is zero then the component was not
// defined in the SOFx marker.
if (scan_components [ii]->horizontalFrequency () == 0)
throw JpegBadStream ("Component Not Defined") ;
UBYTE1 rb = inputstream.getByte () ;
unsigned int actable = rb & 0x0F ;
unsigned int dctable = rb >> 4 ;
scan_components [ii]->setHuffmanTables (
dc_tables [dctable],
ac_tables [actable]) ;
if (verbose_flag)
{
cout << " Component ID: "
<< dec << (unsigned int) componentID << endl ;
cout << " DC Entropy Table: "
<< dec << dctable << endl ;
cout << " AC Entropy Table: "
<< dec << actable << endl ;
}
}
unsigned int spectralselectionstart = inputstream.getByte () ; // Ss in standard
unsigned int spectralselectionend = inputstream.getByte () ; // Se in standard
UBYTE1 ssa = inputstream.getByte () ;
unsigned int successiveapproximationhigh = ssa >> 4 ; // Ah in standard
unsigned int successiveapproximationlow = ssa & 0x0F ; // Al in standard
if (verbose_flag)
{
cout << " Spectral Selection Start: "
<< dec << (unsigned int) spectralselectionstart << endl ;
cout << " Spectral Selection End: "
<< dec << (unsigned int) spectralselectionend << endl ;
cout << " Successive Approximation High: "
<< dec << successiveapproximationhigh << endl ;
cout << " Successive Approximation Low: "
<< dec << successiveapproximationlow << endl ;
cout << "}" << endl ;
}
for (ii = 0 ; ii < scan_component_count ; ++ ii)
{
if (progressive_frame)
{
scan_components [ii]->checkQuantizationTable () ;
if (spectralselectionstart == 0)
scan_components [ii]->checkDcTable () ;
else
scan_components [ii]->checkAcTable () ;
}
else
{
scan_components [ii]->checkQuantizationTable () ;
scan_components [ii]->checkDcTable () ;
scan_components [ii]->checkAcTable () ;
}
scan_components [ii]->allocateComponentBuffers (*this) ;
}
++ current_scan ;
inputstream.enterBitMode (CHAR_BIT) ;
if (progressive_frame)
{
readProgressiveScanData (inputstream,
spectralselectionstart,
spectralselectionend,
successiveapproximationhigh,
successiveapproximationlow) ;
}
else
{
readSequentialScanData (inputstream) ;
}
inputstream.exitBitMode () ;
//int *coef;
for (ii = 0 ; ii < scan_component_count ; ++ ii)
{
unsigned int count = scan_components[ii]->pdu_rows*scan_components[ii]->pdu_cols ;
JpegCoefficientBlock *coefficient_blocks = new JpegCoefficientBlock [count];
memset(coefficient_blocks,0,sizeof(JpegCoefficientBlock)*count) ;
scan_components[ii]->printOnArray(coefficient_blocks);
//ShowMessage(coefficient_blocks[0][0]);
}
callProgressFunction (100) ;
return ;
}
//
// 描述:
//
// 求非交织扫描:
//
// o The dimensions in pixels for an MCU
// o The number of MCU rows and columns needed to encode the scan.
//
void JpegDecoder::calculateMcuDimensions ()
{
mcu_height = max_vertical_frequency * JPEGSAMPLEWIDTH ;
mcu_width = max_horizontal_frequency * JPEGSAMPLEWIDTH ;
mcu_rows = (frame_height + mcu_height - 1) / mcu_height ;
mcu_cols = (frame_width + mcu_width - 1) / mcu_width ;
return ;
}
//
// 描述:
//
// 进度函数
//
// 参数:
// progress:进度百分比
//
void JpegDecoder::callProgressFunction (unsigned int progress)
{
if (progress_function == 0)
return ;
bool abort = false ;
unsigned int percent = progress ;
if (percent > 100)
percent = 100 ;
if (progress_function != 0)
{
progress_function (*this,
progress_data,
current_scan,
scan_count,
percent,
abort) ;
}
if (abort)
throw GraphicsAbort () ;
return ;
}
//
// 描述:
//
// 累进扫描时读扫描数据
//
// All we do here is determine if we are processing a DC
// scan (sss==sse==0) or AC scan and if we are processing
// the first scan for the spectral selection (sah==0) or
// subsequent scan.
//
// Parameters:
// sss: Spectral Selection Start (0..63)
// sse: Spectral Selection End (sse..63)
// sah: Successive Approximation High
// sal: Successive Approximation Low
//
void JpegDecoder::readProgressiveScanData (JpegInputStream &inputstream,
unsigned int sss, unsigned int sse,
unsigned int sah, unsigned int sal)
{
if (sss == 0)
{
if (sse != 0)
throw JpegBadStream ("Progressive scan contains DC and AC data") ;
if (sah == 0)
{
readDcFirst (inputstream, sal) ;
}
else
{
readDcRefine (inputstream, sal) ;
}
}
else
{
if (sah == 0)
{
readAcFirst (inputstream, sss, sse, sal) ;
}
else
{
readAcRefine (inputstream, sss, sse, sal) ;
}
}
return ;
}
//
// 描述:
//
// 读第一个DC扫描的扫描数据 for
// one or more components.
//
// 参数:
//
// ssa: Successive Approximation
//
void JpegDecoder::readDcFirst (JpegInputStream &inputstream, unsigned int ssa)
{
resetDcDifferences () ;
unsigned int restartcount = 0 ;
if (scanIsInterleaved ())
{
for (unsigned int mcurow = 0 ;
mcurow < mcu_rows ;
++ mcurow)
{
callProgressFunction (mcurow * 100 / mcu_rows) ;
for (unsigned int mcucol = 0 ;
mcucol < mcu_cols ;
++ mcucol, ++restartcount)
{
if (restart_interval != 0
&& restart_interval == restartcount)
{
resetDcDifferences () ;
processRestartMarker (inputstream) ;
restartcount = 0 ;
}
for (unsigned int cc = 0 ; cc < scan_component_count ; ++ cc)
{
for (unsigned int cy = 0 ;
cy < scan_components [cc]->verticalFrequency () ;
++ cy)
{
unsigned int durow = scan_components [cc]->verticalFrequency ()
* mcurow + cy ;
for (unsigned int cx = 0 ;
cx < scan_components [cc]->horizontalFrequency () ;
++ cx)
{
unsigned int ducol = scan_components [cc]->horizontalFrequency ()
* mcucol + cx ;
scan_components [cc]->decodeDcFirst (inputstream, durow, ducol, ssa) ;
}
}
}
}
}
}
else
{
for (unsigned int row = 0 ;
row < scan_components [0]->noninterleavedRows () ;
++ row)
{
callProgressFunction (row * 100 / scan_components [0]->noninterleavedRows ()) ;
for (unsigned int col = 0 ;
col < scan_components [0]->noninterleavedCols () ;
++ col, ++restartcount)
{
if (restart_interval != 0 && restart_interval == restartcount)
{
resetDcDifferences () ;
processRestartMarker (inputstream) ;
restartcount = 0 ;
}
scan_components [0]->decodeDcFirst (inputstream, row, col, ssa) ;
}
}
}
return ;
}
//
// 描述:
//
// This function reads the scan data for a refining DC scan.
//
// Parameters:
// ssa: The successive approximation value for this scan.
//
void JpegDecoder::readDcRefine (JpegInputStream &inputstream, unsigned int ssa)
{
resetDcDifferences () ;
unsigned int restartcount = 0 ;
if (scanIsInterleaved ())
{
for (unsigned int mcurow = 0 ; mcurow < mcu_rows ; ++ mcurow)
{
callProgressFunction (mcurow * 100 / mcu_rows) ;
for (unsigned int mcucol = 0 ;
mcucol < mcu_cols ;
++ mcucol, ++restartcount)
{
if (restart_interval != 0 && restart_interval == restartcount)
{
resetDcDifferences () ;
processRestartMarker (inputstream) ;
restartcount = 0 ;
}
for (unsigned int cc = 0 ; cc < scan_component_count ; ++ cc)
{
for (unsigned int cy = 0 ;
cy < scan_components [cc]->verticalFrequency () ;
++ cy)
{
unsigned int durow = scan_components [cc]->verticalFrequency ()
* mcurow + cy ;
for (unsigned int cx = 0 ;
cx < scan_components [cc]->horizontalFrequency () ;
++ cx)
{
unsigned int ducol = scan_components [cc]->horizontalFrequency ()
* mcucol + cx ;
scan_components [cc]->decodeDcRefine (inputstream, durow, ducol, ssa) ;
}
}
}
}
}
}
else
{
for (unsigned int row = 0 ;
row < scan_components [0]->noninterleavedRows () ;
++ row)
{
callProgressFunction (row * 100 / scan_components [0]->noninterleavedRows ()) ;
for (unsigned int col = 0 ;
col < scan_components [0]->noninterleavedCols () ;
++ col, ++restartcount)
{
if (restart_interval != 0 && restart_interval == restartcount)
{
resetDcDifferences () ;
processRestartMarker (inputstream) ;
restartcount = 0 ;
}
scan_components [0]->decodeDcRefine (inputstream, row, col, ssa) ;
}
}
}
return ;
}
//
// 描述:
//
// This function reads the scan data for the first AC scan for a
// component. Progressive scans that read AC data cannot be
// interleaved.
//
// Parameters:
// sss: Spectral Selection Start
// sse: Spectral Selection End
// ssa: Spectral Selection
//
void JpegDecoder::readAcFirst (JpegInputStream &inputstream,
unsigned int sss,
unsigned int sse,
unsigned int ssa)
{
resetDcDifferences () ;
unsigned int restartcount = 0 ;
for (unsigned int row = 0 ;
row < scan_components [0]->noninterleavedRows () ;
++ row)
{
callProgressFunction (row * 100 / scan_components [0]->noninterleavedRows ()) ;
for (unsigned int col = 0 ;
col < scan_components [0]->noninterleavedCols () ;
++ col, ++restartcount)
{
if (restart_interval != 0 && restart_interval == restartcount)
{
resetDcDifferences () ;
processRestartMarker (inputstream) ;
restartcount = 0 ;
}
scan_components [0]->decodeAcFirst (inputstream,
row, col,
sss, sse,
ssa) ;
}
}
return ;
}
//
// 描述:
//
// This function reads the scan data for a refining AC scan for a
// component. Progressive scans that read AC data cannot be
// interleaved.
//
// Parameters:
// sss: Spectral Selection Start
// sse: Spectral Selection End
// ssa: Spectral Selection
//
void JpegDecoder::readAcRefine (JpegInputStream &inputstream,
unsigned int sss,
unsigned int sse,
unsigned int ssa)
{
resetDcDifferences () ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -