@@ -319,13 +319,31 @@ var Jbig2Image = (function Jbig2ImageClosure() {
319
319
{x : 1 , y : -1 }, {x : -4 , y : 0 }, {x : -3 , y : 0 }, {x : -2 , y : 0 }, {x : -1 , y : 0 }]
320
320
];
321
321
322
+ var RefinementTemplates = [
323
+ {
324
+ coding : [{x : 0 , y : -1 }, {x : 1 , y : -1 }, {x : -1 , y : 0 }],
325
+ reference : [{x : 0 , y : -1 }, {x : 1 , y : -1 }, {x : -1 , y : 0 }, {x : 0 , y : 0 },
326
+ {x : 1 , y : 0 }, {x : -1 , y : 1 }, {x : 0 , y : 1 }, {x : 1 , y : 1 }]
327
+ },
328
+ {
329
+ coding : [{x : -1 , y : -1 }, {x : 0 , y : -1 }, {x : 1 , y : -1 }, {x : -1 , y : 0 }],
330
+ reference : [{x : 0 , y : -1 }, {x : -1 , y : 0 }, {x : 0 , y : 0 }, {x : 1 , y : 0 },
331
+ {x : 0 , y : 1 }, {x : 1 , y : 1 }]
332
+ }
333
+ ];
334
+
322
335
var ReusedContexts = [
323
336
0x1CD3 , // '00111001101' (template) + '0011' (at),
324
337
0x079A , // '001111001101' + '0',
325
338
0x00E3 , // '001110001' + '1',
326
339
0x018B // '011000101' + '1'
327
340
];
328
341
342
+ var RefinementReusedContexts = [
343
+ 0x0020 , // '000' + '0' (coding) + '00010000' + '0' (reference)
344
+ 0x0008 // '0000' + '001000'
345
+ ];
346
+
329
347
function log2 (x ) {
330
348
var n = 1 , i = 0 ;
331
349
while (x > n ) {
@@ -353,7 +371,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
353
371
return (data [start ] << 24 ) >> 24 ;
354
372
}
355
373
356
- // 6.2
374
+ // 6.2 Generic Region Decoding Procedure
357
375
function decodeBitmap (mmr , width , height , templateIndex , prediction , skip , at ,
358
376
data , start , end ) {
359
377
if (mmr )
@@ -368,7 +386,8 @@ var Jbig2Image = (function Jbig2ImageClosure() {
368
386
templateX [k ] = template [k ].x ;
369
387
templateY [k ] = template [k ].y ;
370
388
}
371
- var pseudoPixelContext = ReusedContexts [template ];
389
+
390
+ var pseudoPixelContext = ReusedContexts [templateIndex ];
372
391
var bitmap = [];
373
392
var decoder , contexts , cx ;
374
393
if (data instanceof ArithmeticDecoder ) {
@@ -382,6 +401,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
382
401
decoder = new ArithmeticDecoder (data , start , end );
383
402
contexts = [] ;
384
403
}
404
+
385
405
var ltp = 0 ;
386
406
for (var i = 0 ; i < height ; i ++) {
387
407
if (prediction ) {
@@ -420,6 +440,90 @@ var Jbig2Image = (function Jbig2ImageClosure() {
420
440
return bitmap ;
421
441
}
422
442
443
+ // 6.3.2 Generic Refinement Region Decoding Procedure
444
+ function decodeRefinement (width , height , templateIndex , referenceBitmap ,
445
+ offsetX , offsetY , prediction , at ,
446
+ data , start , end ) {
447
+ var codingTemplate = RefinementTemplates [templateIndex ].coding ;
448
+ if (templateIndex == 0 )
449
+ codingTemplate = codingTemplate .concat ( [at [0 ]]);
450
+ var codingTemplateLength = codingTemplate .length ;
451
+ var codingTemplateX = new Int32Array (codingTemplateLength );
452
+ var codingTemplateY = new Int32Array (codingTemplateLength );
453
+ for (var k = 0 ; k < codingTemplateLength ; k ++) {
454
+ codingTemplateX [k ] = codingTemplate [k ].x ;
455
+ codingTemplateY [k ] = codingTemplate [k ].y ;
456
+ }
457
+ var referenceTemplate = RefinementTemplates [templateIndex ].reference ;
458
+ if (templateIndex == 0 )
459
+ referenceTemplate = referenceTemplate .concat ( [at [1 ]]);
460
+ var referenceTemplateLength = referenceTemplate .length ;
461
+ var referenceTemplateX = new Int32Array (referenceTemplateLength );
462
+ var referenceTemplateY = new Int32Array (referenceTemplateLength );
463
+ for (var k = 0 ; k < referenceTemplateLength ; k ++) {
464
+ referenceTemplateX [k ] = referenceTemplate [k ].x ;
465
+ referenceTemplateY [k ] = referenceTemplate [k ].y ;
466
+ }
467
+ var referenceWidth = referenceBitmap [0 ].length ;
468
+ var referenceHeight = referenceBitmap .length ;
469
+
470
+ var pseudoPixelContext = RefinementReusedContexts [templateIndex ];
471
+ var bitmap = [];
472
+ var decoder , contexts , cx ;
473
+ if (data instanceof ArithmeticDecoder ) {
474
+ decoder = data ;
475
+ var contextCache = start ;
476
+ if ('GR' in contextCache )
477
+ contexts = contextCache ['GR' ];
478
+ else
479
+ contextCache ['GR' ] = contexts = [];
480
+ } else {
481
+ decoder = new ArithmeticDecoder (data , start , end );
482
+ contexts = [] ;
483
+ }
484
+
485
+ var ltp = 0 ;
486
+ for (var i = 0 ; i < height ; i ++) {
487
+ if (prediction ) {
488
+ cx = contexts [pseudoPixelContext ];
489
+ if (!cx )
490
+ contexts [pseudoPixelContext ] = cx = {index : 0 , mps : 0 };
491
+ var sltp = decoder .readBit (cx );
492
+ ltp ^= sltp ;
493
+ }
494
+ var row = new Uint8Array (width );
495
+ bitmap .push (row );
496
+ for (var j = 0 ; j < width ; j ++) {
497
+ if (ltp )
498
+ throw 'prediction is not supported' ;
499
+
500
+ var contextLabel = 0 ;
501
+ for (var k = 0 ; k < codingTemplateLength ; k ++) {
502
+ var i0 = i + codingTemplateY [k ], j0 = j + codingTemplateX [k ];
503
+ if (i0 < 0 || j0 < 0 || j0 >= width )
504
+ contextLabel <<= 1 ; // out of bound pixel
505
+ else
506
+ contextLabel = (contextLabel << 1 ) | bitmap [i0 ][j0 ];
507
+ }
508
+ for (var k = 0 ; k < referenceTemplateLength ; k ++) {
509
+ var i0 = i + referenceTemplateY [k ] + offsetY ;
510
+ var j0 = j + referenceTemplateX [k ] + offsetX ;
511
+ if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth )
512
+ contextLabel <<= 1 ; // out of bound pixel
513
+ else
514
+ contextLabel = (contextLabel << 1 ) | referenceBitmap [i0 ][j0 ];
515
+ }
516
+ cx = contexts [contextLabel ];
517
+ if (!cx )
518
+ contexts [contextLabel ] = cx = {index : 0 , mps : 0 };
519
+ var pixel = decoder .readBit (cx );
520
+ row [j ] = pixel ;
521
+ }
522
+ }
523
+
524
+ return bitmap ;
525
+ }
526
+
423
527
// 6.5.5 Decoding the symbol dictionary
424
528
function decodeSymbolDictionary (huffman , refinement , symbols ,
425
529
numberOfNewSymbols , numberOfExportedSymbols ,
@@ -428,12 +532,11 @@ var Jbig2Image = (function Jbig2ImageClosure() {
428
532
data , start , end ) {
429
533
if (huffman )
430
534
throw 'huffman is not supported' ;
431
- if (refinement )
432
- throw 'refinement is not supported' ;
433
535
434
536
var newSymbols = [];
435
537
var currentHeight = 0 ;
436
538
var contextCache = {};
539
+ var symbolCodeLength = log2 (symbols .length + numberOfNewSymbols );
437
540
var decoder = new ArithmeticDecoder (data , start , end );
438
541
while (newSymbols .length < numberOfNewSymbols ) {
439
542
var deltaHeight = decodeInteger (contextCache , 'IADH' , decoder ); // 6.5.6
@@ -446,9 +549,25 @@ var Jbig2Image = (function Jbig2ImageClosure() {
446
549
break ; // OOB
447
550
currentWidth += deltaWidth ;
448
551
totalWidth += currentWidth ;
449
- // 6.5.8.1 Direct-coded symbol bitmap
450
- var bitmap = decodeBitmap (false , currentWidth , currentHeight ,
451
- templateIndex , false , null , at , decoder , contextCache );
552
+ var bitmap ;
553
+ if (refinement ) {
554
+ // 6.5.8.2 Refinement/aggregate-coded symbol bitmap
555
+ var numberOfInstances = decodeInteger (contextCache , 'IAAI' , decoder );
556
+ if (numberOfInstances > 1 )
557
+ throw 'number of instances > 1 is not supported' ;
558
+ var symbolId = decodeIAID (contextCache , decoder , symbolCodeLength );
559
+ var rdx = decodeInteger (contextCache , 'IARDX' , decoder ); // 6.4.11.3
560
+ var rdy = decodeInteger (contextCache , 'IARDY' , decoder ); // 6.4.11.4
561
+ var symbol = symbolId < symbols .length ? symbols [symbolId ] :
562
+ newSymbols [symbolId - symbols .length ];
563
+ bitmap = decodeRefinement (currentWidth , currentHeight ,
564
+ refinementTemplateIndex , symbol , rdx , rdy , false , refinementAt ,
565
+ decoder , contextCache );
566
+ } else {
567
+ // 6.5.8.1 Direct-coded symbol bitmap
568
+ bitmap = decodeBitmap (false , currentWidth , currentHeight ,
569
+ templateIndex , false , null , at , decoder , contextCache );
570
+ }
452
571
newSymbols .push (bitmap );
453
572
}
454
573
}
@@ -473,12 +592,10 @@ var Jbig2Image = (function Jbig2ImageClosure() {
473
592
stripSize , inputSymbols , symbolCodeLength ,
474
593
transposed , dsOffset , referenceCorner ,
475
594
combinationOperator , huffmanTables ,
476
- refinementTemplate , refinementAt ,
595
+ refinementTemplateIndex , refinementAt ,
477
596
data , start , end ) {
478
597
if (huffman )
479
598
throw 'huffman is not supported' ;
480
- if (refinement )
481
- throw 'refinement is not supported' ;
482
599
483
600
// Prepare bitmap
484
601
var bitmap = [];
@@ -496,7 +613,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
496
613
497
614
if (transposed )
498
615
throw 'transposed!=0 is not supported' ;
499
- if (combinationOperator != 0 )
616
+ if (combinationOperator != 0 && combinationOperator != 2 )
500
617
throw 'combinationOperator==' + combinationOperator + ' is not supported' ;
501
618
502
619
var stripT = -decodeInteger (contextCache , 'IADT' , decoder ); // 6.4.6
@@ -512,20 +629,41 @@ var Jbig2Image = (function Jbig2ImageClosure() {
512
629
do {
513
630
var currentT = stripSize == 1 ? 0 :
514
631
decodeInteger (contextCache , 'IAIT' , decoder ); // 6.4.9
515
- var t = stripT + currentT ;
632
+ var t = stripSize * stripT + currentT ;
516
633
var symbolId = decodeIAID (contextCache , decoder , symbolCodeLength );
517
-
634
+ var applyRefinement = refinement &&
635
+ decodeInteger (contextCache , 'IARI' , decoder );
518
636
var symbolBitmap = inputSymbols [symbolId ];
519
637
var symbolWidth = symbolBitmap [0 ].length ;
520
638
var symbolHeight = symbolBitmap .length ;
639
+ if (applyRefinement ) {
640
+ var rdw = decodeInteger (contextCache , 'IARDW' , decoder ); // 6.4.11.1
641
+ var rdh = decodeInteger (contextCache , 'IARDH' , decoder ); // 6.4.11.2
642
+ var rdx = decodeInteger (contextCache , 'IARDX' , decoder ); // 6.4.11.3
643
+ var rdy = decodeInteger (contextCache , 'IARDY' , decoder ); // 6.4.11.4
644
+ symbolWidth += rdw ;
645
+ symbolHeight += rdh ;
646
+ symbolBitmap = decodeRefinement (symbolWidth , symbolHeight ,
647
+ refinementTemplateIndex , symbolBitmap , (rdw >> 1 ) + rdx ,
648
+ (rdh >> 1 ) + rdy , false , refinementAt ,
649
+ decoder , contextCache );
650
+ }
521
651
var offsetT = t - ((referenceCorner & 1 ) ? 0 : symbolHeight );
522
652
var offsetS = currentS - ((referenceCorner & 2 ) ? symbolWidth : 0 );
523
653
for (var t2 = 0 ; t2 < symbolHeight ; t2 ++) {
524
654
var row = bitmap [offsetT + t2 ];
525
655
if (!row ) continue ;
526
656
var symbolRow = symbolBitmap [t2 ];
527
- for (var s2 = 0 ; s2 < symbolWidth ; s2 ++)
528
- row [offsetS + s2 ] |= symbolRow [s2 ];
657
+ switch (combinationOperator ) {
658
+ case 0 : // OR
659
+ for (var s2 = 0 ; s2 < symbolWidth ; s2 ++)
660
+ row [offsetS + s2 ] |= symbolRow [s2 ];
661
+ break ;
662
+ case 2 : // XOR
663
+ for (var s2 = 0 ; s2 < symbolWidth ; s2 ++)
664
+ row [offsetS + s2 ] ^= symbolRow [s2 ];
665
+ break ;
666
+ }
529
667
}
530
668
531
669
currentS += symbolWidth - 1 ;
@@ -722,7 +860,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
722
860
});
723
861
position += 2 ;
724
862
}
725
- dictionary .refinementAt = at ;
863
+ textRegion .refinementAt = at ;
726
864
}
727
865
textRegion .numberOfSymbolInstances = readUint32 (data , position );
728
866
position += 4 ;
0 commit comments