@@ -42,8 +42,7 @@ public override SimpleBitmap Decode(byte[] src) {
4242 SimpleBitmap bmp = new SimpleBitmap ( ) ;
4343
4444 ReadMarkers ( src , bmp ) ;
45- Fail ( "JPEG decoder unfinished" ) ;
46- return null ;
45+ return bmp ;
4746 }
4847
4948
@@ -249,7 +248,7 @@ void SetHuffTables(byte compID, byte tables) {
249248
250249 static byte [ ] zigzag_to_linear = new byte [ 64 ]
251250 {
252- 0 , 1 , 8 , 16 , 9 , 2 , 3 , 10 ,
251+ 0 , 1 , 8 , 16 , 9 , 2 , 3 , 10 ,
253252 17 , 24 , 32 , 25 , 18 , 11 , 4 , 5 ,
254253 12 , 19 , 26 , 33 , 40 , 48 , 41 , 34 ,
255254 27 , 20 , 13 , 6 , 7 , 14 , 21 , 28 ,
@@ -262,7 +261,6 @@ void SetHuffTables(byte compID, byte tables) {
262261 void DecodeMCUs ( byte [ ] src , SimpleBitmap bmp ) {
263262 int mcus_x = ( bmp . Width + 7 ) / 8 ;
264263 int mcus_y = ( bmp . Height + 7 ) / 8 ;
265- bit_offset = AdvanceOffset ( 0 ) ;
266264
267265 JpegComponent [ ] comps = this . comps ;
268266 int [ ] block = new int [ 64 ] ;
@@ -307,24 +305,60 @@ void DecodeMCUs(byte[] src, SimpleBitmap bmp) {
307305 }
308306 } while ( idx < 64 ) ;
309307
310- Fail ( "DE" ) ;
308+ float [ ] output = new float [ 64 ] ;
309+ IDCT ( block , output ) ;
310+
311+ for ( int YY = 0 ; YY < 8 ; YY ++ )
312+ for ( int XX = 0 ; XX < 8 ; XX ++ )
313+ {
314+ int globalX = x * 8 + XX ;
315+ int globalY = y * 8 + YY ;
316+ if ( globalX < bmp . Width && globalY < bmp . Height ) {
317+ byte rgb = ( byte ) output [ YY * 8 + XX ] ;
318+ Pixel p = new Pixel ( rgb , rgb , rgb , 255 ) ;
319+ bmp . pixels [ globalY * bmp . Width + globalX ] = p ;
320+ }
321+ }
322+ // Fail("DE");
323+ }
324+ }
325+ // Fail("MCUs");
326+ }
327+
328+ void IDCT ( int [ ] block , float [ ] output ) {
329+ for ( int y = 0 ; y < 8 ; y ++ )
330+ for ( int x = 0 ; x < 8 ; x ++ )
331+ {
332+ float sum = 0.0f ;
333+ for ( int v = 0 ; v < 8 ; v ++ )
334+ for ( int u = 0 ; u < 8 ; u ++ )
335+ {
336+ float cu = u == 0 ? 0.70710678f : 1.0f ;
337+ float cv = v == 0 ? 0.70710678f : 1.0f ;
338+
339+ float suv = block [ v * 8 + u ] ;
340+ float cosu = ( float ) Math . Cos ( ( 2 * x + 1 ) * u * Math . PI / 16.0 ) ;
341+ float cosv = ( float ) Math . Cos ( ( 2 * y + 1 ) * v * Math . PI / 16.0 ) ;
342+
343+ sum += cu * cv * suv * cosu * cosv ;
311344 }
345+ output [ y * 8 + x ] = ( sum / 4.0f ) + 128.0f ; // undo level shift at end
312346 }
313- Fail ( "MCUs" ) ;
314347 }
315348
316349 uint bit_buf ;
317350 int bit_cnt ;
318- int bit_offset ;
351+ bool end ;
319352
320353 int ReadBits ( byte [ ] src , int count ) {
321- while ( bit_cnt <= 24 ) {
322- byte next = src [ bit_offset ++ ] ;
354+ while ( bit_cnt <= 24 && ! end ) {
355+ byte next = src [ buf_offset ++ ] ;
323356 // JPEG byte stuffing
324357 // TODO restart markers ?
325358 if ( next == 0xFF ) {
326- byte type = src [ bit_offset ++ ] ;
327- if ( type != 0 ) Fail ( "unexpected marker" ) ;
359+ byte type = src [ buf_offset ++ ] ;
360+ if ( type == 0xD9 ) { end = true ; buf_offset -= 2 ; }
361+ else if ( type != 0 ) Fail ( "unexpected marker" ) ;
328362 }
329363
330364 bit_buf <<= 8 ;
0 commit comments