@@ -168,14 +168,50 @@ var Jbig2Image = (function Jbig2ImageClosure() {
168
168
return ArithmeticDecoder ;
169
169
})();
170
170
171
+ // Utility data structures
172
+ function ContextCache () {}
173
+
174
+ ContextCache .prototype = {
175
+ getContexts : function (id ) {
176
+ if (id in this )
177
+ return this [id ];
178
+ return (this [id ] = []);
179
+ }
180
+ };
181
+
182
+ function DecodingContext (data , start , end ) {
183
+ this .data = data ;
184
+ this .start = start ;
185
+ this .end = end ;
186
+ }
187
+
188
+ DecodingContext .prototype = {
189
+ get decoder () {
190
+ var decoder = new ArithmeticDecoder (this .data , this .start , this .end );
191
+ Object .defineProperty (this , 'decoder' , {
192
+ value : decoder ,
193
+ writable : false ,
194
+ configurable : true ,
195
+ enumerable : true
196
+ });
197
+ return decoder ;
198
+ },
199
+ get contextCache () {
200
+ var cache = new ContextCache ();
201
+ Object .defineProperty (this , 'contextCache' , {
202
+ value : cache ,
203
+ writable : false ,
204
+ configurable : true ,
205
+ enumerable : true
206
+ });
207
+ return cache ;
208
+ }
209
+ };
210
+
171
211
// Annex A. Arithmetic Integer Decoding Procedure
172
212
// A.2 Procedure for decoding values
173
213
function decodeInteger (contextCache , procedure , decoder ) {
174
- var contexts ;
175
- if (procedure in contextCache )
176
- contexts = contextCache [procedure ];
177
- else
178
- contextCache [procedure ] = contexts = [];
214
+ var contexts = contextCache .getContexts (procedure );
179
215
180
216
var prev = 1 ;
181
217
var state = 1 , v = 0 , s ;
@@ -232,13 +268,10 @@ var Jbig2Image = (function Jbig2ImageClosure() {
232
268
v += offset ;
233
269
return !s ? v : v > 0 ? -v : null ;
234
270
}
271
+
235
272
// A.3 The IAID decoding procedure
236
273
function decodeIAID (contextCache , decoder , codeLength ) {
237
- var contexts ;
238
- if ('IAID' in contextCache )
239
- contexts = contextCache ['IAID' ];
240
- else
241
- contextCache ['IAID' ] = contexts = [];
274
+ var contexts = contextCache .getContexts ('IAID' );
242
275
243
276
var prev = 1 ;
244
277
for (var i = 0 ; i < codeLength ; i ++) {
@@ -254,41 +287,6 @@ var Jbig2Image = (function Jbig2ImageClosure() {
254
287
return prev - Math .pow (2 , codeLength );
255
288
}
256
289
257
- // Annex B. Huffman Table Decoding Procedure
258
- // B.5 Standard Huffman tables
259
- function TableB1 (reader ) {
260
- if (!reader .readBit ())
261
- return reader .readBits (4 ); // 0 + VAL
262
- if (!reader .readBit ())
263
- return reader .readBits (8 ) + 16 ; // 10 + (VAL - 16)
264
- if (!reader .readBit ())
265
- return reader .readBits (16 ) + 272 ; // 110 + (VAL - 272)
266
- if (!reader .readBit ())
267
- return reader .readBits (32 ) + 65808 ; // 1110 + (VAL - 65808)
268
- }
269
-
270
- function TableB2 (reader ) {
271
- if (!reader .readBit ())
272
- return 0 ; // 0
273
- if (!reader .readBit ())
274
- return 1 ; // 10
275
- if (!reader .readBit ())
276
- return 2 ; // 110
277
- if (!reader .readBit ())
278
- return reader .readBits (3 ) + 3 ; // 1110 + (VAL - 3)
279
- if (!reader .readBit ())
280
- return reader .readBits (6 ) + 11 ; // 11110 + (VAL - 11)
281
- if (!reader .readBit ())
282
- return reader .readBits (32 ) + 75 ; // 111110 + (VAL - 75)
283
- return null ; // OOB
284
- }
285
-
286
- function TableB3 (reader ) {}
287
-
288
- function TableB4 (reader ) {}
289
-
290
- function TableB5 (reader ) {}
291
-
292
290
// 7.3 Segment types
293
291
var SegmentTypes = [
294
292
'SymbolDictionary' , null , null , null , 'IntermediateTextRegion' , null ,
@@ -374,7 +372,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
374
372
375
373
// 6.2 Generic Region Decoding Procedure
376
374
function decodeBitmap (mmr , width , height , templateIndex , prediction , skip , at ,
377
- data , start , end ) {
375
+ decodingContext ) {
378
376
if (mmr )
379
377
throw 'MMR encoding is not supported' ;
380
378
@@ -390,23 +388,14 @@ var Jbig2Image = (function Jbig2ImageClosure() {
390
388
391
389
var pseudoPixelContext = ReusedContexts [templateIndex ];
392
390
var bitmap = [];
393
- var decoder , contexts , cx ;
394
- if (data instanceof ArithmeticDecoder ) {
395
- decoder = data ;
396
- var contextCache = start ;
397
- if ('GB' in contextCache )
398
- contexts = contextCache ['GB' ];
399
- else
400
- contextCache ['GB' ] = contexts = [];
401
- } else {
402
- decoder = new ArithmeticDecoder (data , start , end );
403
- contexts = [] ;
404
- }
391
+
392
+ var decoder = decodingContext .decoder ;
393
+ var contexts = decodingContext .contextCache .getContexts ('GB' );
405
394
406
395
var ltp = 0 ;
407
396
for (var i = 0 ; i < height ; i ++) {
408
397
if (prediction ) {
409
- cx = contexts [pseudoPixelContext ];
398
+ var cx = contexts [pseudoPixelContext ];
410
399
if (!cx )
411
400
contexts [pseudoPixelContext ] = cx = {index : 0 , mps : 0 };
412
401
var sltp = decoder .readBit (cx );
@@ -431,7 +420,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
431
420
else
432
421
contextLabel = (contextLabel << 1 ) | bitmap [i0 ][j0 ];
433
422
}
434
- cx = contexts [contextLabel ];
423
+ var cx = contexts [contextLabel ];
435
424
if (!cx )
436
425
contexts [contextLabel ] = cx = {index : 0 , mps : 0 };
437
426
var pixel = decoder .readBit (cx );
@@ -444,7 +433,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
444
433
// 6.3.2 Generic Refinement Region Decoding Procedure
445
434
function decodeRefinement (width , height , templateIndex , referenceBitmap ,
446
435
offsetX , offsetY , prediction , at ,
447
- data , start , end ) {
436
+ decodingContext ) {
448
437
var codingTemplate = RefinementTemplates [templateIndex ].coding ;
449
438
if (templateIndex == 0 )
450
439
codingTemplate = codingTemplate .concat ( [at [0 ]]);
@@ -470,23 +459,14 @@ var Jbig2Image = (function Jbig2ImageClosure() {
470
459
471
460
var pseudoPixelContext = RefinementReusedContexts [templateIndex ];
472
461
var bitmap = [];
473
- var decoder , contexts , cx ;
474
- if (data instanceof ArithmeticDecoder ) {
475
- decoder = data ;
476
- var contextCache = start ;
477
- if ('GR' in contextCache )
478
- contexts = contextCache ['GR' ];
479
- else
480
- contextCache ['GR' ] = contexts = [];
481
- } else {
482
- decoder = new ArithmeticDecoder (data , start , end );
483
- contexts = [] ;
484
- }
462
+
463
+ var decoder = decodingContext .decoder ;
464
+ var contexts = decodingContext .contextCache .getContexts ('GR' );
485
465
486
466
var ltp = 0 ;
487
467
for (var i = 0 ; i < height ; i ++) {
488
468
if (prediction ) {
489
- cx = contexts [pseudoPixelContext ];
469
+ var cx = contexts [pseudoPixelContext ];
490
470
if (!cx )
491
471
contexts [pseudoPixelContext ] = cx = {index : 0 , mps : 0 };
492
472
var sltp = decoder .readBit (cx );
@@ -514,7 +494,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
514
494
else
515
495
contextLabel = (contextLabel << 1 ) | referenceBitmap [i0 ][j0 ];
516
496
}
517
- cx = contexts [contextLabel ];
497
+ var cx = contexts [contextLabel ];
518
498
if (!cx )
519
499
contexts [contextLabel ] = cx = {index : 0 , mps : 0 };
520
500
var pixel = decoder .readBit (cx );
@@ -530,15 +510,17 @@ var Jbig2Image = (function Jbig2ImageClosure() {
530
510
numberOfNewSymbols , numberOfExportedSymbols ,
531
511
huffmanTables , templateIndex , at ,
532
512
refinementTemplateIndex , refinementAt ,
533
- data , start , end ) {
513
+ decodingContext ) {
534
514
if (huffman )
535
515
throw 'huffman is not supported' ;
536
516
537
517
var newSymbols = [];
538
518
var currentHeight = 0 ;
539
- var contextCache = {};
540
519
var symbolCodeLength = log2 (symbols .length + numberOfNewSymbols );
541
- var decoder = new ArithmeticDecoder (data , start , end );
520
+
521
+ var decoder = decodingContext .decoder ;
522
+ var contextCache = decodingContext .contextCache ;
523
+
542
524
while (newSymbols .length < numberOfNewSymbols ) {
543
525
var deltaHeight = decodeInteger (contextCache , 'IADH' , decoder ); // 6.5.6
544
526
currentHeight += deltaHeight ;
@@ -563,11 +545,11 @@ var Jbig2Image = (function Jbig2ImageClosure() {
563
545
newSymbols [symbolId - symbols .length ];
564
546
bitmap = decodeRefinement (currentWidth , currentHeight ,
565
547
refinementTemplateIndex , symbol , rdx , rdy , false , refinementAt ,
566
- decoder , contextCache );
548
+ decodingContext );
567
549
} else {
568
550
// 6.5.8.1 Direct-coded symbol bitmap
569
551
bitmap = decodeBitmap (false , currentWidth , currentHeight ,
570
- templateIndex , false , null , at , decoder , contextCache );
552
+ templateIndex , false , null , at , decodingContext );
571
553
}
572
554
newSymbols .push (bitmap );
573
555
}
@@ -594,7 +576,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
594
576
transposed , dsOffset , referenceCorner ,
595
577
combinationOperator , huffmanTables ,
596
578
refinementTemplateIndex , refinementAt ,
597
- data , start , end ) {
579
+ decodingContext ) {
598
580
if (huffman )
599
581
throw 'huffman is not supported' ;
600
582
@@ -609,8 +591,8 @@ var Jbig2Image = (function Jbig2ImageClosure() {
609
591
bitmap .push (row );
610
592
}
611
593
612
- var contextCache = {} ;
613
- var decoder = new ArithmeticDecoder ( data , start , end ) ;
594
+ var decoder = decodingContext . decoder ;
595
+ var contextCache = decodingContext . contextCache ;
614
596
615
597
if (transposed )
616
598
throw 'transposed!=0 is not supported' ;
@@ -647,7 +629,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
647
629
symbolBitmap = decodeRefinement (symbolWidth , symbolHeight ,
648
630
refinementTemplateIndex , symbolBitmap , (rdw >> 1 ) + rdx ,
649
631
(rdh >> 1 ) + rdy , false , refinementAt ,
650
- decoder , contextCache );
632
+ decodingContext );
651
633
}
652
634
var offsetT = t - ((referenceCorner & 1 ) ? 0 : symbolHeight );
653
635
var offsetS = currentS - ((referenceCorner & 2 ) ? symbolWidth : 0 );
@@ -1007,64 +989,58 @@ var Jbig2Image = (function Jbig2ImageClosure() {
1007
989
function SimpleSegmentVisitor_ImmediateGenericRegion (region , data ,
1008
990
start , end ) {
1009
991
var regionInfo = region .info ;
992
+ var decodingContext = new DecodingContext (data , start , end );
1010
993
var bitmap = decodeBitmap (region .mmr , regionInfo .width , regionInfo .height ,
1011
994
region .template , region .prediction , null ,
1012
- region .at , data , start , end );
995
+ region .at , decodingContext );
1013
996
this .drawBitmap (regionInfo , bitmap );
1014
997
},
1015
998
SymbolDictionary :
1016
999
function SimpleSegmentVisitor_SymbolDictionary (dictionary , currentSegment ,
1017
1000
referredSegments ,
1018
1001
data , start , end ) {
1019
- var symbols = this .symbols ;
1020
1002
var huffmanTables ;
1021
- if (dictionary .huffman ) {
1022
- huffmanTables = {};
1023
- huffmanTables .DeltaHeights = dictionary .huffmanDHSelector == 0 ?
1024
- TableB4 : dictionary .huffmanDHSelector == 1 ? TableB5 :
1025
- this .userTable ;
1026
- huffmanTables .DeltaWidths = dictionary .huffmanDHSelector == 0 ?
1027
- TableB2 : dictionary .huffmanDHSelector == 2 ? TableB3 :
1028
- this .userTable ;
1029
- huffmanTables .BitmapSize = dictionary .huffmanBitmapSizeSelector == 0 ?
1030
- TableB1 : this .userTable ;
1031
- huffmanTables .AggregationInstances =
1032
- dictionary .aggregationInstancesSelector == 0 ? TableB1 :
1033
- this .userTable ;
1034
- }
1003
+ if (dictionary .huffman )
1004
+ throw 'huffman is not supported' ;
1005
+
1035
1006
// Combines exported symbols from all referred segments
1007
+ var symbols = this .symbols ;
1008
+ if (!symbols )
1009
+ this .symbols = symbols = {};
1010
+
1036
1011
var inputSymbols = [];
1037
1012
for (var i = 0 ; i < referredSegments .length ; i ++)
1038
1013
inputSymbols = inputSymbols .concat (symbols [referredSegments [i ]]);
1039
1014
1040
- if (!symbols )
1041
- this .symbols = symbols = {};
1015
+ var decodingContext = new DecodingContext (data , start , end );
1042
1016
symbols [currentSegment ] = decodeSymbolDictionary (dictionary .huffman ,
1043
1017
dictionary .refinement , inputSymbols , dictionary .numberOfNewSymbols ,
1044
1018
dictionary .numberOfExportedSymbols , huffmanTables ,
1045
1019
dictionary .template , dictionary .at ,
1046
1020
dictionary .refinementTemplate , dictionary .refinementAt ,
1047
- data , start , end );
1021
+ decodingContext );
1048
1022
},
1049
1023
ImmediateTextRegion :
1050
1024
function SimpleSegmentVisitor_ImmediateTextRegion (region ,
1051
1025
referredSegments ,
1052
1026
data , start , end ) {
1053
1027
var regionInfo = region .info ;
1054
- var symbols = this .symbols ;
1055
1028
var huffmanTables ;
1029
+
1056
1030
// Combines exported symbols from all referred segments
1031
+ var symbols = this .symbols ;
1057
1032
var inputSymbols = [];
1058
1033
for (var i = 0 ; i < referredSegments .length ; i ++)
1059
1034
inputSymbols = inputSymbols .concat (symbols [referredSegments [i ]]);
1060
1035
var symbolCodeLength = log2 (inputSymbols .length );
1061
1036
1037
+ var decodingContext = new DecodingContext (data , start , end );
1062
1038
var bitmap = decodeTextRegion (region .huffman , region .refinement ,
1063
1039
regionInfo .width , regionInfo .height , region .defaultPixelValue ,
1064
1040
region .numberOfSymbolInstances , region .stripSize , inputSymbols ,
1065
1041
symbolCodeLength , region .transposed , region .dsOffset ,
1066
1042
region .referenceCorner , region .combinationOperator , huffmanTables ,
1067
- region .refinementTemplate , region .refinementAt , data , start , end );
1043
+ region .refinementTemplate , region .refinementAt , decodingContext );
1068
1044
this .drawBitmap (regionInfo , bitmap );
1069
1045
}
1070
1046
};
0 commit comments