1 11 package org.eclipse.swt.internal.image; 12 13 import org.eclipse.swt.*; 14 15 22 final class TIFFModifiedHuffmanCodec { 23 static final short[][][] BLACK_CODE = { 24 25 {{2, 3}, {3, 2}}, 26 27 {{2, 1}, {3, 4}}, 28 29 {{2, 6}, {3, 5}}, 30 31 {{3, 7}}, 32 33 {{4, 9}, {5, 8}}, 34 35 {{4, 10}, {5, 11}, {7, 12}}, 36 37 {{4, 13}, {7, 14}}, 38 39 {{24, 15}}, 40 41 {{8, 18}, {15, 64}, {23, 16}, {24, 17}, {55, 0}}, 42 43 {{0, -1}, {8, 1792}, {23, 24}, {24, 25}, {40, 23}, {55, 22}, {103, 19}, 44 {104, 20}, {108, 21}, {12, 1856}, {13, 1920}}, 45 46 {{18, 1984}, {19, 2048}, {20, 2112}, {21, 2176}, {22, 2240}, {23, 2304}, 47 {28, 2368}, {29, 2432}, {30, 2496}, {31, 2560}, {36, 52}, {39, 55}, {40, 56}, 48 {43, 59}, {44, 60}, {51, 320}, {52, 384}, {53, 448}, {55, 53}, {56, 54}, {82, 50}, 49 {83, 51}, {84, 44}, {85, 45}, {86, 46}, {87, 47}, {88, 57}, {89, 58}, {90, 61}, 50 {91, 256}, {100, 48}, {101, 49}, {102, 62}, {103, 63}, {104, 30}, {105, 31}, 51 {106, 32}, {107, 33}, {108, 40}, {109, 41}, {200, 128}, {201, 192}, {202, 26}, 52 {203, 27}, {204, 28}, {205, 29}, {210, 34}, {211, 35}, {212, 36}, {213, 37}, 53 {214, 38}, {215, 39}, {218, 42}, {219, 43}}, 54 55 {{74, 640}, {75, 704}, {76, 768}, {77, 832}, {82, 1280}, {83, 1344}, {84, 1408}, 56 {85, 1472}, {90, 1536}, {91, 1600}, {100, 1664}, {101, 1728}, {108, 512}, 57 {109, 576}, {114, 896}, {115, 960}, {116, 1024}, {117, 1088}, {118, 1152}, 58 {119, 1216}} 59 }; 60 61 static final short[][][] WHITE_CODE = { 62 63 {{7, 2}, {8, 3}, {11, 4}, {12, 5}, {14, 6}, {15, 7}}, 64 65 {{7, 10}, {8, 11}, {18, 128}, {19, 8}, {20, 9}, {27, 64}}, 66 67 {{3, 13}, {7, 1}, {8, 12}, {23, 192}, {24, 1664}, {42, 16}, {43, 17}, {52, 14}, 68 {53, 15}}, 69 70 {{3, 22}, {4, 23}, {8, 20}, {12, 19}, {19, 26}, {23, 21}, {24, 28}, {36, 27}, 71 {39, 18}, {40, 24}, {43, 25}, {55, 256}}, 72 73 {{2, 29}, {3, 30}, {4, 45}, {5, 46}, {10, 47}, {11, 48}, {18, 33}, {19, 34}, 74 {20, 35}, {21, 36}, {22, 37}, {23, 38}, {26, 31}, {27, 32}, {36, 53}, {37, 54}, 75 {40, 39}, {41, 40}, {42, 41}, {43, 42}, {44, 43}, {45, 44}, {50, 61}, {51, 62}, 76 {52, 63}, {53, 0}, {54, 320}, {55, 384}, {74, 59}, {75, 60}, {82, 49}, {83, 50}, 77 {84, 51}, {85, 52}, {88, 55}, {89, 56}, {90, 57}, {91, 58}, {100, 448}, 78 {101, 512}, {103, 640}, {104, 576}}, 79 80 {{152, 1472}, {153, 1536}, {154, 1600}, {155, 1728}, {204, 704}, {205, 768}, 81 {210, 832}, {211, 896}, {212, 960}, {213, 1024}, {214, 1088}, {215, 1152}, 82 {216, 1216}, {217, 1280}, {218, 1344}, {219, 1408}}, 83 84 {}, 85 86 {{8, 1792}, {12, 1856}, {13, 1920}}, 87 88 {{1, -1}, {18, 1984}, {19, 2048}, {20, 2112}, {21, 2176}, {22, 2240}, {23, 2304}, 89 {28, 2368}, {29, 2432}, {30, 2496}, {31, 2560}} 90 }; 91 92 static final int BLACK_MIN_BITS = 2; 93 static final int WHITE_MIN_BITS = 4; 94 95 boolean isWhite; 96 int whiteValue = 0; 97 int blackValue = 1; 98 byte[] src; 99 byte[] dest; 100 int byteOffsetSrc = 0; 101 int bitOffsetSrc = 0; 102 int byteOffsetDest = 0; 103 int bitOffsetDest = 0; 104 int code = 0; 105 int nbrBits = 0; 106 107 int rowSize; 108 109 public int decode(byte[] src, byte[] dest, int offsetDest, int rowSize, int nRows) { 110 this.src = src; 111 this.dest = dest; 112 this.rowSize = rowSize; 113 byteOffsetSrc = 0; 114 bitOffsetSrc = 0; 115 byteOffsetDest = offsetDest; 116 bitOffsetDest = 0; 117 int cnt = 0; 118 while (cnt < nRows && decodeRow()) { 119 cnt++; 120 121 if (bitOffsetDest > 0) { 122 byteOffsetDest++; 123 bitOffsetDest = 0; 124 } 125 } 126 return byteOffsetDest - offsetDest; 127 } 128 129 boolean decodeRow() { 130 isWhite = true; 131 int n = 0; 132 while (n < rowSize) { 133 int runLength = decodeRunLength(); 134 if (runLength < 0) return false; 135 n += runLength; 136 setNextBits(isWhite ? whiteValue : blackValue, runLength); 137 isWhite = !isWhite; 138 } 139 return true; 140 } 141 142 int decodeRunLength() { 143 int runLength = 0; 144 int partialRun = 0; 145 short[][][] huffmanCode = isWhite ? WHITE_CODE : BLACK_CODE; 146 while (true) { 147 boolean found = false; 148 nbrBits = isWhite ? WHITE_MIN_BITS : BLACK_MIN_BITS; 149 code = getNextBits(nbrBits); 150 for (int i = 0; i < huffmanCode.length; i++) { 151 for (int j = 0; j < huffmanCode[i].length; j++) { 152 if (huffmanCode[i][j][0] == code) { 153 found = true; 154 partialRun = huffmanCode[i][j][1]; 155 if (partialRun == -1) { 156 157 if (byteOffsetSrc == src.length - 1) return -1; 158 159 } else { 160 runLength += partialRun; 161 if (partialRun < 64) return runLength; 162 } 163 break; 164 } 165 } 166 if (found) break; 167 code = code << 1 | getNextBit(); 168 } 169 if (!found) SWT.error(SWT.ERROR_INVALID_IMAGE); 170 } 171 } 172 173 int getNextBit() { 174 int value = (src[byteOffsetSrc] >>> (7 - bitOffsetSrc)) & 0x1; 175 bitOffsetSrc++; 176 if (bitOffsetSrc > 7) { 177 byteOffsetSrc++; 178 bitOffsetSrc = 0; 179 } 180 return value; 181 } 182 183 int getNextBits(int cnt) { 184 int value = 0; 185 for (int i = 0; i < cnt; i++) { 186 value = value << 1 | getNextBit(); 187 } 188 return value; 189 } 190 191 void setNextBits(int value, int cnt) { 192 int n = cnt; 193 while (bitOffsetDest > 0 && bitOffsetDest <= 7 && n > 0) { 194 dest[byteOffsetDest] = value == 1 ? 195 (byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) : 196 (byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest))); 197 n--; 198 bitOffsetDest++; 199 } 200 if (bitOffsetDest == 8) { 201 byteOffsetDest++; 202 bitOffsetDest = 0; 203 } 204 while (n >= 8) { 205 dest[byteOffsetDest++] = (byte) (value == 1 ? 0xFF : 0); 206 n -= 8; 207 } 208 while (n > 0) { 209 dest[byteOffsetDest] = value == 1 ? 210 (byte)(dest[byteOffsetDest] | (1 << (7 - bitOffsetDest))) : 211 (byte)(dest[byteOffsetDest] & ~(1 << (7 - bitOffsetDest))); 212 n--; 213 bitOffsetDest++; 214 } 215 } 216 217 } 218 | Popular Tags |