66namespace ImageSharp . Formats . Jpeg . Port
77{
88 using System ;
9- using System . Buffers ;
9+ using System . Collections . Generic ;
1010 using System . IO ;
11+ using System . Linq ;
1112
1213 using ImageSharp . Formats . Jpeg . Port . Components ;
1314 using ImageSharp . Memory ;
@@ -346,9 +347,9 @@ private void ProcessDefineHuffmanTablesMarker(int remaining)
346347
347348 using ( var huffmanData = new Buffer < byte > ( remaining ) )
348349 {
349- this . InputStream . Read ( huffmanData . Array , 1 , remaining ) ;
350+ this . InputStream . Skip ( 1 ) ;
351+ this . InputStream . Read ( huffmanData . Array , 0 , remaining ) ;
350352
351- int o = 0 ;
352353 for ( int i = 0 ; i < remaining ; )
353354 {
354355 byte huffmanTableSpec = huffmanData [ i ] ;
@@ -357,41 +358,95 @@ private void ProcessDefineHuffmanTablesMarker(int remaining)
357358
358359 for ( int j = 0 ; j < 16 ; j ++ )
359360 {
360- codeLengthSum += codeLengths [ j ] = huffmanData [ o ++ ] ;
361+ codeLengthSum += codeLengths [ j ] = huffmanData [ j ] ;
361362 }
362363
363364 // TODO: Pooling?
364365 short [ ] huffmanValues = new short [ codeLengthSum ] ;
365- using ( var values = new Buffer < byte > ( 256 ) )
366+ using ( var values = new Buffer < byte > ( codeLengthSum ) )
366367 {
367368 this . InputStream . Read ( values . Array , 0 , codeLengthSum ) ;
368369
369370 for ( int j = 0 ; j < codeLengthSum ; j ++ )
370371 {
371- huffmanValues [ j ] = values [ o ++ ] ;
372+ huffmanValues [ j ] = values [ j ] ;
372373 }
373- }
374374
375- i += 17 + codeLengthSum ;
375+ i += 17 + codeLengthSum ;
376376
377- this . BuildHuffmanTable (
378- huffmanTableSpec >> 4 == 0 ? this . dcHuffmanTables : this . acHuffmanTables ,
379- huffmanTableSpec & 15 ,
380- codeLengths ,
381- huffmanValues ) ;
377+ this . BuildHuffmanTable (
378+ huffmanTableSpec >> 4 == 0 ? this . dcHuffmanTables : this . acHuffmanTables ,
379+ huffmanTableSpec & 15 ,
380+ codeLengths ,
381+ huffmanValues ) ;
382+ }
382383 }
383384 }
384385 }
385386
386387 private void BuildHuffmanTable ( HuffmanTables tables , int index , byte [ ] codeLengths , short [ ] values )
387388 {
389+ // (╯°□°)╯︵ ┻━┻ Everything up to here is going well. I can't match the JavaScript now though.
388390 int length = 16 ;
389391 while ( length > 0 && codeLengths [ length - 1 ] == 0 )
390392 {
391393 length -- ;
392394 }
393395
394- Span < short > tableSpan = tables . Tables . GetRowSpan ( index ) ;
396+ var code = new Queue < HuffmanBranch > ( ) ;
397+ code . Enqueue ( new HuffmanBranch ( new List < HuffmanBranch > ( ) ) ) ;
398+ HuffmanBranch p = code . Peek ( ) ;
399+ p . Children = new List < HuffmanBranch > ( ) ;
400+ HuffmanBranch q ;
401+ int k = 0 ;
402+ try
403+ {
404+ for ( int i = 0 ; i < length ; i ++ )
405+ {
406+ for ( int j = 0 ; j < codeLengths [ i ] ; j ++ )
407+ {
408+ p = code . Dequeue ( ) ;
409+ p . Children . Add ( new HuffmanBranch ( values [ k ] ) ) ;
410+ while ( p . Index > 0 )
411+ {
412+ p = code . Dequeue ( ) ;
413+ }
414+
415+ p . Index ++ ;
416+ code . Enqueue ( p ) ;
417+ while ( code . Count <= i )
418+ {
419+ q = new HuffmanBranch ( new List < HuffmanBranch > ( ) ) ;
420+ code . Enqueue ( q ) ;
421+ p . Children . Add ( new HuffmanBranch ( q . Children ) ) ;
422+ p = q ;
423+ }
424+
425+ k ++ ;
426+ }
427+
428+ if ( i + 1 < length )
429+ {
430+ // p here points to last code
431+ q = new HuffmanBranch ( new List < HuffmanBranch > ( ) ) ;
432+ code . Enqueue ( q ) ;
433+ p . Children . Add ( new HuffmanBranch ( q . Children ) ) ;
434+ p = q ;
435+ }
436+ }
437+
438+ Span < HuffmanBranch > tableSpan = tables . Tables . GetRowSpan ( index ) ;
439+
440+ List < HuffmanBranch > result = code . Peek ( ) . Children ;
441+ for ( int i = 0 ; i < result . Count ; i ++ )
442+ {
443+ tableSpan [ i ] = result [ i ] ;
444+ }
445+ }
446+ catch ( Exception e )
447+ {
448+ throw ;
449+ }
395450 }
396451
397452 /// <summary>
0 commit comments