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