| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.ext.awt.image.codec.tiff; |
| |
| /** |
| * |
| * @version $Id$ |
| */ |
| class TIFFFaxDecoder { |
| |
| private int bitPointer, bytePointer; |
| private byte[] data; |
| private int w, h; |
| private int fillOrder; |
| |
| // Data structures needed to store changing elements for the previous |
| // and the current scanline |
| private int changingElemSize = 0; |
| private int[] prevChangingElems; |
| private int[] currChangingElems; |
| |
| // Element at which to start search in getNextChangingElement |
| private int lastChangingElement = 0; |
| |
| private int compression = 2; |
| |
| // Variables set by T4Options |
| private int uncompressedMode = 0; |
| private int fillBits = 0; |
| private int oneD; |
| |
| static int[] table1 = { |
| 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN |
| 0x01, // 1 bits are left in first byte |
| 0x03, // 2 bits are left in first byte |
| 0x07, // 3 bits are left in first byte |
| 0x0f, // 4 bits are left in first byte |
| 0x1f, // 5 bits are left in first byte |
| 0x3f, // 6 bits are left in first byte |
| 0x7f, // 7 bits are left in first byte |
| 0xff // 8 bits are left in first byte |
| }; |
| |
| static int[] table2 = { |
| 0x00, // 0 |
| 0x80, // 1 |
| 0xc0, // 2 |
| 0xe0, // 3 |
| 0xf0, // 4 |
| 0xf8, // 5 |
| 0xfc, // 6 |
| 0xfe, // 7 |
| 0xff // 8 |
| }; |
| |
| // Table to be used when fillOrder = 2, for flipping bytes. |
| static byte[] flipTable = { |
| 0, -128, 64, -64, 32, -96, 96, -32, |
| 16, -112, 80, -48, 48, -80, 112, -16, |
| 8, -120, 72, -56, 40, -88, 104, -24, |
| 24, -104, 88, -40, 56, -72, 120, -8, |
| 4, -124, 68, -60, 36, -92, 100, -28, |
| 20, -108, 84, -44, 52, -76, 116, -12, |
| 12, -116, 76, -52, 44, -84, 108, -20, |
| 28, -100, 92, -36, 60, -68, 124, -4, |
| 2, -126, 66, -62, 34, -94, 98, -30, |
| 18, -110, 82, -46, 50, -78, 114, -14, |
| 10, -118, 74, -54, 42, -86, 106, -22, |
| 26, -102, 90, -38, 58, -70, 122, -6, |
| 6, -122, 70, -58, 38, -90, 102, -26, |
| 22, -106, 86, -42, 54, -74, 118, -10, |
| 14, -114, 78, -50, 46, -82, 110, -18, |
| 30, -98, 94, -34, 62, -66, 126, -2, |
| 1, -127, 65, -63, 33, -95, 97, -31, |
| 17, -111, 81, -47, 49, -79, 113, -15, |
| 9, -119, 73, -55, 41, -87, 105, -23, |
| 25, -103, 89, -39, 57, -71, 121, -7, |
| 5, -123, 69, -59, 37, -91, 101, -27, |
| 21, -107, 85, -43, 53, -75, 117, -11, |
| 13, -115, 77, -51, 45, -83, 109, -19, |
| 29, -99, 93, -35, 61, -67, 125, -3, |
| 3, -125, 67, -61, 35, -93, 99, -29, |
| 19, -109, 83, -45, 51, -77, 115, -13, |
| 11, -117, 75, -53, 43, -85, 107, -21, |
| 27, -101, 91, -37, 59, -69, 123, -5, |
| 7, -121, 71, -57, 39, -89, 103, -25, |
| 23, -105, 87, -41, 55, -73, 119, -9, |
| 15, -113, 79, -49, 47, -81, 111, -17, |
| 31, -97, 95, -33, 63, -65, 127, -1, |
| }; |
| |
| // The main 10 bit white runs lookup table |
| static short[] white = { |
| // 0 - 7 |
| 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225, |
| // 8 - 15 |
| 944, 944, 944, 944, 976, 976, 976, 976, |
| // 16 - 23 |
| 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488, |
| // 24 - 31 |
| 718, 718, 718, 718, 718, 718, 718, 718, |
| // 32 - 39 |
| 750, 750, 750, 750, 750, 750, 750, 750, |
| // 40 - 47 |
| 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552, |
| // 48 - 55 |
| 428, 428, 428, 428, 428, 428, 428, 428, |
| // 56 - 63 |
| 428, 428, 428, 428, 428, 428, 428, 428, |
| // 64 - 71 |
| 654, 654, 654, 654, 654, 654, 654, 654, |
| // 72 - 79 |
| 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104, |
| // 80 - 87 |
| 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168, |
| // 88 - 95 |
| 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232, |
| // 96 - 103 |
| 622, 622, 622, 622, 622, 622, 622, 622, |
| // 104 - 111 |
| 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040, |
| // 112 - 119 |
| 44, 44, 44, 44, 44, 44, 44, 44, |
| // 120 - 127 |
| 44, 44, 44, 44, 44, 44, 44, 44, |
| // 128 - 135 |
| 396, 396, 396, 396, 396, 396, 396, 396, |
| // 136 - 143 |
| 396, 396, 396, 396, 396, 396, 396, 396, |
| // 144 - 151 |
| 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744, |
| // 152 - 159 |
| 846, 846, 846, 846, 846, 846, 846, 846, |
| // 160 - 167 |
| 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296, |
| // 168 - 175 |
| 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360, |
| // 176 - 183 |
| 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424, |
| // 184 - 191 |
| 686, 686, 686, 686, 686, 686, 686, 686, |
| // 192 - 199 |
| 910, 910, 910, 910, 910, 910, 910, 910, |
| // 200 - 207 |
| 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000, |
| // 208 - 215 |
| 2032, 2032, 2032, 2032, 16, 16, 16, 16, |
| // 216 - 223 |
| 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305, |
| // 224 - 231 |
| 330, 330, 330, 330, 330, 330, 330, 330, |
| // 232 - 239 |
| 330, 330, 330, 330, 330, 330, 330, 330, |
| // 240 - 247 |
| 330, 330, 330, 330, 330, 330, 330, 330, |
| // 248 - 255 |
| 330, 330, 330, 330, 330, 330, 330, 330, |
| // 256 - 263 |
| 362, 362, 362, 362, 362, 362, 362, 362, |
| // 264 - 271 |
| 362, 362, 362, 362, 362, 362, 362, 362, |
| // 272 - 279 |
| 362, 362, 362, 362, 362, 362, 362, 362, |
| // 280 - 287 |
| 362, 362, 362, 362, 362, 362, 362, 362, |
| // 288 - 295 |
| 878, 878, 878, 878, 878, 878, 878, 878, |
| // 296 - 303 |
| 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936, |
| // 304 - 311 |
| -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221, |
| // 312 - 319 |
| 590, 590, 590, 590, 590, 590, 590, 590, |
| // 320 - 327 |
| 782, 782, 782, 782, 782, 782, 782, 782, |
| // 328 - 335 |
| 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616, |
| // 336 - 343 |
| 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680, |
| // 344 - 351 |
| 814, 814, 814, 814, 814, 814, 814, 814, |
| // 352 - 359 |
| 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808, |
| // 360 - 367 |
| 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872, |
| // 368 - 375 |
| 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, |
| // 376 - 383 |
| 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, |
| // 384 - 391 |
| -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, |
| // 392 - 399 |
| -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, |
| // 400 - 407 |
| 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401, |
| // 408 - 415 |
| 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497, |
| // 416 - 423 |
| 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691, |
| // 424 - 431 |
| 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653, |
| // 432 - 439 |
| -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461, |
| // 440 - 447 |
| 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207, |
| // 448 - 455 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 456 - 463 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 464 - 471 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 472 - 479 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 480 - 487 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 488 - 495 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 496 - 503 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 504 - 511 |
| 72, 72, 72, 72, 72, 72, 72, 72, |
| // 512 - 519 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 520 - 527 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 528 - 535 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 536 - 543 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 544 - 551 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 552 - 559 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 560 - 567 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 568 - 575 |
| 104, 104, 104, 104, 104, 104, 104, 104, |
| // 576 - 583 |
| 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, |
| // 584 - 591 |
| 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, |
| // 592 - 599 |
| 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, |
| // 600 - 607 |
| 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, |
| // 608 - 615 |
| 266, 266, 266, 266, 266, 266, 266, 266, |
| // 616 - 623 |
| 266, 266, 266, 266, 266, 266, 266, 266, |
| // 624 - 631 |
| 266, 266, 266, 266, 266, 266, 266, 266, |
| // 632 - 639 |
| 266, 266, 266, 266, 266, 266, 266, 266, |
| // 640 - 647 |
| 298, 298, 298, 298, 298, 298, 298, 298, |
| // 648 - 655 |
| 298, 298, 298, 298, 298, 298, 298, 298, |
| // 656 - 663 |
| 298, 298, 298, 298, 298, 298, 298, 298, |
| // 664 - 671 |
| 298, 298, 298, 298, 298, 298, 298, 298, |
| // 672 - 679 |
| 524, 524, 524, 524, 524, 524, 524, 524, |
| // 680 - 687 |
| 524, 524, 524, 524, 524, 524, 524, 524, |
| // 688 - 695 |
| 556, 556, 556, 556, 556, 556, 556, 556, |
| // 696 - 703 |
| 556, 556, 556, 556, 556, 556, 556, 556, |
| // 704 - 711 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 712 - 719 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 720 - 727 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 728 - 735 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 736 - 743 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 744 - 751 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 752 - 759 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 760 - 767 |
| 136, 136, 136, 136, 136, 136, 136, 136, |
| // 768 - 775 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 776 - 783 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 784 - 791 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 792 - 799 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 800 - 807 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 808 - 815 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 816 - 823 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 824 - 831 |
| 168, 168, 168, 168, 168, 168, 168, 168, |
| // 832 - 839 |
| 460, 460, 460, 460, 460, 460, 460, 460, |
| // 840 - 847 |
| 460, 460, 460, 460, 460, 460, 460, 460, |
| // 848 - 855 |
| 492, 492, 492, 492, 492, 492, 492, 492, |
| // 856 - 863 |
| 492, 492, 492, 492, 492, 492, 492, 492, |
| // 864 - 871 |
| 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, |
| // 872 - 879 |
| 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, |
| // 880 - 887 |
| 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, |
| // 888 - 895 |
| 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, |
| // 896 - 903 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 904 - 911 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 912 - 919 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 920 - 927 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 928 - 935 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 936 - 943 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 944 - 951 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 952 - 959 |
| 200, 200, 200, 200, 200, 200, 200, 200, |
| // 960 - 967 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 968 - 975 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 976 - 983 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 984 - 991 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 992 - 999 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 1000 - 1007 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 1008 - 1015 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| // 1016 - 1023 |
| 232, 232, 232, 232, 232, 232, 232, 232, |
| }; |
| |
| // Additional make up codes for both White and Black runs |
| static short[] additionalMakeup = { |
| 28679, 28679, 31752, (short)32777, |
| (short)33801, (short)34825, (short)35849, (short)36873, |
| (short)29703, (short)29703, (short)30727, (short)30727, |
| (short)37897, (short)38921, (short)39945, (short)40969 |
| }; |
| |
| // Initial black run look up table, uses the first 4 bits of a code |
| static short[] initBlack = { |
| // 0 - 7 |
| 3226, 6412, 200, 168, 38, 38, 134, 134, |
| // 8 - 15 |
| 100, 100, 100, 100, 68, 68, 68, 68 |
| }; |
| |
| // |
| static short[] twoBitBlack = {292, 260, 226, 226}; // 0 - 3 |
| |
| // Main black run table, using the last 9 bits of possible 13 bit code |
| static short[] black = { |
| // 0 - 7 |
| 62, 62, 30, 30, 0, 0, 0, 0, |
| // 8 - 15 |
| 0, 0, 0, 0, 0, 0, 0, 0, |
| // 16 - 23 |
| 0, 0, 0, 0, 0, 0, 0, 0, |
| // 24 - 31 |
| 0, 0, 0, 0, 0, 0, 0, 0, |
| // 32 - 39 |
| 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, |
| // 40 - 47 |
| 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, |
| // 48 - 55 |
| 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, |
| // 56 - 63 |
| 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, |
| // 64 - 71 |
| 588, 588, 588, 588, 588, 588, 588, 588, |
| // 72 - 79 |
| 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776, |
| // 80 - 87 |
| 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904, |
| // 88 - 95 |
| 1936, 1936, -16365, -14317, 782, 782, 782, 782, |
| // 96 - 103 |
| 814, 814, 814, 814, -12269, -10221, 10257, 10257, |
| // 104 - 111 |
| 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712, |
| // 112 - 119 |
| 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605, |
| // 120 - 127 |
| 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061, |
| // 128 - 135 |
| 424, 424, 424, 424, 424, 424, 424, 424, |
| // 136 - 143 |
| 424, 424, 424, 424, 424, 424, 424, 424, |
| // 144 - 151 |
| 424, 424, 424, 424, 424, 424, 424, 424, |
| // 152 - 159 |
| 424, 424, 424, 424, 424, 424, 424, 424, |
| // 160 - 167 |
| 750, 750, 750, 750, 1616, 1616, 1648, 1648, |
| // 168 - 175 |
| 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520, |
| // 176 - 183 |
| 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209, |
| // 184 - 191 |
| 524, 524, 524, 524, 524, 524, 524, 524, |
| // 192 - 199 |
| 556, 556, 556, 556, 556, 556, 556, 556, |
| // 200 - 207 |
| 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032, |
| // 208 - 215 |
| 976, 976, 1008, 1008, 1040, 1040, 1072, 1072, |
| // 216 - 223 |
| 1296, 1296, 1328, 1328, 718, 718, 718, 718, |
| // 224 - 231 |
| 456, 456, 456, 456, 456, 456, 456, 456, |
| // 232 - 239 |
| 456, 456, 456, 456, 456, 456, 456, 456, |
| // 240 - 247 |
| 456, 456, 456, 456, 456, 456, 456, 456, |
| // 248 - 255 |
| 456, 456, 456, 456, 456, 456, 456, 456, |
| // 256 - 263 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 264 - 271 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 272 - 279 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 280 - 287 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 288 - 295 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 296 - 303 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 304 - 311 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 312 - 319 |
| 326, 326, 326, 326, 326, 326, 326, 326, |
| // 320 - 327 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 328 - 335 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 336 - 343 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 344 - 351 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 352 - 359 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 360 - 367 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 368 - 375 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 376 - 383 |
| 358, 358, 358, 358, 358, 358, 358, 358, |
| // 384 - 391 |
| 490, 490, 490, 490, 490, 490, 490, 490, |
| // 392 - 399 |
| 490, 490, 490, 490, 490, 490, 490, 490, |
| // 400 - 407 |
| 4113, 4113, 6161, 6161, 848, 848, 880, 880, |
| // 408 - 415 |
| 912, 912, 944, 944, 622, 622, 622, 622, |
| // 416 - 423 |
| 654, 654, 654, 654, 1104, 1104, 1136, 1136, |
| // 424 - 431 |
| 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264, |
| // 432 - 439 |
| 686, 686, 686, 686, 1360, 1360, 1392, 1392, |
| // 440 - 447 |
| 12, 12, 12, 12, 12, 12, 12, 12, |
| // 448 - 455 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 456 - 463 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 464 - 471 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 472 - 479 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 480 - 487 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 488 - 495 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 496 - 503 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| // 504 - 511 |
| 390, 390, 390, 390, 390, 390, 390, 390, |
| }; |
| |
| static byte[] twoDCodes = { |
| // 0 - 7 |
| 80, 88, 23, 71, 30, 30, 62, 62, |
| // 8 - 15 |
| 4, 4, 4, 4, 4, 4, 4, 4, |
| // 16 - 23 |
| 11, 11, 11, 11, 11, 11, 11, 11, |
| // 24 - 31 |
| 11, 11, 11, 11, 11, 11, 11, 11, |
| // 32 - 39 |
| 35, 35, 35, 35, 35, 35, 35, 35, |
| // 40 - 47 |
| 35, 35, 35, 35, 35, 35, 35, 35, |
| // 48 - 55 |
| 51, 51, 51, 51, 51, 51, 51, 51, |
| // 56 - 63 |
| 51, 51, 51, 51, 51, 51, 51, 51, |
| // 64 - 71 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 72 - 79 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 80 - 87 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 88 - 95 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 96 - 103 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 104 - 111 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 112 - 119 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| // 120 - 127 |
| 41, 41, 41, 41, 41, 41, 41, 41, |
| }; |
| |
| /** |
| * @param fillOrder The fill order of the compressed data bytes. |
| */ |
| public TIFFFaxDecoder(int fillOrder, int w, int h) { |
| this.fillOrder = fillOrder; |
| this.w = w; |
| this.h = h; |
| |
| this.bitPointer = 0; |
| this.bytePointer = 0; |
| this.prevChangingElems = new int[w]; |
| this.currChangingElems = new int[w]; |
| } |
| |
| // One-dimensional decoding methods |
| |
| public void decode1D(byte[] buffer, byte[] compData, |
| int startX, int height) { |
| this.data = compData; |
| |
| int lineOffset = 0; |
| int scanlineStride = (w + 7)/8; |
| |
| bitPointer = 0; |
| bytePointer = 0; |
| |
| for (int i = 0; i < height; i++) { |
| decodeNextScanline(buffer, lineOffset, startX); |
| lineOffset += scanlineStride; |
| } |
| } |
| |
| public void decodeNextScanline(byte[] buffer, |
| int lineOffset, int bitOffset) { |
| int bits = 0, code = 0, isT = 0; |
| int current, entry, twoBits; |
| boolean isWhite = true; |
| |
| // Initialize starting of the changing elements array |
| changingElemSize = 0; |
| |
| // While scanline not complete |
| while (bitOffset < w) { |
| while (isWhite) { |
| // White run |
| current = nextNBits(10); |
| entry = white[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x0f; |
| |
| if (bits == 12) { // Additional Make up code |
| // Get the next 2 bits |
| twoBits = nextLesserThan8Bits(2); |
| // Consolidate the 2 new bits and last 2 bits into 4 bits |
| current = ((current << 2) & 0x000c) | twoBits; |
| entry = additionalMakeup[current]; |
| bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 |
| code = (entry >>> 4) & 0x0fff; // 12 bits |
| bitOffset += code; // Skip white run |
| |
| updatePointer(4 - bits); |
| } else if (bits == 0) { // ERROR |
| throw new Error("TIFFFaxDecoder0"); |
| } else if (bits == 15) { // EOL |
| throw new Error("TIFFFaxDecoder1"); |
| } else { |
| // 11 bits - 0000 0111 1111 1111 = 0x07ff |
| code = (entry >>> 5) & 0x07ff; |
| bitOffset += code; |
| |
| updatePointer(10 - bits); |
| if (isT == 0) { |
| isWhite = false; |
| currChangingElems[changingElemSize++] = bitOffset; |
| } |
| } |
| } |
| |
| // Check whether this run completed one width, if so |
| // advance to next byte boundary for compression = 2. |
| if (bitOffset == w) { |
| if (compression == 2) { |
| advancePointer(); |
| } |
| break; |
| } |
| |
| while ( ! isWhite ) { |
| // Black run |
| current = nextLesserThan8Bits(4); |
| entry = initBlack[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x000f; |
| code = (entry >>> 5) & 0x07ff; |
| |
| if (code == 100) { |
| current = nextNBits(9); |
| entry = black[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x000f; |
| code = (entry >>> 5) & 0x07ff; |
| |
| if (bits == 12) { |
| // Additional makeup codes |
| updatePointer(5); |
| current = nextLesserThan8Bits(4); |
| entry = additionalMakeup[current]; |
| bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 |
| code = (entry >>> 4) & 0x0fff; // 12 bits |
| |
| setToBlack(buffer, lineOffset, bitOffset, code); |
| bitOffset += code; |
| |
| updatePointer(4 - bits); |
| } else if (bits == 15) { |
| // EOL code |
| throw new Error("TIFFFaxDecoder2"); |
| } else { |
| setToBlack(buffer, lineOffset, bitOffset, code); |
| bitOffset += code; |
| |
| updatePointer(9 - bits); |
| if (isT == 0) { |
| isWhite = true; |
| currChangingElems[changingElemSize++] = bitOffset; |
| } |
| } |
| } else if (code == 200) { |
| // Is a Terminating code |
| current = nextLesserThan8Bits(2); |
| entry = twoBitBlack[current]; |
| code = (entry >>> 5) & 0x07ff; |
| bits = (entry >>> 1) & 0x0f; |
| |
| setToBlack(buffer, lineOffset, bitOffset, code); |
| bitOffset += code; |
| |
| updatePointer(2 - bits); |
| isWhite = true; |
| currChangingElems[changingElemSize++] = bitOffset; |
| } else { |
| // Is a Terminating code |
| setToBlack(buffer, lineOffset, bitOffset, code); |
| bitOffset += code; |
| |
| updatePointer(4 - bits); |
| isWhite = true; |
| currChangingElems[changingElemSize++] = bitOffset; |
| } |
| } |
| |
| // Check whether this run completed one width |
| if (bitOffset == w) { |
| if (compression == 2) { |
| advancePointer(); |
| } |
| break; |
| } |
| } |
| |
| currChangingElems[changingElemSize++] = bitOffset; |
| } |
| |
| // Two-dimensional decoding methods |
| |
| public void decode2D(byte[] buffer, |
| byte[] compData, |
| int startX, |
| int height, |
| long tiffT4Options) { |
| this.data = compData; |
| compression = 3; |
| |
| bitPointer = 0; |
| bytePointer = 0; |
| |
| int scanlineStride = (w + 7)/8; |
| |
| int a0, a1, b1, b2; |
| int[] b = new int[2]; |
| int entry, code, bits; |
| boolean isWhite; |
| int currIndex = 0; |
| int[] temp; |
| |
| // fillBits - dealt with this in readEOL |
| // 1D/2D encoding - dealt with this in readEOL |
| |
| // uncompressedMode - haven't dealt with this yet. |
| |
| |
| oneD = (int)(tiffT4Options & 0x01); |
| uncompressedMode = (int)((tiffT4Options & 0x02) >> 1); |
| fillBits = (int)((tiffT4Options & 0x04) >> 2); |
| |
| // The data must start with an EOL code |
| if (readEOL() != 1) { |
| throw new Error("TIFFFaxDecoder3"); |
| } |
| |
| int lineOffset = 0; |
| int bitOffset; |
| |
| // Then the 1D encoded scanline data will occur, changing elements |
| // array gets set. |
| decodeNextScanline(buffer, lineOffset, startX); |
| lineOffset += scanlineStride; |
| |
| for (int lines = 1; lines < height; lines++) { |
| |
| // Every line must begin with an EOL followed by a bit which |
| // indicates whether the following scanline is 1D or 2D encoded. |
| if (readEOL() == 0) { |
| // 2D encoded scanline follows |
| |
| // Initialize previous scanlines changing elements, and |
| // initialize current scanline's changing elements array |
| temp = prevChangingElems; |
| prevChangingElems = currChangingElems; |
| currChangingElems = temp; |
| currIndex = 0; |
| |
| // a0 has to be set just before the start of this scanline. |
| a0 = -1; |
| isWhite = true; |
| bitOffset = startX; |
| |
| lastChangingElement = 0; |
| |
| while (bitOffset < w) { |
| // Get the next changing element |
| getNextChangingElement(a0, isWhite, b); |
| |
| b1 = b[0]; |
| b2 = b[1]; |
| |
| // Get the next seven bits |
| entry = nextLesserThan8Bits(7); |
| |
| // Run these through the 2DCodes table |
| entry = (int)(twoDCodes[entry] & 0xff); |
| |
| // Get the code and the number of bits used up |
| code = (entry & 0x78) >>> 3; |
| bits = entry & 0x07; |
| |
| if (code == 0) { |
| if (!isWhite) { |
| setToBlack(buffer, lineOffset, bitOffset, |
| b2 - bitOffset); |
| } |
| bitOffset = a0 = b2; |
| |
| // Set pointer to consume the correct number of bits. |
| updatePointer(7 - bits); |
| } else if (code == 1) { |
| // Horizontal |
| updatePointer(7 - bits); |
| |
| // identify the next 2 codes. |
| int number; |
| if (isWhite) { |
| number = decodeWhiteCodeWord(); |
| bitOffset += number; |
| currChangingElems[currIndex++] = bitOffset; |
| |
| number = decodeBlackCodeWord(); |
| setToBlack(buffer, lineOffset, bitOffset, number); |
| bitOffset += number; |
| currChangingElems[currIndex++] = bitOffset; |
| } else { |
| number = decodeBlackCodeWord(); |
| setToBlack(buffer, lineOffset, bitOffset, number); |
| bitOffset += number; |
| currChangingElems[currIndex++] = bitOffset; |
| |
| number = decodeWhiteCodeWord(); |
| bitOffset += number; |
| currChangingElems[currIndex++] = bitOffset; |
| } |
| |
| a0 = bitOffset; |
| } else if (code <= 8) { |
| // Vertical |
| a1 = b1 + (code - 5); |
| |
| currChangingElems[currIndex++] = a1; |
| |
| // We write the current color till a1 - 1 pos, |
| // since a1 is where the next color starts |
| if (!isWhite) { |
| setToBlack(buffer, lineOffset, bitOffset, |
| a1 - bitOffset); |
| } |
| bitOffset = a0 = a1; |
| isWhite = !isWhite; |
| |
| updatePointer(7 - bits); |
| } else { |
| throw new Error("TIFFFaxDecoder4"); |
| } |
| } |
| |
| // Add the changing element beyond the current scanline for the |
| // other color too |
| currChangingElems[currIndex++] = bitOffset; |
| changingElemSize = currIndex; |
| } else { |
| // 1D encoded scanline follows |
| decodeNextScanline(buffer, lineOffset, startX); |
| } |
| |
| lineOffset += scanlineStride; |
| } |
| } |
| |
| public synchronized void decodeT6(byte[] buffer, |
| byte[] compData, |
| int startX, |
| int height, |
| long tiffT6Options) { |
| this.data = compData; |
| compression = 4; |
| |
| bitPointer = 0; |
| bytePointer = 0; |
| |
| int scanlineStride = (w + 7)/8; |
| |
| int a0, a1, b1, b2; |
| int entry, code, bits; |
| boolean isWhite; |
| int currIndex; |
| int[] temp; |
| |
| // Return values from getNextChangingElement |
| int[] b = new int[2]; |
| |
| // uncompressedMode - have written some code for this, but this |
| // has not been tested due to lack of test images using this optional |
| |
| uncompressedMode = (int)((tiffT6Options & 0x02) >> 1); |
| |
| // Local cached reference |
| int[] cce = currChangingElems; |
| |
| // Assume invisible preceding row of all white pixels and insert |
| // both black and white changing elements beyond the end of this |
| // imaginary scanline. |
| changingElemSize = 0; |
| cce[changingElemSize++] = w; |
| cce[changingElemSize++] = w; |
| |
| int lineOffset = 0; |
| int bitOffset; |
| |
| for (int lines = 0; lines < height; lines++) { |
| // a0 has to be set just before the start of the scanline. |
| a0 = -1; |
| isWhite = true; |
| |
| // Assign the changing elements of the previous scanline to |
| // prevChangingElems and start putting this new scanline's |
| // changing elements into the currChangingElems. |
| temp = prevChangingElems; |
| prevChangingElems = currChangingElems; |
| cce = currChangingElems = temp; |
| currIndex = 0; |
| |
| // Start decoding the scanline at startX in the raster |
| bitOffset = startX; |
| |
| // Reset search start position for getNextChangingElement |
| lastChangingElement = 0; |
| |
| // Till one whole scanline is decoded |
| while (bitOffset < w) { |
| // Get the next changing element |
| getNextChangingElement(a0, isWhite, b); |
| b1 = b[0]; |
| b2 = b[1]; |
| |
| // Get the next seven bits |
| entry = nextLesserThan8Bits(7); |
| // Run these through the 2DCodes table |
| entry = (int)(twoDCodes[entry] & 0xff); |
| |
| // Get the code and the number of bits used up |
| code = (entry & 0x78) >>> 3; |
| bits = entry & 0x07; |
| |
| if (code == 0) { // Pass |
| // We always assume WhiteIsZero format for fax. |
| if (!isWhite) { |
| setToBlack(buffer, lineOffset, bitOffset, |
| b2 - bitOffset); |
| } |
| bitOffset = a0 = b2; |
| |
| // Set pointer to only consume the correct number of bits. |
| updatePointer(7 - bits); |
| } else if (code == 1) { // Horizontal |
| // Set pointer to only consume the correct number of bits. |
| updatePointer(7 - bits); |
| |
| // identify the next 2 alternating color codes. |
| int number; |
| if (isWhite) { |
| // Following are white and black runs |
| number = decodeWhiteCodeWord(); |
| bitOffset += number; |
| cce[currIndex++] = bitOffset; |
| |
| number = decodeBlackCodeWord(); |
| setToBlack(buffer, lineOffset, bitOffset, number); |
| bitOffset += number; |
| cce[currIndex++] = bitOffset; |
| } else { |
| // First a black run and then a white run follows |
| number = decodeBlackCodeWord(); |
| setToBlack(buffer, lineOffset, bitOffset, number); |
| bitOffset += number; |
| cce[currIndex++] = bitOffset; |
| |
| number = decodeWhiteCodeWord(); |
| bitOffset += number; |
| cce[currIndex++] = bitOffset; |
| } |
| |
| a0 = bitOffset; |
| } else if (code <= 8) { // Vertical |
| a1 = b1 + (code - 5); |
| cce[currIndex++] = a1; |
| |
| // We write the current color till a1 - 1 pos, |
| // since a1 is where the next color starts |
| if (!isWhite) { |
| setToBlack(buffer, lineOffset, bitOffset, |
| a1 - bitOffset); |
| } |
| bitOffset = a0 = a1; |
| isWhite = !isWhite; |
| |
| updatePointer(7 - bits); |
| } else if (code == 11) { |
| if (nextLesserThan8Bits(3) != 7) { |
| throw new Error("TIFFFaxDecoder5"); |
| } |
| |
| int zeros = 0; |
| boolean exit = false; |
| |
| while (!exit) { |
| while (nextLesserThan8Bits(1) != 1) { |
| zeros++; |
| } |
| |
| if (zeros > 5) { |
| // Exit code |
| |
| // Zeros before exit code |
| zeros = zeros - 6; |
| |
| if (!isWhite && (zeros > 0)) { |
| cce[currIndex++] = bitOffset; |
| } |
| |
| // Zeros before the exit code |
| bitOffset += zeros; |
| if (zeros > 0) { |
| // Some zeros have been written |
| isWhite = true; |
| } |
| |
| // Read in the bit which specifies the color of |
| // the following run |
| if (nextLesserThan8Bits(1) == 0) { |
| if (!isWhite) { |
| cce[currIndex++] = bitOffset; |
| } |
| isWhite = true; |
| } else { |
| if (isWhite) { |
| cce[currIndex++] = bitOffset; |
| } |
| isWhite = false; |
| } |
| |
| exit = true; |
| } |
| |
| if (zeros == 5) { |
| if (!isWhite) { |
| cce[currIndex++] = bitOffset; |
| } |
| bitOffset += zeros; |
| |
| // Last thing written was white |
| isWhite = true; |
| } else { |
| bitOffset += zeros; |
| |
| cce[currIndex++] = bitOffset; |
| setToBlack(buffer, lineOffset, bitOffset, 1); |
| ++bitOffset; |
| |
| // Last thing written was black |
| isWhite = false; |
| } |
| |
| } |
| } else { |
| throw new Error("TIFFFaxDecoder5"); |
| } |
| } |
| |
| // Add the changing element beyond the current scanline for the |
| // other color too |
| cce[currIndex++] = bitOffset; |
| |
| // Number of changing elements in this scanline. |
| changingElemSize = currIndex; |
| |
| lineOffset += scanlineStride; |
| } |
| } |
| |
| private void setToBlack(byte[] buffer, |
| int lineOffset, int bitOffset, |
| int numBits) { |
| int bitNum = 8*lineOffset + bitOffset; |
| int lastBit = bitNum + numBits; |
| |
| int byteNum = bitNum >> 3; |
| |
| // Handle bits in first byte |
| int shift = bitNum & 0x7; |
| if (shift > 0) { |
| int maskVal = 1 << (7 - shift); |
| byte val = buffer[byteNum]; |
| while (maskVal > 0 && bitNum < lastBit) { |
| val |= maskVal; |
| maskVal >>= 1; |
| ++bitNum; |
| } |
| buffer[byteNum] = val; |
| } |
| |
| // Fill in 8 bits at a time |
| byteNum = bitNum >> 3; |
| while (bitNum < lastBit - 7) { |
| buffer[byteNum++] = (byte)255; |
| bitNum += 8; |
| } |
| |
| // Fill in remaining bits |
| while (bitNum < lastBit) { |
| byteNum = bitNum >> 3; |
| buffer[byteNum] |= 1 << (7 - (bitNum & 0x7)); |
| ++bitNum; |
| } |
| } |
| |
| // Returns run length |
| private int decodeWhiteCodeWord() { |
| int current, entry, bits, isT, twoBits, code = -1; |
| int runLength = 0; |
| boolean isWhite = true; |
| |
| while (isWhite) { |
| current = nextNBits(10); |
| entry = white[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x0f; |
| |
| if (bits == 12) { // Additional Make up code |
| // Get the next 2 bits |
| twoBits = nextLesserThan8Bits(2); |
| // Consolidate the 2 new bits and last 2 bits into 4 bits |
| current = ((current << 2) & 0x000c) | twoBits; |
| entry = additionalMakeup[current]; |
| bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 |
| code = (entry >>> 4) & 0x0fff; // 12 bits |
| runLength += code; |
| updatePointer(4 - bits); |
| } else if (bits == 0) { // ERROR |
| throw new Error("TIFFFaxDecoder0"); |
| } else if (bits == 15) { // EOL |
| throw new Error("TIFFFaxDecoder1"); |
| } else { |
| // 11 bits - 0000 0111 1111 1111 = 0x07ff |
| code = (entry >>> 5) & 0x07ff; |
| runLength += code; |
| updatePointer(10 - bits); |
| if (isT == 0) { |
| isWhite = false; |
| } |
| } |
| } |
| |
| return runLength; |
| } |
| |
| // Returns run length |
| private int decodeBlackCodeWord() { |
| int current, entry, bits, isT, code = -1; |
| int runLength = 0; |
| boolean isWhite = false; |
| |
| while (!isWhite) { |
| current = nextLesserThan8Bits(4); |
| entry = initBlack[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x000f; |
| code = (entry >>> 5) & 0x07ff; |
| |
| if (code == 100) { |
| current = nextNBits(9); |
| entry = black[current]; |
| |
| // Get the 3 fields from the entry |
| isT = entry & 0x0001; |
| bits = (entry >>> 1) & 0x000f; |
| code = (entry >>> 5) & 0x07ff; |
| |
| if (bits == 12) { |
| // Additional makeup codes |
| updatePointer(5); |
| current = nextLesserThan8Bits(4); |
| entry = additionalMakeup[current]; |
| bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 |
| code = (entry >>> 4) & 0x0fff; // 12 bits |
| runLength += code; |
| |
| updatePointer(4 - bits); |
| } else if (bits == 15) { |
| // EOL code |
| throw new Error("TIFFFaxDecoder2"); |
| } else { |
| runLength += code; |
| updatePointer(9 - bits); |
| if (isT == 0) { |
| isWhite = true; |
| } |
| } |
| } else if (code == 200) { |
| // Is a Terminating code |
| current = nextLesserThan8Bits(2); |
| entry = twoBitBlack[current]; |
| code = (entry >>> 5) & 0x07ff; |
| runLength += code; |
| bits = (entry >>> 1) & 0x0f; |
| updatePointer(2 - bits); |
| isWhite = true; |
| } else { |
| // Is a Terminating code |
| runLength += code; |
| updatePointer(4 - bits); |
| isWhite = true; |
| } |
| } |
| |
| return runLength; |
| } |
| |
| private int readEOL() { |
| if (fillBits == 0) { |
| if (nextNBits(12) != 1) { |
| throw new Error("TIFFFaxDecoder6"); |
| } |
| } else if (fillBits == 1) { |
| |
| // First EOL code word xxxx 0000 0000 0001 will occur |
| // As many fill bits will be present as required to make |
| // the EOL code of 12 bits end on a byte boundary. |
| |
| int bitsLeft = 8 - bitPointer; |
| |
| if (nextNBits(bitsLeft) != 0) { |
| throw new Error("TIFFFaxDecoder8"); |
| } |
| |
| // If the number of bitsLeft is less than 8, then to have a 12 |
| // bit EOL sequence, two more bytes are certainly going to be |
| // required. The first of them has to be all zeros, so ensure |
| // that. |
| if (bitsLeft < 4) { |
| if (nextNBits(8) != 0) { |
| throw new Error("TIFFFaxDecoder8"); |
| } |
| } |
| |
| // There might be a random number of fill bytes with 0s, so |
| // loop till the EOL of 0000 0001 is found, as long as all |
| // the bytes preceding it are 0's. |
| int n; |
| while ((n = nextNBits(8)) != 1) { |
| |
| // If not all zeros |
| if (n != 0) { |
| throw new Error("TIFFFaxDecoder8"); |
| } |
| } |
| } |
| |
| // If one dimensional encoding mode, then always return 1 |
| if (oneD == 0) { |
| return 1; |
| } else { |
| // Otherwise for 2D encoding mode, |
| // The next one bit signifies 1D/2D encoding of next line. |
| return nextLesserThan8Bits(1); |
| } |
| } |
| |
| private void getNextChangingElement(int a0, boolean isWhite, int[] ret) { |
| // Local copies of instance variables |
| int[] pce = this.prevChangingElems; |
| int ces = this.changingElemSize; |
| |
| // If the previous match was at an odd element, we still |
| // have to search the preceeding element. |
| // int start = lastChangingElement & ~0x1; |
| int start = lastChangingElement > 0 ? lastChangingElement - 1 : 0; |
| if (isWhite) { |
| start &= ~0x1; // Search even numbered elements |
| } else { |
| start |= 0x1; // Search odd numbered elements |
| } |
| |
| int i = start; |
| for (; i < ces; i += 2) { |
| int temp = pce[i]; |
| if (temp > a0) { |
| lastChangingElement = i; |
| ret[0] = temp; |
| break; |
| } |
| } |
| |
| if (i + 1 < ces) { |
| ret[1] = pce[i + 1]; |
| } |
| } |
| |
| private int nextNBits(int bitsToGet) { |
| byte b, next, next2next; |
| int l = data.length - 1; |
| int bp = this.bytePointer; |
| |
| if (fillOrder == 1) { |
| b = data[bp]; |
| |
| if (bp == l) { |
| next = 0x00; |
| next2next = 0x00; |
| } else if ((bp + 1) == l) { |
| next = data[bp + 1]; |
| next2next = 0x00; |
| } else { |
| next = data[bp + 1]; |
| next2next = data[bp + 2]; |
| } |
| } else if (fillOrder == 2) { |
| b = flipTable[data[bp] & 0xff]; |
| |
| if (bp == l) { |
| next = 0x00; |
| next2next = 0x00; |
| } else if ((bp + 1) == l) { |
| next = flipTable[data[bp + 1] & 0xff]; |
| next2next = 0x00; |
| } else { |
| next = flipTable[data[bp + 1] & 0xff]; |
| next2next = flipTable[data[bp + 2] & 0xff]; |
| } |
| } else { |
| throw new Error("TIFFFaxDecoder7"); |
| } |
| |
| int bitsLeft = 8 - bitPointer; |
| int bitsFromNextByte = bitsToGet - bitsLeft; |
| int bitsFromNext2NextByte = 0; |
| if (bitsFromNextByte > 8) { |
| bitsFromNext2NextByte = bitsFromNextByte - 8; |
| bitsFromNextByte = 8; |
| } |
| |
| bytePointer++; |
| |
| int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft); |
| int i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); |
| |
| int i3 = 0; |
| if (bitsFromNext2NextByte != 0) { |
| i2 <<= bitsFromNext2NextByte; |
| i3 = (next2next & table2[bitsFromNext2NextByte]) >>> |
| (8 - bitsFromNext2NextByte); |
| i2 |= i3; |
| bytePointer++; |
| bitPointer = bitsFromNext2NextByte; |
| } else { |
| if (bitsFromNextByte == 8) { |
| bitPointer = 0; |
| bytePointer++; |
| } else { |
| bitPointer = bitsFromNextByte; |
| } |
| } |
| |
| int i = i1 | i2; |
| return i; |
| } |
| |
| private int nextLesserThan8Bits(int bitsToGet) { |
| byte b, next; |
| int l = data.length - 1; |
| int bp = this.bytePointer; |
| |
| if (fillOrder == 1) { |
| b = data[bp]; |
| if (bp == l) { |
| next = 0x00; |
| } else { |
| next = data[bp + 1]; |
| } |
| } else if (fillOrder == 2) { |
| b = flipTable[data[bp] & 0xff]; |
| if (bp == l) { |
| next = 0x00; |
| } else { |
| next = flipTable[data[bp + 1] & 0xff]; |
| } |
| } else { |
| throw new Error("TIFFFaxDecoder7"); |
| } |
| |
| int bitsLeft = 8 - bitPointer; |
| int bitsFromNextByte = bitsToGet - bitsLeft; |
| |
| int shift = bitsLeft - bitsToGet; |
| int i1, i2; |
| if (shift >= 0) { |
| i1 = (b & table1[bitsLeft]) >>> shift; |
| bitPointer += bitsToGet; |
| if (bitPointer == 8) { |
| bitPointer = 0; |
| bytePointer++; |
| } |
| } else { |
| i1 = (b & table1[bitsLeft]) << (-shift); |
| i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); |
| |
| i1 |= i2; |
| bytePointer++; |
| bitPointer = bitsFromNextByte; |
| } |
| |
| return i1; |
| } |
| |
| // Move pointer backwards by given amount of bits |
| private void updatePointer(int bitsToMoveBack) { |
| int i = bitPointer - bitsToMoveBack; |
| |
| if (i < 0) { |
| bytePointer--; |
| bitPointer = 8 + i; |
| } else { |
| bitPointer = i; |
| } |
| } |
| |
| // Move to the next byte boundary |
| private boolean advancePointer() { |
| if (bitPointer != 0) { |
| bytePointer++; |
| bitPointer = 0; |
| } |
| |
| return true; |
| } |
| } |
| |