0001: /*
0002: * $RCSfile: TIFFFaxDecoder.java,v $
0003: *
0004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Use is subject to license terms.
0007: *
0008: * $Revision: 1.3 $
0009: * $Date: 2005/11/14 22:44:48 $
0010: * $State: Exp $
0011: */
0012: package com.sun.media.jai.codecimpl;
0013:
0014: import java.awt.image.WritableRaster;
0015:
0016: class TIFFFaxDecoder {
0017:
0018: private int bitPointer, bytePointer;
0019: private byte[] data;
0020: private int w, h;
0021: private int fillOrder;
0022:
0023: // Data structures needed to store changing elements for the previous
0024: // and the current scanline
0025: private int changingElemSize = 0;
0026: private int prevChangingElems[];
0027: private int currChangingElems[];
0028:
0029: // Element at which to start search in getNextChangingElement
0030: private int lastChangingElement = 0;
0031:
0032: private int compression = 2;
0033:
0034: // Variables set by T4Options
0035: private int uncompressedMode = 0;
0036: private int fillBits = 0;
0037: private int oneD;
0038:
0039: static int table1[] = { 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN
0040: 0x01, // 1 bits are left in first byte
0041: 0x03, // 2 bits are left in first byte
0042: 0x07, // 3 bits are left in first byte
0043: 0x0f, // 4 bits are left in first byte
0044: 0x1f, // 5 bits are left in first byte
0045: 0x3f, // 6 bits are left in first byte
0046: 0x7f, // 7 bits are left in first byte
0047: 0xff // 8 bits are left in first byte
0048: };
0049:
0050: static int table2[] = { 0x00, // 0
0051: 0x80, // 1
0052: 0xc0, // 2
0053: 0xe0, // 3
0054: 0xf0, // 4
0055: 0xf8, // 5
0056: 0xfc, // 6
0057: 0xfe, // 7
0058: 0xff // 8
0059: };
0060:
0061: // Table to be used when fillOrder = 2, for flipping bytes.
0062: static byte flipTable[] = { 0, -128, 64, -64, 32, -96, 96, -32, 16,
0063: -112, 80, -48, 48, -80, 112, -16, 8, -120, 72, -56, 40,
0064: -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4,
0065: -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52,
0066: -76, 116, -12, 12, -116, 76, -52, 44, -84, 108, -20, 28,
0067: -100, 92, -36, 60, -68, 124, -4, 2, -126, 66, -62, 34, -94,
0068: 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10, -118,
0069: 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70,
0070: 122, -6, 6, -122, 70, -58, 38, -90, 102, -26, 22, -106, 86,
0071: -42, 54, -74, 118, -10, 14, -114, 78, -50, 46, -82, 110,
0072: -18, 30, -98, 94, -34, 62, -66, 126, -2, 1, -127, 65, -63,
0073: 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9,
0074: -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57,
0075: -71, 121, -7, 5, -123, 69, -59, 37, -91, 101, -27, 21,
0076: -107, 85, -43, 53, -75, 117, -11, 13, -115, 77, -51, 45,
0077: -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3, -125,
0078: 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115,
0079: -13, 11, -117, 75, -53, 43, -85, 107, -21, 27, -101, 91,
0080: -37, 59, -69, 123, -5, 7, -121, 71, -57, 39, -89, 103, -25,
0081: 23, -105, 87, -41, 55, -73, 119, -9, 15, -113, 79, -49, 47,
0082: -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1, };
0083:
0084: // The main 10 bit white runs lookup table
0085: static short white[] = {
0086: // 0 - 7
0087: 6430, 6400, 6400, 6400,
0088: 3225,
0089: 3225,
0090: 3225,
0091: 3225,
0092: // 8 - 15
0093: 944, 944, 944, 944,
0094: 976,
0095: 976,
0096: 976,
0097: 976,
0098: // 16 - 23
0099: 1456, 1456, 1456, 1456,
0100: 1488,
0101: 1488,
0102: 1488,
0103: 1488,
0104: // 24 - 31
0105: 718, 718, 718, 718,
0106: 718,
0107: 718,
0108: 718,
0109: 718,
0110: // 32 - 39
0111: 750, 750, 750, 750,
0112: 750,
0113: 750,
0114: 750,
0115: 750,
0116: // 40 - 47
0117: 1520, 1520, 1520, 1520,
0118: 1552,
0119: 1552,
0120: 1552,
0121: 1552,
0122: // 48 - 55
0123: 428, 428, 428, 428,
0124: 428,
0125: 428,
0126: 428,
0127: 428,
0128: // 56 - 63
0129: 428, 428, 428, 428,
0130: 428,
0131: 428,
0132: 428,
0133: 428,
0134: // 64 - 71
0135: 654, 654, 654, 654,
0136: 654,
0137: 654,
0138: 654,
0139: 654,
0140: // 72 - 79
0141: 1072, 1072, 1072, 1072,
0142: 1104,
0143: 1104,
0144: 1104,
0145: 1104,
0146: // 80 - 87
0147: 1136, 1136, 1136, 1136,
0148: 1168,
0149: 1168,
0150: 1168,
0151: 1168,
0152: // 88 - 95
0153: 1200, 1200, 1200, 1200,
0154: 1232,
0155: 1232,
0156: 1232,
0157: 1232,
0158: // 96 - 103
0159: 622, 622, 622, 622,
0160: 622,
0161: 622,
0162: 622,
0163: 622,
0164: // 104 - 111
0165: 1008, 1008, 1008, 1008,
0166: 1040,
0167: 1040,
0168: 1040,
0169: 1040,
0170: // 112 - 119
0171: 44, 44, 44, 44,
0172: 44,
0173: 44,
0174: 44,
0175: 44,
0176: // 120 - 127
0177: 44, 44, 44, 44,
0178: 44,
0179: 44,
0180: 44,
0181: 44,
0182: // 128 - 135
0183: 396, 396, 396, 396,
0184: 396,
0185: 396,
0186: 396,
0187: 396,
0188: // 136 - 143
0189: 396, 396, 396, 396,
0190: 396,
0191: 396,
0192: 396,
0193: 396,
0194: // 144 - 151
0195: 1712, 1712, 1712, 1712,
0196: 1744,
0197: 1744,
0198: 1744,
0199: 1744,
0200: // 152 - 159
0201: 846, 846, 846, 846,
0202: 846,
0203: 846,
0204: 846,
0205: 846,
0206: // 160 - 167
0207: 1264, 1264, 1264, 1264,
0208: 1296,
0209: 1296,
0210: 1296,
0211: 1296,
0212: // 168 - 175
0213: 1328, 1328, 1328, 1328,
0214: 1360,
0215: 1360,
0216: 1360,
0217: 1360,
0218: // 176 - 183
0219: 1392, 1392, 1392, 1392,
0220: 1424,
0221: 1424,
0222: 1424,
0223: 1424,
0224: // 184 - 191
0225: 686, 686, 686, 686,
0226: 686,
0227: 686,
0228: 686,
0229: 686,
0230: // 192 - 199
0231: 910, 910, 910, 910,
0232: 910,
0233: 910,
0234: 910,
0235: 910,
0236: // 200 - 207
0237: 1968, 1968, 1968, 1968,
0238: 2000,
0239: 2000,
0240: 2000,
0241: 2000,
0242: // 208 - 215
0243: 2032, 2032, 2032, 2032,
0244: 16,
0245: 16,
0246: 16,
0247: 16,
0248: // 216 - 223
0249: 10257, 10257, 10257, 10257,
0250: 12305,
0251: 12305,
0252: 12305,
0253: 12305,
0254: // 224 - 231
0255: 330, 330, 330, 330,
0256: 330,
0257: 330,
0258: 330,
0259: 330,
0260: // 232 - 239
0261: 330, 330, 330, 330,
0262: 330,
0263: 330,
0264: 330,
0265: 330,
0266: // 240 - 247
0267: 330, 330, 330, 330,
0268: 330,
0269: 330,
0270: 330,
0271: 330,
0272: // 248 - 255
0273: 330, 330, 330, 330,
0274: 330,
0275: 330,
0276: 330,
0277: 330,
0278: // 256 - 263
0279: 362, 362, 362, 362,
0280: 362,
0281: 362,
0282: 362,
0283: 362,
0284: // 264 - 271
0285: 362, 362, 362, 362,
0286: 362,
0287: 362,
0288: 362,
0289: 362,
0290: // 272 - 279
0291: 362, 362, 362, 362,
0292: 362,
0293: 362,
0294: 362,
0295: 362,
0296: // 280 - 287
0297: 362, 362, 362, 362,
0298: 362,
0299: 362,
0300: 362,
0301: 362,
0302: // 288 - 295
0303: 878, 878, 878, 878,
0304: 878,
0305: 878,
0306: 878,
0307: 878,
0308: // 296 - 303
0309: 1904, 1904, 1904, 1904,
0310: 1936,
0311: 1936,
0312: 1936,
0313: 1936,
0314: // 304 - 311
0315: -18413, -18413, -16365, -16365,
0316: -14317,
0317: -14317,
0318: -10221,
0319: -10221,
0320: // 312 - 319
0321: 590, 590, 590, 590, 590,
0322: 590,
0323: 590,
0324: 590,
0325: // 320 - 327
0326: 782, 782, 782, 782, 782,
0327: 782,
0328: 782,
0329: 782,
0330: // 328 - 335
0331: 1584, 1584, 1584, 1584, 1616,
0332: 1616,
0333: 1616,
0334: 1616,
0335: // 336 - 343
0336: 1648, 1648, 1648, 1648, 1680,
0337: 1680,
0338: 1680,
0339: 1680,
0340: // 344 - 351
0341: 814, 814, 814, 814, 814,
0342: 814,
0343: 814,
0344: 814,
0345: // 352 - 359
0346: 1776, 1776, 1776, 1776, 1808,
0347: 1808,
0348: 1808,
0349: 1808,
0350: // 360 - 367
0351: 1840, 1840, 1840, 1840, 1872,
0352: 1872,
0353: 1872,
0354: 1872,
0355: // 368 - 375
0356: 6157, 6157, 6157, 6157, 6157,
0357: 6157,
0358: 6157,
0359: 6157,
0360: // 376 - 383
0361: 6157, 6157, 6157, 6157, 6157,
0362: 6157,
0363: 6157,
0364: 6157,
0365: // 384 - 391
0366: -12275, -12275, -12275, -12275, -12275,
0367: -12275,
0368: -12275,
0369: -12275,
0370: // 392 - 399
0371: -12275, -12275, -12275, -12275, -12275, -12275,
0372: -12275,
0373: -12275,
0374: // 400 - 407
0375: 14353, 14353, 14353, 14353, 16401, 16401, 16401,
0376: 16401,
0377: // 408 - 415
0378: 22547, 22547, 24595, 24595, 20497, 20497, 20497,
0379: 20497,
0380: // 416 - 423
0381: 18449, 18449, 18449, 18449, 26643, 26643, 28691,
0382: 28691,
0383: // 424 - 431
0384: 30739, 30739, -32749, -32749, -30701, -30701, -28653,
0385: -28653,
0386: // 432 - 439
0387: -26605, -26605, -24557, -24557, -22509, -22509, -20461,
0388: -20461,
0389: // 440 - 447
0390: 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207,
0391: // 448 - 455
0392: 72, 72, 72, 72, 72, 72, 72, 72,
0393: // 456 - 463
0394: 72, 72, 72, 72, 72, 72, 72, 72,
0395: // 464 - 471
0396: 72, 72, 72, 72, 72, 72, 72, 72,
0397: // 472 - 479
0398: 72, 72, 72, 72, 72, 72, 72, 72,
0399: // 480 - 487
0400: 72, 72, 72, 72, 72, 72, 72, 72,
0401: // 488 - 495
0402: 72, 72, 72, 72, 72, 72, 72, 72,
0403: // 496 - 503
0404: 72, 72, 72, 72, 72, 72, 72, 72,
0405: // 504 - 511
0406: 72, 72, 72, 72, 72, 72, 72, 72,
0407: // 512 - 519
0408: 104, 104, 104, 104, 104, 104, 104, 104,
0409: // 520 - 527
0410: 104, 104, 104, 104, 104, 104, 104, 104,
0411: // 528 - 535
0412: 104, 104, 104, 104, 104, 104, 104, 104,
0413: // 536 - 543
0414: 104, 104, 104, 104, 104, 104, 104, 104,
0415: // 544 - 551
0416: 104, 104, 104, 104, 104, 104, 104, 104,
0417: // 552 - 559
0418: 104, 104, 104, 104, 104, 104, 104, 104,
0419: // 560 - 567
0420: 104, 104, 104, 104, 104, 104, 104, 104,
0421: // 568 - 575
0422: 104, 104, 104, 104, 104, 104, 104, 104,
0423: // 576 - 583
0424: 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
0425: // 584 - 591
0426: 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
0427: // 592 - 599
0428: 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
0429: // 600 - 607
0430: 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
0431: // 608 - 615
0432: 266, 266, 266, 266, 266, 266, 266, 266,
0433: // 616 - 623
0434: 266, 266, 266, 266, 266, 266, 266, 266,
0435: // 624 - 631
0436: 266, 266, 266, 266, 266, 266, 266, 266,
0437: // 632 - 639
0438: 266, 266, 266, 266, 266, 266, 266, 266,
0439: // 640 - 647
0440: 298, 298, 298, 298, 298, 298, 298, 298,
0441: // 648 - 655
0442: 298, 298, 298, 298, 298, 298, 298, 298,
0443: // 656 - 663
0444: 298, 298, 298, 298, 298, 298, 298, 298,
0445: // 664 - 671
0446: 298, 298, 298, 298, 298, 298, 298, 298,
0447: // 672 - 679
0448: 524, 524, 524, 524, 524, 524, 524, 524,
0449: // 680 - 687
0450: 524, 524, 524, 524, 524, 524, 524, 524,
0451: // 688 - 695
0452: 556, 556, 556, 556, 556, 556, 556, 556,
0453: // 696 - 703
0454: 556, 556, 556, 556, 556, 556, 556, 556,
0455: // 704 - 711
0456: 136, 136, 136, 136, 136, 136, 136, 136,
0457: // 712 - 719
0458: 136, 136, 136, 136, 136, 136, 136, 136,
0459: // 720 - 727
0460: 136, 136, 136, 136, 136, 136, 136, 136,
0461: // 728 - 735
0462: 136, 136, 136, 136, 136, 136, 136, 136,
0463: // 736 - 743
0464: 136, 136, 136, 136, 136, 136, 136, 136,
0465: // 744 - 751
0466: 136, 136, 136, 136, 136, 136, 136, 136,
0467: // 752 - 759
0468: 136, 136, 136, 136, 136, 136, 136, 136,
0469: // 760 - 767
0470: 136, 136, 136, 136, 136, 136, 136, 136,
0471: // 768 - 775
0472: 168, 168, 168, 168, 168, 168, 168, 168,
0473: // 776 - 783
0474: 168, 168, 168, 168, 168, 168, 168, 168,
0475: // 784 - 791
0476: 168, 168, 168, 168, 168, 168, 168, 168,
0477: // 792 - 799
0478: 168, 168, 168, 168, 168, 168, 168, 168,
0479: // 800 - 807
0480: 168, 168, 168, 168, 168, 168, 168, 168,
0481: // 808 - 815
0482: 168, 168, 168, 168, 168, 168, 168, 168,
0483: // 816 - 823
0484: 168, 168, 168, 168, 168, 168, 168, 168,
0485: // 824 - 831
0486: 168, 168, 168, 168, 168, 168, 168, 168,
0487: // 832 - 839
0488: 460, 460, 460, 460, 460, 460, 460, 460,
0489: // 840 - 847
0490: 460, 460, 460, 460, 460, 460, 460, 460,
0491: // 848 - 855
0492: 492, 492, 492, 492, 492, 492, 492, 492,
0493: // 856 - 863
0494: 492, 492, 492, 492, 492, 492, 492, 492,
0495: // 864 - 871
0496: 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
0497: // 872 - 879
0498: 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
0499: // 880 - 887
0500: 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
0501: // 888 - 895
0502: 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
0503: // 896 - 903
0504: 200, 200, 200, 200, 200, 200, 200, 200,
0505: // 904 - 911
0506: 200, 200, 200, 200, 200, 200, 200, 200,
0507: // 912 - 919
0508: 200, 200, 200, 200, 200, 200, 200, 200,
0509: // 920 - 927
0510: 200, 200, 200, 200, 200, 200, 200, 200,
0511: // 928 - 935
0512: 200, 200, 200, 200, 200, 200, 200, 200,
0513: // 936 - 943
0514: 200, 200, 200, 200, 200, 200, 200, 200,
0515: // 944 - 951
0516: 200, 200, 200, 200, 200, 200, 200, 200,
0517: // 952 - 959
0518: 200, 200, 200, 200, 200, 200, 200, 200,
0519: // 960 - 967
0520: 232, 232, 232, 232, 232, 232, 232, 232,
0521: // 968 - 975
0522: 232, 232, 232, 232, 232, 232, 232, 232,
0523: // 976 - 983
0524: 232, 232, 232, 232, 232, 232, 232, 232,
0525: // 984 - 991
0526: 232, 232, 232, 232, 232, 232, 232, 232,
0527: // 992 - 999
0528: 232, 232, 232, 232, 232, 232, 232, 232,
0529: // 1000 - 1007
0530: 232, 232, 232, 232, 232, 232, 232, 232,
0531: // 1008 - 1015
0532: 232, 232, 232, 232, 232, 232, 232, 232,
0533: // 1016 - 1023
0534: 232, 232, 232, 232, 232, 232, 232, 232, };
0535:
0536: // Additional make up codes for both White and Black runs
0537: static short additionalMakeup[] = { 28679, 28679, 31752,
0538: (short) 32777, (short) 33801, (short) 34825, (short) 35849,
0539: (short) 36873, (short) 29703, (short) 29703, (short) 30727,
0540: (short) 30727, (short) 37897, (short) 38921, (short) 39945,
0541: (short) 40969 };
0542:
0543: // Initial black run look up table, uses the first 4 bits of a code
0544: static short initBlack[] = {
0545: // 0 - 7
0546: 3226, 6412, 200, 168, 38, 38, 134, 134,
0547: // 8 - 15
0548: 100, 100, 100, 100, 68, 68, 68, 68 };
0549:
0550: //
0551: static short twoBitBlack[] = { 292, 260, 226, 226 }; // 0 - 3
0552:
0553: // Main black run table, using the last 9 bits of possible 13 bit code
0554: static short black[] = {
0555: // 0 - 7
0556: 62, 62, 30, 30, 0, 0, 0, 0,
0557: // 8 - 15
0558: 0, 0, 0, 0, 0, 0, 0, 0,
0559: // 16 - 23
0560: 0, 0, 0, 0, 0, 0, 0, 0,
0561: // 24 - 31
0562: 0, 0, 0, 0, 0, 0, 0, 0,
0563: // 32 - 39
0564: 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
0565: // 40 - 47
0566: 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
0567: // 48 - 55
0568: 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
0569: // 56 - 63
0570: 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
0571: // 64 - 71
0572: 588, 588, 588, 588, 588, 588, 588, 588,
0573: // 72 - 79
0574: 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,
0575: // 80 - 87
0576: 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904,
0577: // 88 - 95
0578: 1936, 1936, -16365, -14317, 782, 782, 782, 782,
0579: // 96 - 103
0580: 814, 814, 814, 814, -12269, -10221, 10257, 10257,
0581: // 104 - 111
0582: 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712,
0583: // 112 - 119
0584: 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,
0585: // 120 - 127
0586: 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061,
0587: // 128 - 135
0588: 424, 424, 424, 424, 424, 424, 424, 424,
0589: // 136 - 143
0590: 424, 424, 424, 424, 424, 424, 424, 424,
0591: // 144 - 151
0592: 424, 424, 424, 424, 424, 424, 424, 424,
0593: // 152 - 159
0594: 424, 424, 424, 424, 424, 424, 424, 424,
0595: // 160 - 167
0596: 750, 750, 750, 750, 1616, 1616, 1648, 1648,
0597: // 168 - 175
0598: 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520,
0599: // 176 - 183
0600: 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209,
0601: // 184 - 191
0602: 524, 524, 524, 524, 524, 524, 524, 524,
0603: // 192 - 199
0604: 556, 556, 556, 556, 556, 556, 556, 556,
0605: // 200 - 207
0606: 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032,
0607: // 208 - 215
0608: 976, 976, 1008, 1008, 1040, 1040, 1072, 1072,
0609: // 216 - 223
0610: 1296, 1296, 1328, 1328, 718, 718, 718, 718,
0611: // 224 - 231
0612: 456, 456, 456, 456, 456, 456, 456, 456,
0613: // 232 - 239
0614: 456, 456, 456, 456, 456, 456, 456, 456,
0615: // 240 - 247
0616: 456, 456, 456, 456, 456, 456, 456, 456,
0617: // 248 - 255
0618: 456, 456, 456, 456, 456, 456, 456, 456,
0619: // 256 - 263
0620: 326, 326, 326, 326, 326, 326, 326, 326,
0621: // 264 - 271
0622: 326, 326, 326, 326, 326, 326, 326, 326,
0623: // 272 - 279
0624: 326, 326, 326, 326, 326, 326, 326, 326,
0625: // 280 - 287
0626: 326, 326, 326, 326, 326, 326, 326, 326,
0627: // 288 - 295
0628: 326, 326, 326, 326, 326, 326, 326, 326,
0629: // 296 - 303
0630: 326, 326, 326, 326, 326, 326, 326, 326,
0631: // 304 - 311
0632: 326, 326, 326, 326, 326, 326, 326, 326,
0633: // 312 - 319
0634: 326, 326, 326, 326, 326, 326, 326, 326,
0635: // 320 - 327
0636: 358, 358, 358, 358, 358, 358, 358, 358,
0637: // 328 - 335
0638: 358, 358, 358, 358, 358, 358, 358, 358,
0639: // 336 - 343
0640: 358, 358, 358, 358, 358, 358, 358, 358,
0641: // 344 - 351
0642: 358, 358, 358, 358, 358, 358, 358, 358,
0643: // 352 - 359
0644: 358, 358, 358, 358, 358, 358, 358, 358,
0645: // 360 - 367
0646: 358, 358, 358, 358, 358, 358, 358, 358,
0647: // 368 - 375
0648: 358, 358, 358, 358, 358, 358, 358, 358,
0649: // 376 - 383
0650: 358, 358, 358, 358, 358, 358, 358, 358,
0651: // 384 - 391
0652: 490, 490, 490, 490, 490, 490, 490, 490,
0653: // 392 - 399
0654: 490, 490, 490, 490, 490, 490, 490, 490,
0655: // 400 - 407
0656: 4113, 4113, 6161, 6161, 848, 848, 880, 880,
0657: // 408 - 415
0658: 912, 912, 944, 944, 622, 622, 622, 622,
0659: // 416 - 423
0660: 654, 654, 654, 654, 1104, 1104, 1136, 1136,
0661: // 424 - 431
0662: 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264,
0663: // 432 - 439
0664: 686, 686, 686, 686, 1360, 1360, 1392, 1392,
0665: // 440 - 447
0666: 12, 12, 12, 12, 12, 12, 12, 12,
0667: // 448 - 455
0668: 390, 390, 390, 390, 390, 390, 390, 390,
0669: // 456 - 463
0670: 390, 390, 390, 390, 390, 390, 390, 390,
0671: // 464 - 471
0672: 390, 390, 390, 390, 390, 390, 390, 390,
0673: // 472 - 479
0674: 390, 390, 390, 390, 390, 390, 390, 390,
0675: // 480 - 487
0676: 390, 390, 390, 390, 390, 390, 390, 390,
0677: // 488 - 495
0678: 390, 390, 390, 390, 390, 390, 390, 390,
0679: // 496 - 503
0680: 390, 390, 390, 390, 390, 390, 390, 390,
0681: // 504 - 511
0682: 390, 390, 390, 390, 390, 390, 390, 390, };
0683:
0684: static byte twoDCodes[] = {
0685: // 0 - 7
0686: 80, 88, 23, 71, 30, 30, 62, 62,
0687: // 8 - 15
0688: 4, 4, 4, 4, 4, 4, 4, 4,
0689: // 16 - 23
0690: 11, 11, 11, 11, 11, 11, 11, 11,
0691: // 24 - 31
0692: 11, 11, 11, 11, 11, 11, 11, 11,
0693: // 32 - 39
0694: 35, 35, 35, 35, 35, 35, 35, 35,
0695: // 40 - 47
0696: 35, 35, 35, 35, 35, 35, 35, 35,
0697: // 48 - 55
0698: 51, 51, 51, 51, 51, 51, 51, 51,
0699: // 56 - 63
0700: 51, 51, 51, 51, 51, 51, 51, 51,
0701: // 64 - 71
0702: 41, 41, 41, 41, 41, 41, 41, 41,
0703: // 72 - 79
0704: 41, 41, 41, 41, 41, 41, 41, 41,
0705: // 80 - 87
0706: 41, 41, 41, 41, 41, 41, 41, 41,
0707: // 88 - 95
0708: 41, 41, 41, 41, 41, 41, 41, 41,
0709: // 96 - 103
0710: 41, 41, 41, 41, 41, 41, 41, 41,
0711: // 104 - 111
0712: 41, 41, 41, 41, 41, 41, 41, 41,
0713: // 112 - 119
0714: 41, 41, 41, 41, 41, 41, 41, 41,
0715: // 120 - 127
0716: 41, 41, 41, 41, 41, 41, 41, 41, };
0717:
0718: /**
0719: * @param fillOrder The fill order of the compressed data bytes.
0720: * @param compData Array containing compressed data.
0721: * @param w
0722: * @param h
0723: */
0724: public TIFFFaxDecoder(int fillOrder, int w, int h) {
0725: this .fillOrder = fillOrder;
0726: this .w = w;
0727: this .h = h;
0728:
0729: this .bitPointer = 0;
0730: this .bytePointer = 0;
0731: this .prevChangingElems = new int[w + 1];
0732: this .currChangingElems = new int[w + 1];
0733: }
0734:
0735: // One-dimensional decoding methods
0736:
0737: public void decode1D(byte[] buffer, byte[] compData, int startX,
0738: int height) {
0739: this .data = compData;
0740:
0741: int lineOffset = 0;
0742: int scanlineStride = (w + 7) / 8;
0743:
0744: bitPointer = 0;
0745: bytePointer = 0;
0746:
0747: for (int i = 0; i < height; i++) {
0748: decodeNextScanline(buffer, lineOffset, startX);
0749: lineOffset += scanlineStride;
0750: }
0751: }
0752:
0753: public void decodeNextScanline(byte[] buffer, int lineOffset,
0754: int bitOffset) {
0755: int bits = 0, code = 0, isT = 0;
0756: int current, entry, twoBits;
0757: boolean isWhite = true;
0758: int dstEnd = 0;
0759:
0760: // Initialize starting of the changing elements array
0761: changingElemSize = 0;
0762:
0763: // While scanline not complete
0764: while (bitOffset < w) {
0765: while (isWhite) {
0766: // White run
0767: current = nextNBits(10);
0768: entry = white[current];
0769:
0770: // Get the 3 fields from the entry
0771: isT = entry & 0x0001;
0772: bits = (entry >>> 1) & 0x0f;
0773:
0774: if (bits == 12) { // Additional Make up code
0775: // Get the next 2 bits
0776: twoBits = nextLesserThan8Bits(2);
0777: // Consolidate the 2 new bits and last 2 bits into 4 bits
0778: current = ((current << 2) & 0x000c) | twoBits;
0779: entry = additionalMakeup[current];
0780: bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
0781: code = (entry >>> 4) & 0x0fff; // 12 bits
0782: bitOffset += code; // Skip white run
0783:
0784: updatePointer(4 - bits);
0785: } else if (bits == 0) { // ERROR
0786: throw new RuntimeException(JaiI18N
0787: .getString("TIFFFaxDecoder0"));
0788: } else if (bits == 15) { // EOL
0789: //throw new Error(JaiI18N.getString("TIFFFaxDecoder1"));
0790: //
0791: // Instead of throwing an error, assume that the EOL
0792: // was premature. Rewind the pointers to the start
0793: // of the EOL and return, thereby stopping decoding
0794: // this line.
0795: //
0796: updatePointer(12);
0797: return;
0798: } else {
0799: // 11 bits - 0000 0111 1111 1111 = 0x07ff
0800: code = (entry >>> 5) & 0x07ff;
0801: bitOffset += code;
0802:
0803: updatePointer(10 - bits);
0804: if (isT == 0) {
0805: isWhite = false;
0806: currChangingElems[changingElemSize++] = bitOffset;
0807: }
0808: }
0809: }
0810:
0811: // Check whether this run completed one width, if so
0812: // advance to next byte boundary for compression = 2.
0813: if (bitOffset == w) {
0814: if (compression == 2) {
0815: advancePointer();
0816: }
0817: break;
0818: }
0819:
0820: while (isWhite == false) {
0821: // Black run
0822: current = nextLesserThan8Bits(4);
0823: entry = initBlack[current];
0824:
0825: // Get the 3 fields from the entry
0826: isT = entry & 0x0001;
0827: bits = (entry >>> 1) & 0x000f;
0828: code = (entry >>> 5) & 0x07ff;
0829:
0830: if (code == 100) {
0831: current = nextNBits(9);
0832: entry = black[current];
0833:
0834: // Get the 3 fields from the entry
0835: isT = entry & 0x0001;
0836: bits = (entry >>> 1) & 0x000f;
0837: code = (entry >>> 5) & 0x07ff;
0838:
0839: if (bits == 12) {
0840: // Additional makeup codes
0841: updatePointer(5);
0842: current = nextLesserThan8Bits(4);
0843: entry = additionalMakeup[current];
0844: bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
0845: code = (entry >>> 4) & 0x0fff; // 12 bits
0846:
0847: setToBlack(buffer, lineOffset, bitOffset, code);
0848: bitOffset += code;
0849:
0850: updatePointer(4 - bits);
0851: } else if (bits == 15) {
0852: // EOL code
0853: //throw new Error(JaiI18N.getString("TIFFFaxDecoder2"));
0854: //
0855: // Instead of throwing an error, assume that the EOL
0856: // was premature. Rewind the pointers to the start
0857: // of the EOL and return, thereby stopping decoding
0858: // this line.
0859: //
0860: updatePointer(12);
0861: return;
0862: } else {
0863: setToBlack(buffer, lineOffset, bitOffset, code);
0864: bitOffset += code;
0865:
0866: updatePointer(9 - bits);
0867: if (isT == 0) {
0868: isWhite = true;
0869: currChangingElems[changingElemSize++] = bitOffset;
0870: }
0871: }
0872: } else if (code == 200) {
0873: // Is a Terminating code
0874: current = nextLesserThan8Bits(2);
0875: entry = twoBitBlack[current];
0876: code = (entry >>> 5) & 0x07ff;
0877: bits = (entry >>> 1) & 0x0f;
0878:
0879: setToBlack(buffer, lineOffset, bitOffset, code);
0880: bitOffset += code;
0881:
0882: updatePointer(2 - bits);
0883: isWhite = true;
0884: currChangingElems[changingElemSize++] = bitOffset;
0885: } else {
0886: // Is a Terminating code
0887: setToBlack(buffer, lineOffset, bitOffset, code);
0888: bitOffset += code;
0889:
0890: updatePointer(4 - bits);
0891: isWhite = true;
0892: currChangingElems[changingElemSize++] = bitOffset;
0893: }
0894: }
0895:
0896: // Check whether this run completed one width
0897: if (bitOffset == w) {
0898: if (compression == 2) {
0899: advancePointer();
0900: }
0901: break;
0902: }
0903: }
0904:
0905: currChangingElems[changingElemSize++] = bitOffset;
0906: }
0907:
0908: // Two-dimensional decoding methods
0909:
0910: public void decode2D(byte[] buffer, byte compData[], int startX,
0911: int height, long tiffT4Options) {
0912: this .data = compData;
0913: compression = 3;
0914:
0915: bitPointer = 0;
0916: bytePointer = 0;
0917:
0918: int scanlineStride = (w + 7) / 8;
0919:
0920: int a0, a1, b1, b2;
0921: int[] b = new int[2];
0922: int entry, code, bits, color;
0923: boolean isWhite;
0924: int currIndex = 0;
0925: int temp[];
0926:
0927: // fillBits - dealt with this in readEOL
0928: // 1D/2D encoding - dealt with this in readEOL
0929:
0930: // uncompressedMode - haven't dealt with this yet.
0931: // TODO: Deal with uncompressedMode, aastha 03/03/1999
0932:
0933: oneD = (int) (tiffT4Options & 0x01);
0934: uncompressedMode = (int) ((tiffT4Options & 0x02) >> 1);
0935: fillBits = (int) ((tiffT4Options & 0x04) >> 2);
0936:
0937: // The data must start with an EOL code
0938: if (readEOL(true) != 1) {
0939: throw new RuntimeException(JaiI18N
0940: .getString("TIFFFaxDecoder3"));
0941: }
0942:
0943: int lineOffset = 0;
0944: int bitOffset;
0945:
0946: // Then the 1D encoded scanline data will occur, changing elements
0947: // array gets set.
0948: decodeNextScanline(buffer, lineOffset, startX);
0949: lineOffset += scanlineStride;
0950:
0951: for (int lines = 1; lines < height; lines++) {
0952:
0953: // Every line must begin with an EOL followed by a bit which
0954: // indicates whether the following scanline is 1D or 2D encoded.
0955: if (readEOL(false) == 0) {
0956: // 2D encoded scanline follows
0957:
0958: // Initialize previous scanlines changing elements, and
0959: // initialize current scanline's changing elements array
0960: temp = prevChangingElems;
0961: prevChangingElems = currChangingElems;
0962: currChangingElems = temp;
0963: currIndex = 0;
0964:
0965: // a0 has to be set just before the start of this scanline.
0966: a0 = -1;
0967: isWhite = true;
0968: bitOffset = startX;
0969:
0970: lastChangingElement = 0;
0971:
0972: while (bitOffset < w) {
0973: // Get the next changing element
0974: getNextChangingElement(a0, isWhite, b);
0975:
0976: b1 = b[0];
0977: b2 = b[1];
0978:
0979: // Get the next seven bits
0980: entry = nextLesserThan8Bits(7);
0981:
0982: // Run these through the 2DCodes table
0983: entry = (int) (twoDCodes[entry] & 0xff);
0984:
0985: // Get the code and the number of bits used up
0986: code = (entry & 0x78) >>> 3;
0987: bits = entry & 0x07;
0988:
0989: if (code == 0) {
0990: if (!isWhite) {
0991: setToBlack(buffer, lineOffset, bitOffset,
0992: b2 - bitOffset);
0993: }
0994: bitOffset = a0 = b2;
0995:
0996: // Set pointer to consume the correct number of bits.
0997: updatePointer(7 - bits);
0998: } else if (code == 1) {
0999: // Horizontal
1000: updatePointer(7 - bits);
1001:
1002: // identify the next 2 codes.
1003: int number;
1004: if (isWhite) {
1005: number = decodeWhiteCodeWord();
1006: bitOffset += number;
1007: currChangingElems[currIndex++] = bitOffset;
1008:
1009: number = decodeBlackCodeWord();
1010: setToBlack(buffer, lineOffset, bitOffset,
1011: number);
1012: bitOffset += number;
1013: currChangingElems[currIndex++] = bitOffset;
1014: } else {
1015: number = decodeBlackCodeWord();
1016: setToBlack(buffer, lineOffset, bitOffset,
1017: number);
1018: bitOffset += number;
1019: currChangingElems[currIndex++] = bitOffset;
1020:
1021: number = decodeWhiteCodeWord();
1022: bitOffset += number;
1023: currChangingElems[currIndex++] = bitOffset;
1024: }
1025:
1026: a0 = bitOffset;
1027: } else if (code <= 8) {
1028: // Vertical
1029: a1 = b1 + (code - 5);
1030:
1031: currChangingElems[currIndex++] = a1;
1032:
1033: // We write the current color till a1 - 1 pos,
1034: // since a1 is where the next color starts
1035: if (!isWhite) {
1036: setToBlack(buffer, lineOffset, bitOffset,
1037: a1 - bitOffset);
1038: }
1039: bitOffset = a0 = a1;
1040: isWhite = !isWhite;
1041:
1042: updatePointer(7 - bits);
1043: } else {
1044: throw new RuntimeException(JaiI18N
1045: .getString("TIFFFaxDecoder4"));
1046: }
1047: }
1048:
1049: // Add the changing element beyond the current scanline for the
1050: // other color too
1051: currChangingElems[currIndex++] = bitOffset;
1052: changingElemSize = currIndex;
1053: } else {
1054: // 1D encoded scanline follows
1055: decodeNextScanline(buffer, lineOffset, startX);
1056: }
1057:
1058: lineOffset += scanlineStride;
1059: }
1060: }
1061:
1062: public synchronized void decodeT6(byte[] buffer, byte[] compData,
1063: int startX, int height, long tiffT6Options) {
1064: this .data = compData;
1065: compression = 4;
1066:
1067: bitPointer = 0;
1068: bytePointer = 0;
1069:
1070: int scanlineStride = (w + 7) / 8;
1071: int bufferOffset = 0;
1072:
1073: int a0, a1, b1, b2;
1074: int entry, code, bits;
1075: byte color;
1076: boolean isWhite;
1077: int currIndex;
1078: int temp[];
1079:
1080: // Return values from getNextChangingElement
1081: int[] b = new int[2];
1082:
1083: // uncompressedMode - have written some code for this, but this
1084: // has not been tested due to lack of test images using this optional
1085: // extension. This code is when code == 11. aastha 03/03/1999
1086: uncompressedMode = (int) ((tiffT6Options & 0x02) >> 1);
1087:
1088: // Local cached reference
1089: int[] cce = currChangingElems;
1090:
1091: // Assume invisible preceding row of all white pixels and insert
1092: // both black and white changing elements beyond the end of this
1093: // imaginary scanline.
1094: changingElemSize = 0;
1095: cce[changingElemSize++] = w;
1096: cce[changingElemSize++] = w;
1097:
1098: int lineOffset = 0;
1099: int bitOffset;
1100:
1101: for (int lines = 0; lines < height; lines++) {
1102: // a0 has to be set just before the start of the scanline.
1103: a0 = -1;
1104: isWhite = true;
1105:
1106: // Assign the changing elements of the previous scanline to
1107: // prevChangingElems and start putting this new scanline's
1108: // changing elements into the currChangingElems.
1109: temp = prevChangingElems;
1110: prevChangingElems = currChangingElems;
1111: cce = currChangingElems = temp;
1112: currIndex = 0;
1113:
1114: // Start decoding the scanline at startX in the raster
1115: bitOffset = startX;
1116:
1117: // Reset search start position for getNextChangingElement
1118: lastChangingElement = 0;
1119:
1120: // Till one whole scanline is decoded
1121: while (bitOffset < w) {
1122: // Get the next changing element
1123: getNextChangingElement(a0, isWhite, b);
1124: b1 = b[0];
1125: b2 = b[1];
1126:
1127: // Get the next seven bits
1128: entry = nextLesserThan8Bits(7);
1129: // Run these through the 2DCodes table
1130: entry = (int) (twoDCodes[entry] & 0xff);
1131:
1132: // Get the code and the number of bits used up
1133: code = (entry & 0x78) >>> 3;
1134: bits = entry & 0x07;
1135:
1136: if (code == 0) { // Pass
1137: // We always assume WhiteIsZero format for fax.
1138: if (!isWhite) {
1139: if (b2 > w) {
1140: b2 = w;
1141: }
1142: setToBlack(buffer, lineOffset, bitOffset, b2
1143: - bitOffset);
1144: }
1145: bitOffset = a0 = b2;
1146:
1147: // Set pointer to only consume the correct number of bits.
1148: updatePointer(7 - bits);
1149: } else if (code == 1) { // Horizontal
1150: // Set pointer to only consume the correct number of bits.
1151: updatePointer(7 - bits);
1152:
1153: // identify the next 2 alternating color codes.
1154: int number;
1155: if (isWhite) {
1156: // Following are white and black runs
1157: number = decodeWhiteCodeWord();
1158: bitOffset += number;
1159: cce[currIndex++] = bitOffset;
1160:
1161: number = decodeBlackCodeWord();
1162: if (number > w - bitOffset) {
1163: number = w - bitOffset;
1164: }
1165: setToBlack(buffer, lineOffset, bitOffset,
1166: number);
1167: bitOffset += number;
1168: cce[currIndex++] = bitOffset;
1169: } else {
1170: // First a black run and then a white run follows
1171: number = decodeBlackCodeWord();
1172: if (number > w - bitOffset) {
1173: number = w - bitOffset;
1174: }
1175: setToBlack(buffer, lineOffset, bitOffset,
1176: number);
1177: bitOffset += number;
1178: cce[currIndex++] = bitOffset;
1179:
1180: number = decodeWhiteCodeWord();
1181: bitOffset += number;
1182: cce[currIndex++] = bitOffset;
1183: }
1184:
1185: a0 = bitOffset;
1186: } else if (code <= 8) { // Vertical
1187: a1 = b1 + (code - 5);
1188: cce[currIndex++] = a1;
1189:
1190: // We write the current color till a1 - 1 pos,
1191: // since a1 is where the next color starts
1192: if (!isWhite) {
1193: if (a1 > w) {
1194: a1 = w;
1195: }
1196: setToBlack(buffer, lineOffset, bitOffset, a1
1197: - bitOffset);
1198: }
1199: bitOffset = a0 = a1;
1200: isWhite = !isWhite;
1201:
1202: updatePointer(7 - bits);
1203: } else if (code == 11) {
1204: if (nextLesserThan8Bits(3) != 7) {
1205: throw new RuntimeException(JaiI18N
1206: .getString("TIFFFaxDecoder5"));
1207: }
1208:
1209: int zeros = 0;
1210: boolean exit = false;
1211:
1212: while (!exit) {
1213: while (nextLesserThan8Bits(1) != 1) {
1214: zeros++;
1215: }
1216:
1217: if (zeros > 5) {
1218: // Exit code
1219:
1220: // Zeros before exit code
1221: zeros = zeros - 6;
1222:
1223: if (!isWhite && (zeros > 0)) {
1224: cce[currIndex++] = bitOffset;
1225: }
1226:
1227: // Zeros before the exit code
1228: bitOffset += zeros;
1229: if (zeros > 0) {
1230: // Some zeros have been written
1231: isWhite = true;
1232: }
1233:
1234: // Read in the bit which specifies the color of
1235: // the following run
1236: if (nextLesserThan8Bits(1) == 0) {
1237: if (!isWhite) {
1238: cce[currIndex++] = bitOffset;
1239: }
1240: isWhite = true;
1241: } else {
1242: if (isWhite) {
1243: cce[currIndex++] = bitOffset;
1244: }
1245: isWhite = false;
1246: }
1247:
1248: exit = true;
1249: }
1250:
1251: if (zeros == 5) {
1252: if (!isWhite) {
1253: cce[currIndex++] = bitOffset;
1254: }
1255: bitOffset += zeros;
1256:
1257: // Last thing written was white
1258: isWhite = true;
1259: } else {
1260: bitOffset += zeros;
1261:
1262: cce[currIndex++] = bitOffset;
1263: setToBlack(buffer, lineOffset, bitOffset, 1);
1264: ++bitOffset;
1265:
1266: // Last thing written was black
1267: isWhite = false;
1268: }
1269:
1270: }
1271: } else {
1272: throw new RuntimeException(JaiI18N
1273: .getString("TIFFFaxDecoder5"));
1274: }
1275: }
1276:
1277: // Add the changing element beyond the current scanline for the
1278: // other color too, if not already added
1279: if (currIndex <= w)
1280: cce[currIndex++] = bitOffset;
1281:
1282: // Number of changing elements in this scanline.
1283: changingElemSize = currIndex;
1284: lineOffset += scanlineStride;
1285: }
1286: }
1287:
1288: private void setToBlack(byte[] buffer, int lineOffset,
1289: int bitOffset, int numBits) {
1290: int bitNum = 8 * lineOffset + bitOffset;
1291: int lastBit = bitNum + numBits;
1292:
1293: int byteNum = bitNum >> 3;
1294:
1295: // Handle bits in first byte
1296: int shift = bitNum & 0x7;
1297: if (shift > 0) {
1298: int maskVal = 1 << (7 - shift);
1299: byte val = buffer[byteNum];
1300: while (maskVal > 0 && bitNum < lastBit) {
1301: val |= maskVal;
1302: maskVal >>= 1;
1303: ++bitNum;
1304: }
1305: buffer[byteNum] = val;
1306: }
1307:
1308: // Fill in 8 bits at a time
1309: byteNum = bitNum >> 3;
1310: while (bitNum < lastBit - 7) {
1311: buffer[byteNum++] = (byte) 255;
1312: bitNum += 8;
1313: }
1314:
1315: // Fill in remaining bits
1316: while (bitNum < lastBit) {
1317: byteNum = bitNum >> 3;
1318: buffer[byteNum] |= 1 << (7 - (bitNum & 0x7));
1319: ++bitNum;
1320: }
1321: }
1322:
1323: // Returns run length
1324: private int decodeWhiteCodeWord() {
1325: int current, entry, bits, isT, twoBits, code = -1;
1326: int runLength = 0;
1327: boolean isWhite = true;
1328:
1329: while (isWhite) {
1330: current = nextNBits(10);
1331: entry = white[current];
1332:
1333: // Get the 3 fields from the entry
1334: isT = entry & 0x0001;
1335: bits = (entry >>> 1) & 0x0f;
1336:
1337: if (bits == 12) { // Additional Make up code
1338: // Get the next 2 bits
1339: twoBits = nextLesserThan8Bits(2);
1340: // Consolidate the 2 new bits and last 2 bits into 4 bits
1341: current = ((current << 2) & 0x000c) | twoBits;
1342: entry = additionalMakeup[current];
1343: bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
1344: code = (entry >>> 4) & 0x0fff; // 12 bits
1345: runLength += code;
1346: updatePointer(4 - bits);
1347: } else if (bits == 0) { // ERROR
1348: throw new RuntimeException(JaiI18N
1349: .getString("TIFFFaxDecoder0"));
1350: } else if (bits == 15) { // EOL
1351: throw new RuntimeException(JaiI18N
1352: .getString("TIFFFaxDecoder1"));
1353: } else {
1354: // 11 bits - 0000 0111 1111 1111 = 0x07ff
1355: code = (entry >>> 5) & 0x07ff;
1356: runLength += code;
1357: updatePointer(10 - bits);
1358: if (isT == 0) {
1359: isWhite = false;
1360: }
1361: }
1362: }
1363:
1364: return runLength;
1365: }
1366:
1367: // Returns run length
1368: private int decodeBlackCodeWord() {
1369: int current, entry, bits, isT, twoBits, code = -1;
1370: int runLength = 0;
1371: boolean isWhite = false;
1372:
1373: while (!isWhite) {
1374: current = nextLesserThan8Bits(4);
1375: entry = initBlack[current];
1376:
1377: // Get the 3 fields from the entry
1378: isT = entry & 0x0001;
1379: bits = (entry >>> 1) & 0x000f;
1380: code = (entry >>> 5) & 0x07ff;
1381:
1382: if (code == 100) {
1383: current = nextNBits(9);
1384: entry = black[current];
1385:
1386: // Get the 3 fields from the entry
1387: isT = entry & 0x0001;
1388: bits = (entry >>> 1) & 0x000f;
1389: code = (entry >>> 5) & 0x07ff;
1390:
1391: if (bits == 12) {
1392: // Additional makeup codes
1393: updatePointer(5);
1394: current = nextLesserThan8Bits(4);
1395: entry = additionalMakeup[current];
1396: bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
1397: code = (entry >>> 4) & 0x0fff; // 12 bits
1398: runLength += code;
1399:
1400: updatePointer(4 - bits);
1401: } else if (bits == 15) {
1402: // EOL code
1403: throw new RuntimeException(JaiI18N
1404: .getString("TIFFFaxDecoder2"));
1405: } else {
1406: runLength += code;
1407: updatePointer(9 - bits);
1408: if (isT == 0) {
1409: isWhite = true;
1410: }
1411: }
1412: } else if (code == 200) {
1413: // Is a Terminating code
1414: current = nextLesserThan8Bits(2);
1415: entry = twoBitBlack[current];
1416: code = (entry >>> 5) & 0x07ff;
1417: runLength += code;
1418: bits = (entry >>> 1) & 0x0f;
1419: updatePointer(2 - bits);
1420: isWhite = true;
1421: } else {
1422: // Is a Terminating code
1423: runLength += code;
1424: updatePointer(4 - bits);
1425: isWhite = true;
1426: }
1427: }
1428:
1429: return runLength;
1430: }
1431:
1432: // Seeks to the next EOL in the compressed bitstream.
1433: // Returns 'true' if and only if an EOL is found; if 'false'
1434: // is returned it may be inferred that the EOF was reached first.
1435: private boolean seekEOL() {
1436: // Set maximum and current bit index into the compressed data.
1437: int bitIndexMax = data.length * 8 - 1;
1438: int bitIndex = bytePointer * 8 + bitPointer;
1439:
1440: // Loop while at least 12 bits are available.
1441: while (bitIndex <= bitIndexMax - 12) {
1442: // Get the next 12 bits.
1443: int next12Bits = nextNBits(12);
1444: bitIndex += 12;
1445:
1446: // Loop while the 12 bits are not unity, i.e., while the EOL
1447: // has not been reached, and there is at least one bit left.
1448: while (next12Bits != 1 && bitIndex < bitIndexMax) {
1449: next12Bits = ((next12Bits & 0x000007ff) << 1)
1450: | (nextLesserThan8Bits(1) & 0x00000001);
1451: bitIndex++;
1452: }
1453:
1454: // If EOL reached, rewind the pointers and return 'true'.
1455: if (next12Bits == 1) {
1456: updatePointer(12);
1457: return true;
1458: }
1459: }
1460:
1461: // EOL not found: return 'false'.
1462: return false;
1463: }
1464:
1465: private int readEOL(boolean isFirstEOL) {
1466: if (oneD == 0) {
1467: // Seek to the next EOL.
1468: if (!seekEOL()) {
1469: throw new RuntimeException(JaiI18N
1470: .getString("TIFFFaxDecoder9"));
1471: }
1472: }
1473:
1474: if (fillBits == 0) {
1475: int next12Bits = nextNBits(12);
1476: if (isFirstEOL && next12Bits == 0) {
1477:
1478: // Might have the case of EOL padding being used even
1479: // though it was not flagged in the T4Options field.
1480: // This was observed to be the case in TIFFs produced
1481: // by a well known vendor who shall remain nameless.
1482:
1483: if (nextNBits(4) == 1) {
1484: //
1485: // EOL must be padded: reset the fillBits flag.
1486: //
1487: fillBits = 1;
1488: return 1;
1489: }
1490: }
1491: if (next12Bits != 1) {
1492: throw new RuntimeException(JaiI18N
1493: .getString("TIFFFaxDecoder6"));
1494: }
1495: } else if (fillBits == 1) {
1496:
1497: // First EOL code word xxxx 0000 0000 0001 will occur
1498: // As many fill bits will be present as required to make
1499: // the EOL code of 12 bits end on a byte boundary.
1500:
1501: int bitsLeft = 8 - bitPointer;
1502:
1503: if (nextNBits(bitsLeft) != 0) {
1504: throw new RuntimeException(JaiI18N
1505: .getString("TIFFFaxDecoder8"));
1506: }
1507:
1508: // If the number of bitsLeft is less than 4, then to have a 12
1509: // bit EOL sequence, two more bytes are certainly going to be
1510: // required. The first of them has to be all zeros, so ensure
1511: // that.
1512: if (bitsLeft < 4) {
1513: if (nextNBits(8) != 0) {
1514: throw new RuntimeException(JaiI18N
1515: .getString("TIFFFaxDecoder8"));
1516: }
1517: }
1518:
1519: //
1520: // Some encoders under Group 3 Fax compression 1D writes TIFF
1521: // files without the fill bits, but say otherwise in T4Options.
1522: // Need to check for this here.
1523: //
1524: int next8 = nextNBits(8);
1525:
1526: if (isFirstEOL && (next8 & 0xf0) == 0x10) {
1527: //
1528: // Fill bits are not actually used despite what the flag
1529: // says. So switch fillBits off and then rewind so that
1530: // only 12 bits have effectively been read.
1531: //
1532: fillBits = 0;
1533: updatePointer(4);
1534: } else {
1535: //
1536: // This is the normal case.
1537: // There might be a random number of fill bytes with 0s, so
1538: // loop till the EOL of 0000 0001 is found, as long as all
1539: // the bytes preceding it are 0's.
1540: //
1541: while (next8 != 1) {
1542: // If not all zeros
1543: if (next8 != 0) {
1544: throw new RuntimeException(JaiI18N
1545: .getString("TIFFFaxDecoder8"));
1546: }
1547: next8 = nextNBits(8);
1548: }
1549: }
1550: }
1551:
1552: // If one dimensional encoding mode, then always return 1
1553: if (oneD == 0) {
1554: return 1;
1555: } else {
1556: // Otherwise for 2D encoding mode,
1557: // The next one bit signifies 1D/2D encoding of next line.
1558: return nextLesserThan8Bits(1);
1559: }
1560: }
1561:
1562: private void getNextChangingElement(int a0, boolean isWhite,
1563: int[] ret) {
1564: // Local copies of instance variables
1565: int[] pce = this .prevChangingElems;
1566: int ces = this .changingElemSize;
1567:
1568: // If the previous match was at an odd element, we still
1569: // have to search the preceeding element.
1570: // int start = lastChangingElement & ~0x1;
1571: int start = lastChangingElement > 0 ? lastChangingElement - 1
1572: : 0;
1573: if (isWhite) {
1574: start &= ~0x1; // Search even numbered elements
1575: } else {
1576: start |= 0x1; // Search odd numbered elements
1577: }
1578:
1579: int i = start;
1580: for (; i < ces; i += 2) {
1581: int temp = pce[i];
1582: if (temp > a0) {
1583: lastChangingElement = i;
1584: ret[0] = temp;
1585: break;
1586: }
1587: }
1588:
1589: if (i + 1 < ces) {
1590: ret[1] = pce[i + 1];
1591: }
1592: }
1593:
1594: private int nextNBits(int bitsToGet) {
1595: byte b, next, next2next;
1596: int l = data.length - 1;
1597: int bp = this .bytePointer;
1598:
1599: if (fillOrder == 1) {
1600: b = data[bp];
1601:
1602: if (bp == l) {
1603: next = 0x00;
1604: next2next = 0x00;
1605: } else if ((bp + 1) == l) {
1606: next = data[bp + 1];
1607: next2next = 0x00;
1608: } else {
1609: next = data[bp + 1];
1610: next2next = data[bp + 2];
1611: }
1612: } else if (fillOrder == 2) {
1613: b = flipTable[data[bp] & 0xff];
1614:
1615: if (bp == l) {
1616: next = 0x00;
1617: next2next = 0x00;
1618: } else if ((bp + 1) == l) {
1619: next = flipTable[data[bp + 1] & 0xff];
1620: next2next = 0x00;
1621: } else {
1622: next = flipTable[data[bp + 1] & 0xff];
1623: next2next = flipTable[data[bp + 2] & 0xff];
1624: }
1625: } else {
1626: throw new RuntimeException(JaiI18N
1627: .getString("TIFFFaxDecoder7"));
1628: }
1629:
1630: int bitsLeft = 8 - bitPointer;
1631: int bitsFromNextByte = bitsToGet - bitsLeft;
1632: int bitsFromNext2NextByte = 0;
1633: if (bitsFromNextByte > 8) {
1634: bitsFromNext2NextByte = bitsFromNextByte - 8;
1635: bitsFromNextByte = 8;
1636: }
1637:
1638: bytePointer++;
1639:
1640: int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft);
1641: int i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte);
1642:
1643: int i3 = 0;
1644: if (bitsFromNext2NextByte != 0) {
1645: i2 <<= bitsFromNext2NextByte;
1646: i3 = (next2next & table2[bitsFromNext2NextByte]) >>> (8 - bitsFromNext2NextByte);
1647: i2 |= i3;
1648: bytePointer++;
1649: bitPointer = bitsFromNext2NextByte;
1650: } else {
1651: if (bitsFromNextByte == 8) {
1652: bitPointer = 0;
1653: bytePointer++;
1654: } else {
1655: bitPointer = bitsFromNextByte;
1656: }
1657: }
1658:
1659: int i = i1 | i2;
1660: return i;
1661: }
1662:
1663: private int nextLesserThan8Bits(int bitsToGet) {
1664: byte b, next;
1665: int l = data.length - 1;
1666: int bp = this .bytePointer;
1667:
1668: if (fillOrder == 1) {
1669: b = data[bp];
1670: if (bp == l) {
1671: next = 0x00;
1672: } else {
1673: next = data[bp + 1];
1674: }
1675: } else if (fillOrder == 2) {
1676: b = flipTable[data[bp] & 0xff];
1677: if (bp == l) {
1678: next = 0x00;
1679: } else {
1680: next = flipTable[data[bp + 1] & 0xff];
1681: }
1682: } else {
1683: throw new RuntimeException(JaiI18N
1684: .getString("TIFFFaxDecoder7"));
1685: }
1686:
1687: int bitsLeft = 8 - bitPointer;
1688: int bitsFromNextByte = bitsToGet - bitsLeft;
1689:
1690: int shift = bitsLeft - bitsToGet;
1691: int i1, i2;
1692: if (shift >= 0) {
1693: i1 = (b & table1[bitsLeft]) >>> shift;
1694: bitPointer += bitsToGet;
1695: if (bitPointer == 8) {
1696: bitPointer = 0;
1697: bytePointer++;
1698: }
1699: } else {
1700: i1 = (b & table1[bitsLeft]) << (-shift);
1701: i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte);
1702:
1703: i1 |= i2;
1704: bytePointer++;
1705: bitPointer = bitsFromNextByte;
1706: }
1707:
1708: return i1;
1709: }
1710:
1711: // Move pointer backwards by given amount of bits
1712: private void updatePointer(int bitsToMoveBack) {
1713: if (bitsToMoveBack > 8) {
1714: bytePointer -= bitsToMoveBack / 8;
1715: bitsToMoveBack %= 8;
1716: }
1717:
1718: int i = bitPointer - bitsToMoveBack;
1719:
1720: if (i < 0) {
1721: bytePointer--;
1722: bitPointer = 8 + i;
1723: } else {
1724: bitPointer = i;
1725: }
1726: }
1727:
1728: // Move to the next byte boundary
1729: private boolean advancePointer() {
1730: if (bitPointer != 0) {
1731: bytePointer++;
1732: bitPointer = 0;
1733: }
1734:
1735: return true;
1736: }
1737: }
|