📄 tifffaxdecoder.java
字号:
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 RuntimeException("Invalid code encountered."); } else if (bits == 15) { // EOL throw new RuntimeException("EOL code word encountered in White run."); } 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 RuntimeException("EOL code word encountered in Black run."); } 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(boolean isFirstEOL) { if (fillBits == 0) { int next12Bits = nextNBits(12); if (isFirstEOL && next12Bits == 0) { // Might have the case of EOL padding being used even // though it was not flagged in the T4Options field. // This was observed to be the case in TIFFs produced // by a well known vendor who shall remain nameless. if(nextNBits(4) == 1) { // EOL must be padded: reset the fillBits flag. fillBits = 1; return 1; } } if(next12Bits != 1) { throw new RuntimeException("Scanline must begin with EOL code word."); } } 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 RuntimeException("All fill bits preceding EOL code must be 0."); } // 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 RuntimeException("All fill bits preceding EOL code must be 0."); } } // 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 RuntimeException("All fill bits preceding EOL code must be 0."); } } } // 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 RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2."); } 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 RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2."); } 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -