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