@ -44,6 +44,8 @@ namespace ImageSharp.Formats
/// </summary>
private const int MaxTh = 3 ;
private const int ThRowSize = MaxTh + 1 ;
/// <summary>
/// The maximum number of quantization tables
/// </summary>
@ -85,7 +87,9 @@ namespace ImageSharp.Formats
/// <summary>
/// The huffman trees
/// </summary>
private readonly Huffman [ , ] huffmanTrees ;
//private readonly Huffman[,] huffmanTrees;
private readonly Huffman [ ] huffmanTrees ;
/// <summary>
/// Quantization tables, in zigzag order.
@ -187,12 +191,16 @@ namespace ImageSharp.Formats
/// </summary>
private short verticalResolution ;
private int blockIndex ;
/// <summary>
/// Initializes a new instance of the <see cref="JpegDecoderCore"/> class.
/// </summary>
public JpegDecoderCore ( )
{
this . huffmanTrees = new Huffman [ MaxTc + 1 , MaxTh + 1 ] ;
//this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
this . huffmanTrees = new Huffman [ ( MaxTc + 1 ) * ( MaxTh + 1 ) ] ;
this . quantizationTables = new Block [ MaxTq + 1 ] ;
this . temp = new byte [ 2 * Block . BlockSize ] ;
this . componentArray = new Component [ MaxComponents ] ;
@ -201,23 +209,26 @@ namespace ImageSharp.Formats
this . bytes = new Bytes ( ) ;
// TODO: This looks like it could be static.
for ( int i = 0 ; i < MaxTc + 1 ; i + + )
{
for ( int j = 0 ; j < MaxTh + 1 ; j + + )
{
this . huffmanTrees [ i , j ] = new Huffman ( LutSize , MaxNCodes , MaxCodeLength ) ;
//this.huffmanTrees[i, j].Init(LutSize, MaxNCodes, MaxCodeLength);
this . huffmanTrees [ i * ThRowSize + j ] . Init ( LutSize , MaxNCodes , MaxCodeLength ) ;
}
}
for ( int i = 0 ; i < this . quantizationTables . Length ; i + + )
{
this . quantizationTables [ i ] = new Block ( ) ;
//this.quantizationTables[i] = new Block();
this . quantizationTables [ i ] . Init ( ) ;
}
for ( int i = 0 ; i < this . componentArray . Length ; i + + )
{
this . componentArray [ i ] = new Component ( ) ;
}
//for (int i = 0; i < this.componentArray.Length; i++)
//{
// this.componentArray[i] = new Component();
//}
}
@ -502,92 +513,96 @@ namespace ImageSharp.Formats
throw new ImageFormatException ( "Bad Th value" ) ;
}
Huffman huffman = this . huffmanTrees [ tc , th ] ;
ProcessDefineHuffmanTablesMarkerLoop ( ref this . huffmanTrees [ tc * ThRowSize + th ] , ref remaining ) ;
}
}
// Read nCodes and huffman.Valuess (and derive h.Length).
// nCodes[i] is the number of codes with code length i.
// h.Length is the total number of codes.
huffman . Length = 0 ;
private void ProcessDefineHuffmanTablesMarkerLoop ( ref Huffman huffman , ref int remaining )
{
int [ ] ncodes = new int [ MaxCodeLength ] ;
for ( int i = 0 ; i < ncodes . Length ; i + + )
{
ncodes [ i ] = this . temp [ i + 1 ] ;
huffman . Length + = ncodes [ i ] ;
}
// Read nCodes and huffman.Valuess (and derive h.Length).
// nCodes[i] is the number of codes with code length i.
// h.Length is the total number of codes.
huffman . Length = 0 ;
if ( huffman . Length = = 0 )
{
throw new ImageFormatException ( "Huffman table has zero length" ) ;
}
int [ ] ncodes = new int [ MaxCodeLength ] ;
for ( int i = 0 ; i < ncodes . Length ; i + + )
{
ncodes [ i ] = this . temp [ i + 1 ] ;
huffman . Length + = ncodes [ i ] ;
}
if ( huffman . Length > MaxNCodes )
{
throw new ImageFormatException ( "Huffman table has excessive length" ) ;
}
if ( huffman . Length = = 0 )
{
throw new ImageFormatException ( "Huffman table has zero length" ) ;
}
remaining - = huffman . Length + 1 7 ;
if ( remaining < 0 )
{
throw new ImageFormatException ( "DHT has wrong length" ) ;
}
if ( huffman . Length > MaxNCodes )
{
throw new ImageFormatException ( "Huffman table has excessive length" ) ;
}
this . ReadFull ( huffman . Values , 0 , huffman . Length ) ;
remaining - = huffman . Length + 1 7 ;
if ( remaining < 0 )
{
throw new ImageFormatException ( "DHT has wrong length" ) ;
}
// Derive the look-up table.
for ( int i = 0 ; i < huffman . Lut . Length ; i + + )
{
huffman . Lut [ i ] = 0 ;
}
this . ReadFull ( huffman . Values , 0 , huffman . Length ) ;
// Derive the look-up table.
for ( int i = 0 ; i < huffman . Lut . Length ; i + + )
{
huffman . Lut [ i ] = 0 ;
}
uint x = 0 , code = 0 ;
uint x = 0 , code = 0 ;
for ( int i = 0 ; i < LutSize ; i + + )
for ( int i = 0 ; i < LutSize ; i + + )
{
code < < = 1 ;
for ( int j = 0 ; j < ncodes [ i ] ; j + + )
{
code < < = 1 ;
// The codeLength is 1+i, so shift code by 8-(1+i) to
// calculate the high bits for every 8-bit sequence
// whose codeLength's high bits matches code.
// The high 8 bits of lutValue are the encoded value.
// The low 8 bits are 1 plus the codeLength.
byte base2 = ( byte ) ( code < < ( 7 - i ) ) ;
ushort lutValue = ( ushort ) ( ( huffman . Values [ x ] < < 8 ) | ( 2 + i ) ) ;
for ( int j = 0 ; j < ncodes [ i ] ; j + + )
for ( int k = 0 ; k < 1 < < ( 7 - i ) ; k + + )
{
// The codeLength is 1+i, so shift code by 8-(1+i) to
// calculate the high bits for every 8-bit sequence
// whose codeLength's high bits matches code.
// The high 8 bits of lutValue are the encoded value.
// The low 8 bits are 1 plus the codeLength.
byte base2 = ( byte ) ( code < < ( 7 - i ) ) ;
ushort lutValue = ( ushort ) ( ( huffman . Values [ x ] < < 8 ) | ( 2 + i ) ) ;
for ( int k = 0 ; k < 1 < < ( 7 - i ) ; k + + )
{
huffman . Lut [ base2 | k ] = lutValue ;
}
code + + ;
x + + ;
huffman . Lut [ base2 | k ] = lutValue ;
}
code + + ;
x + + ;
}
}
// Derive minCodes, maxCodes, and indices.
int c = 0 , index = 0 ;
for ( int i = 0 ; i < ncodes . Length ; i + + )
// Derive minCodes, maxCodes, and indices.
int c = 0 , index = 0 ;
for ( int i = 0 ; i < ncodes . Length ; i + + )
{
int nc = ncodes [ i ] ;
if ( nc = = 0 )
{
int nc = ncodes [ i ] ;
if ( nc = = 0 )
{
huffman . MinCodes [ i ] = - 1 ;
huffman . MaxCodes [ i ] = - 1 ;
huffman . Indices [ i ] = - 1 ;
}
else
{
huffman . MinCodes [ i ] = c ;
huffman . MaxCodes [ i ] = c + nc - 1 ;
huffman . Indices [ i ] = index ;
c + = nc ;
index + = nc ;
}
c < < = 1 ;
huffman . MinCodes [ i ] = - 1 ;
huffman . MaxCodes [ i ] = - 1 ;
huffman . Indices [ i ] = - 1 ;
}
else
{
huffman . MinCodes [ i ] = c ;
huffman . MaxCodes [ i ] = c + nc - 1 ;
huffman . Indices [ i ] = index ;
c + = nc ;
index + = nc ;
}
c < < = 1 ;
}
}
@ -596,7 +611,7 @@ namespace ImageSharp.Formats
/// </summary>
/// <param name="huffman">The huffman value</param>
/// <returns>The <see cref="byte"/></returns>
private byte DecodeHuffman ( Huffman huffman )
private byte DecodeHuffman ( ref Huffman huffman )
{
if ( huffman . Length = = 0 )
{
@ -1480,7 +1495,8 @@ namespace ImageSharp.Formats
this . ReadFull ( this . temp , 0 , remaining ) ;
byte scanComponentCount = this . temp [ 0 ] ;
if ( remaining ! = 4 + ( 2 * scanComponentCount ) )
int scanComponentCountBy2 = 2 * scanComponentCount ;
if ( remaining ! = 4 + scanComponentCountBy2 )
{
throw new ImageFormatException ( "SOS length inconsistent with number of components" ) ;
}
@ -1490,51 +1506,7 @@ namespace ImageSharp.Formats
for ( int i = 0 ; i < scanComponentCount ; i + + )
{
// Component selector.
int cs = this . temp [ 1 + ( 2 * i ) ] ;
int compIndex = - 1 ;
for ( int j = 0 ; j < this . componentCount ; j + + )
{
Component compv = this . componentArray [ j ] ;
if ( cs = = compv . Identifier )
{
compIndex = j ;
}
}
if ( compIndex < 0 )
{
throw new ImageFormatException ( "Unknown component selector" ) ;
}
scan [ i ] . Index = ( byte ) compIndex ;
// Section B.2.3 states that "the value of Cs_j shall be different from
// the values of Cs_1 through Cs_(j-1)". Since we have previously
// verified that a frame's component identifiers (C_i values in section
// B.2.2) are unique, it suffices to check that the implicit indexes
// into comp are unique.
for ( int j = 0 ; j < i ; j + + )
{
if ( scan [ i ] . Index = = scan [ j ] . Index )
{
throw new ImageFormatException ( "Repeated component selector" ) ;
}
}
totalHv + = this . componentArray [ compIndex ] . HorizontalFactor * this . componentArray [ compIndex ] . VerticalFactor ;
scan [ i ] . DcTableSelector = ( byte ) ( this . temp [ 2 + ( 2 * i ) ] > > 4 ) ;
if ( scan [ i ] . DcTableSelector > MaxTh )
{
throw new ImageFormatException ( "Bad DC table selector value" ) ;
}
scan [ i ] . AcTableSelector = ( byte ) ( this . temp [ 2 + ( 2 * i ) ] & 0x0f ) ;
if ( scan [ i ] . AcTableSelector > MaxTh )
{
throw new ImageFormatException ( "Bad AC table selector value" ) ;
}
ProcessScanImpl ( i , ref scan [ i ] , scan , ref totalHv ) ;
}
// Section B.2.3 states that if there is more than one component then the
@ -1565,10 +1537,10 @@ namespace ImageSharp.Formats
if ( this . isProgressive )
{
zigStart = this . temp [ 1 + ( 2 * scanComponentCount ) ] ;
zigEnd = this . temp [ 2 + ( 2 * scanComponentCount ) ] ;
ah = this . temp [ 3 + ( 2 * scanComponentCount ) ] > > 4 ;
al = this . temp [ 3 + ( 2 * scanComponentCount ) ] & 0x0f ;
zigStart = this . temp [ 1 + scanComponentCountBy2 ] ;
zigEnd = this . temp [ 2 + scanComponentCountBy2 ] ;
ah = this . temp [ 3 + scanComponentCountBy2 ] > > 4 ;
al = this . temp [ 3 + scanComponentCountBy2 ] & 0x0f ;
if ( ( zigStart = = 0 & & zigEnd ! = 0 ) | | zigStart > zigEnd | | Block . BlockSize < = zigEnd )
{
@ -1608,7 +1580,7 @@ namespace ImageSharp.Formats
for ( int j = 0 ; j < this . progCoeffs [ compIndex ] . Length ; j + + )
{
this . progCoeffs [ compIndex ] [ j ] = new Block ( ) ;
this . progCoeffs [ compIndex ] [ j ] . Init ( ) ;
}
}
}
@ -1620,7 +1592,7 @@ namespace ImageSharp.Formats
byte expectedRst = JpegConstants . Markers . RST0 ;
// b is the decoded coefficients block, in natural (not zig-zag) order.
Block b ;
//Block b;
int [ ] dc = new int [ MaxComponents ] ;
// bx and by are the location of the current block, in units of 8x8
@ -1636,7 +1608,7 @@ namespace ImageSharp.Formats
int compIndex = scan [ i ] . Index ;
int hi = this . componentArray [ compIndex ] . HorizontalFactor ;
int vi = this . componentArray [ compIndex ] . VerticalFactor ;
Block qt = this . quantizationTables [ this . componentArray [ compIndex ] . Selector ] ;
for ( int j = 0 ; j < hi * vi ; j + + )
{
@ -1679,168 +1651,28 @@ namespace ImageSharp.Formats
}
}
var qtIndex = this . componentArray [ compIndex ] . Selector ;
// Load the previous partially decoded coefficients, if applicable.
b = this . isProgressive ? this . progCoeffs [ compIndex ] [ ( ( @by * mxx ) * hi ) + bx ] : new Block ( ) ;
if ( ah ! = 0 )
{
this . Refine ( b , this . huffmanTrees [ AcTable , scan [ i ] . AcTableSelector ] , zigStart , zigEnd , 1 < < al ) ;
}
else
{
int zig = zigStart ;
if ( zig = = 0 )
{
zig + + ;
// Decode the DC coefficient, as specified in section F.2.2.1.
byte value = this . DecodeHuffman ( this . huffmanTrees [ DcTable , scan [ i ] . DcTableSelector ] ) ;
if ( value > 1 6 )
{
throw new ImageFormatException ( "Excessive DC component" ) ;
}
int deltaDC = this . ReceiveExtend ( value ) ;
dc [ compIndex ] + = deltaDC ;
b [ 0 ] = dc [ compIndex ] < < al ;
}
if ( zig < = zigEnd & & this . eobRun > 0 )
{
this . eobRun - - ;
}
else
{
// Decode the AC coefficients, as specified in section F.2.2.2.
Huffman huffv = this . huffmanTrees [ AcTable , scan [ i ] . AcTableSelector ] ;
for ( ; zig < = zigEnd ; zig + + )
{
byte value = this . DecodeHuffman ( huffv ) ;
byte val0 = ( byte ) ( value > > 4 ) ;
byte val1 = ( byte ) ( value & 0x0f ) ;
if ( val1 ! = 0 )
{
zig + = val0 ;
if ( zig > zigEnd )
{
break ;
}
int ac = this . ReceiveExtend ( val1 ) ;
b [ Unzig [ zig ] ] = ac < < al ;
}
else
{
if ( val0 ! = 0x0f )
{
this . eobRun = ( ushort ) ( 1 < < val0 ) ;
if ( val0 ! = 0 )
{
this . eobRun | = ( ushort ) this . DecodeBits ( val0 ) ;
}
this . eobRun - - ;
break ;
}
zig + = 0x0f ;
}
}
}
}
//b = this.isProgressive ? this.progCoeffs[compIndex][blockIndex] : new Block();
if ( this . isProgressive )
{
if ( zigEnd ! = Block . BlockSize - 1 | | al ! = 0 )
{
// We haven't completely decoded this 8x8 block. Save the coefficients.
this . progCoeffs [ compIndex ] [ ( ( by * mxx ) * hi ) + bx ] = b ;
// At this point, we could execute the rest of the loop body to dequantize and
// perform the inverse DCT, to save early stages of a progressive image to the
// *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
// the jpeg.Decode function does not return until the entire image is decoded,
// so we "continue" here to avoid wasted computation.
continue ;
}
}
// Dequantize, perform the inverse DCT and store the block to the image.
for ( int zig = 0 ; zig < Block . BlockSize ; zig + + )
{
b [ Unzig [ zig ] ] * = qt [ zig ] ;
}
IDCT . Transform ( b ) ;
byte [ ] dst ;
int offset ;
int stride ;
if ( this . componentCount = = 1 )
{
dst = this . grayImage . Pixels ;
stride = this . grayImage . Stride ;
offset = this . grayImage . Offset + ( 8 * ( ( by * this . grayImage . Stride ) + bx ) ) ;
blockIndex = ( ( @by * mxx ) * hi ) + bx ;
ProcessBlockImpl ( ah ,
ref this . progCoeffs [ compIndex ] [ blockIndex ] ,
scan , i , zigStart , zigEnd , al , dc , compIndex , @by , mxx , hi , bx ,
ref this . quantizationTables [ qtIndex ]
) ;
}
else
{
switch ( compIndex )
{
case 0 :
dst = this . ycbcrImage . YChannel ;
stride = this . ycbcrImage . YStride ;
offset = this . ycbcrImage . YOffset + ( 8 * ( ( by * this . ycbcrImage . YStride ) + bx ) ) ;
break ;
case 1 :
dst = this . ycbcrImage . CbChannel ;
stride = this . ycbcrImage . CStride ;
offset = this . ycbcrImage . COffset + ( 8 * ( ( by * this . ycbcrImage . CStride ) + bx ) ) ;
break ;
case 2 :
dst = this . ycbcrImage . CrChannel ;
stride = this . ycbcrImage . CStride ;
offset = this . ycbcrImage . COffset + ( 8 * ( ( by * this . ycbcrImage . CStride ) + bx ) ) ;
break ;
case 3 :
dst = this . blackPixels ;
stride = this . blackStride ;
offset = 8 * ( ( by * this . blackStride ) + bx ) ;
break ;
default :
throw new ImageFormatException ( "Too many components" ) ;
}
}
// Level shift by +128, clip to [0, 255], and write to dst.
for ( int y = 0 ; y < 8 ; y + + )
{
int y8 = y * 8 ;
int yStride = y * stride ;
for ( int x = 0 ; x < 8 ; x + + )
{
int c = b [ y8 + x ] ;
if ( c < - 1 2 8 )
{
c = 0 ;
}
else if ( c > 1 2 7 )
{
c = 2 5 5 ;
}
else
{
c + = 1 2 8 ;
}
dst [ yStride + x + offset ] = ( byte ) c ;
}
var b = new Block ( ) ;
b . Init ( ) ;
ProcessBlockImpl ( ah , ref b , scan , i , zigStart , zigEnd , al , dc , compIndex , @by , mxx , hi ,
bx , ref this . quantizationTables [ qtIndex ]
) ;
}
}
@ -1883,6 +1715,226 @@ namespace ImageSharp.Formats
// for my
}
private void ProcessBlockImpl ( int ah , ref Block b , Scan [ ] scan , int i , int zigStart , int zigEnd , int al ,
int [ ] dc , int compIndex , int @by , int mxx , int hi , int bx , ref Block qt )
{
if ( ah ! = 0 )
{
this . Refine ( ref b , ref this . huffmanTrees [ AcTable * ThRowSize + scan [ i ] . AcTableSelector ] , zigStart , zigEnd , 1 < < al ) ;
}
else
{
int zig = zigStart ;
if ( zig = = 0 )
{
zig + + ;
// Decode the DC coefficient, as specified in section F.2.2.1.
byte value = this . DecodeHuffman ( ref this . huffmanTrees [ DcTable * ThRowSize + scan [ i ] . DcTableSelector ] ) ;
if ( value > 1 6 )
{
throw new ImageFormatException ( "Excessive DC component" ) ;
}
int deltaDC = this . ReceiveExtend ( value ) ;
dc [ compIndex ] + = deltaDC ;
b [ 0 ] = dc [ compIndex ] < < al ;
}
if ( zig < = zigEnd & & this . eobRun > 0 )
{
this . eobRun - - ;
}
else
{
// Decode the AC coefficients, as specified in section F.2.2.2.
//Huffman huffv = ;
for ( ; zig < = zigEnd ; zig + + )
{
byte value = this . DecodeHuffman ( ref this . huffmanTrees [ AcTable * ThRowSize + scan [ i ] . AcTableSelector ] ) ;
byte val0 = ( byte ) ( value > > 4 ) ;
byte val1 = ( byte ) ( value & 0x0f ) ;
if ( val1 ! = 0 )
{
zig + = val0 ;
if ( zig > zigEnd )
{
break ;
}
int ac = this . ReceiveExtend ( val1 ) ;
b [ Unzig [ zig ] ] = ac < < al ;
}
else
{
if ( val0 ! = 0x0f )
{
this . eobRun = ( ushort ) ( 1 < < val0 ) ;
if ( val0 ! = 0 )
{
this . eobRun | = ( ushort ) this . DecodeBits ( val0 ) ;
}
this . eobRun - - ;
break ;
}
zig + = 0x0f ;
}
}
}
}
if ( this . isProgressive )
{
if ( zigEnd ! = Block . BlockSize - 1 | | al ! = 0 )
{
// We haven't completely decoded this 8x8 block. Save the coefficients.
this . progCoeffs [ compIndex ] [ ( ( @by * mxx ) * hi ) + bx ] = b ;
// At this point, we could execute the rest of the loop body to dequantize and
// perform the inverse DCT, to save early stages of a progressive image to the
// *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
// the jpeg.Decode function does not return until the entire image is decoded,
// so we "continue" here to avoid wasted computation.
return ;
}
}
// Dequantize, perform the inverse DCT and store the block to the image.
for ( int zig = 0 ; zig < Block . BlockSize ; zig + + )
{
b [ Unzig [ zig ] ] * = qt [ zig ] ;
}
IDCT . Transform ( ref b ) ;
byte [ ] dst ;
int offset ;
int stride ;
if ( this . componentCount = = 1 )
{
dst = this . grayImage . Pixels ;
stride = this . grayImage . Stride ;
offset = this . grayImage . Offset + ( 8 * ( ( @by * this . grayImage . Stride ) + bx ) ) ;
}
else
{
switch ( compIndex )
{
case 0 :
dst = this . ycbcrImage . YChannel ;
stride = this . ycbcrImage . YStride ;
offset = this . ycbcrImage . YOffset + ( 8 * ( ( @by * this . ycbcrImage . YStride ) + bx ) ) ;
break ;
case 1 :
dst = this . ycbcrImage . CbChannel ;
stride = this . ycbcrImage . CStride ;
offset = this . ycbcrImage . COffset + ( 8 * ( ( @by * this . ycbcrImage . CStride ) + bx ) ) ;
break ;
case 2 :
dst = this . ycbcrImage . CrChannel ;
stride = this . ycbcrImage . CStride ;
offset = this . ycbcrImage . COffset + ( 8 * ( ( @by * this . ycbcrImage . CStride ) + bx ) ) ;
break ;
case 3 :
dst = this . blackPixels ;
stride = this . blackStride ;
offset = 8 * ( ( @by * this . blackStride ) + bx ) ;
break ;
default :
throw new ImageFormatException ( "Too many components" ) ;
}
}
// Level shift by +128, clip to [0, 255], and write to dst.
for ( int y = 0 ; y < 8 ; y + + )
{
int y8 = y * 8 ;
int yStride = y * stride ;
for ( int x = 0 ; x < 8 ; x + + )
{
int c = b [ y8 + x ] ;
if ( c < - 1 2 8 )
{
c = 0 ;
}
else if ( c > 1 2 7 )
{
c = 2 5 5 ;
}
else
{
c + = 1 2 8 ;
}
dst [ yStride + x + offset ] = ( byte ) c ;
}
}
}
private void ProcessScanImpl ( int i , ref Scan currentScan , Scan [ ] scan , ref int totalHv )
{
// Component selector.
int cs = this . temp [ 1 + ( 2 * i ) ] ;
int compIndex = - 1 ;
for ( int j = 0 ; j < this . componentCount ; j + + )
{
//Component compv = ;
if ( cs = = this . componentArray [ j ] . Identifier )
{
compIndex = j ;
}
}
if ( compIndex < 0 )
{
throw new ImageFormatException ( "Unknown component selector" ) ;
}
currentScan . Index = ( byte ) compIndex ;
ProcessComponentImpl ( i , ref currentScan , scan , ref totalHv , ref this . componentArray [ compIndex ] ) ;
}
private void ProcessComponentImpl ( int i , ref Scan currentScan , Scan [ ] scan , ref int totalHv , ref Component currentComponent )
{
// Section B.2.3 states that "the value of Cs_j shall be different from
// the values of Cs_1 through Cs_(j-1)". Since we have previously
// verified that a frame's component identifiers (C_i values in section
// B.2.2) are unique, it suffices to check that the implicit indexes
// into comp are unique.
for ( int j = 0 ; j < i ; j + + )
{
if ( currentScan . Index = = scan [ j ] . Index )
{
throw new ImageFormatException ( "Repeated component selector" ) ;
}
}
totalHv + = currentComponent . HorizontalFactor * currentComponent . VerticalFactor ;
currentScan . DcTableSelector = ( byte ) ( this . temp [ 2 + ( 2 * i ) ] > > 4 ) ;
if ( currentScan . DcTableSelector > MaxTh )
{
throw new ImageFormatException ( "Bad DC table selector value" ) ;
}
currentScan . AcTableSelector = ( byte ) ( this . temp [ 2 + ( 2 * i ) ] & 0x0f ) ;
if ( currentScan . AcTableSelector > MaxTh )
{
throw new ImageFormatException ( "Bad AC table selector value" ) ;
}
}
/// <summary>
/// Decodes a successive approximation refinement block, as specified in section G.1.2.
/// </summary>
@ -1891,7 +1943,7 @@ namespace ImageSharp.Formats
/// <param name="zigStart">The zig-zag start index</param>
/// <param name="zigEnd">The zig-zag end index</param>
/// <param name="delta">The low transform offset</param>
private void Refine ( Block b , Huffman h , int zigStart , int zigEnd , int delta )
private void Refine ( ref Block b , ref Huffman h , int zigStart , int zigEnd , int delta )
{
// Refining a DC component is trivial.
if ( zigStart = = 0 )
@ -1918,7 +1970,7 @@ namespace ImageSharp.Formats
{
bool done = false ;
int z = 0 ;
byte val = this . DecodeHuffman ( h ) ;
byte val = this . DecodeHuffman ( ref h ) ;
int val0 = val > > 4 ;
int val1 = val & 0x0f ;