decode2D method
Implementation
void decode2D(InputBuffer out, InputBuffer compData, int startX, int height,
int tiffT4Options) {
data = compData;
compression = 3;
bitPointer = 0;
bytePointer = 0;
final scanlineStride = (width + 7) ~/ 8;
int? a0, a1, b1, b2;
final b = List<int?>.filled(2, null);
int entry, code, bits;
bool isWhite;
var currIndex = 0;
List<int?>? temp;
// fillBits - dealt with this in readEOL
// 1D/2D encoding - dealt with this in readEOL
// uncompressedMode - haven't dealt with this yet.
oneD = (tiffT4Options & 0x01);
uncompressedMode = ((tiffT4Options & 0x02) >> 1);
fillBits = ((tiffT4Options & 0x04) >> 2);
// The data must start with an EOL code
if (_readEOL() != 1) {
throw ImageException('TIFFFaxDecoder3');
}
var lineOffset = 0;
int? bitOffset;
// Then the 1D encoded scanline data will occur, changing elements
// array gets set.
_decodeNextScanline(out, lineOffset, startX);
lineOffset += scanlineStride;
for (var 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! < width) {
// 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 = (TWO_D_CODES[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(out, 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(out, lineOffset, bitOffset, number);
bitOffset += number;
currChangingElems![currIndex++] = bitOffset;
} else {
number = _decodeBlackCodeWord();
_setToBlack(out, 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(out, lineOffset, bitOffset, a1 - bitOffset);
}
bitOffset = a0 = a1;
isWhite = !isWhite;
_updatePointer(7 - bits);
} else {
throw ImageException('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(out, lineOffset, startX);
}
lineOffset += scanlineStride;
}
}