in src/main/java/org/apache/pdfbox/jbig2/segments/GenericRefinementRegion.java [543:682]
private void decodeTypicalPredictedLineTemplate0(final int lineNumber, final int width,
final int rowStride, final int refRowStride, final int paddedWidth,
final int deltaRefStride, int byteIndex, final int currentLine, int refByteIndex)
throws IOException
{
int context;
int overriddenContext;
int previousLine;
int previousReferenceLine;
int currentReferenceLine;
int nextReferenceLine;
if (lineNumber > 0)
{
previousLine = regionBitmap.getByteAsInteger(byteIndex - rowStride);
}
else
{
previousLine = 0;
}
if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
{
previousReferenceLine = referenceBitmap
.getByteAsInteger(refByteIndex - refRowStride + deltaRefStride) << 4;
}
else
{
previousReferenceLine = 0;
}
if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
{
currentReferenceLine = referenceBitmap
.getByteAsInteger(refByteIndex + deltaRefStride) << 1;
}
else
{
currentReferenceLine = 0;
}
if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1))
{
nextReferenceLine = referenceBitmap
.getByteAsInteger(refByteIndex + refRowStride + deltaRefStride);
}
else
{
nextReferenceLine = 0;
}
context = ((previousLine >> 5) & 0x6) | ((nextReferenceLine >> 2) & 0x30)
| (currentReferenceLine & 0x180) | (previousReferenceLine & 0xc00);
int nextByte;
for (int x = 0; x < paddedWidth; x = nextByte)
{
byte result = 0;
nextByte = x + 8;
final int minorWidth = width - x > 8 ? 8 : width - x;
final boolean readNextByte = nextByte < width;
final boolean refReadNextByte = nextByte < referenceBitmap.getWidth();
final int yOffset = deltaRefStride + 1;
if (lineNumber > 0)
{
previousLine = (previousLine << 8) | (readNextByte
? regionBitmap.getByteAsInteger(byteIndex - rowStride + 1) : 0);
}
if (currentLine > 0 && currentLine <= referenceBitmap.getHeight())
{
previousReferenceLine = (previousReferenceLine << 8)
| (refReadNextByte ? referenceBitmap
.getByteAsInteger(refByteIndex - refRowStride + yOffset) << 4 : 0);
}
if (currentLine >= 0 && currentLine < referenceBitmap.getHeight())
{
currentReferenceLine = (currentReferenceLine << 8) | (refReadNextByte
? referenceBitmap.getByteAsInteger(refByteIndex + yOffset) << 1 : 0);
}
if (currentLine > -2 && currentLine < (referenceBitmap.getHeight() - 1))
{
nextReferenceLine = (nextReferenceLine << 8) | (refReadNextByte
? referenceBitmap.getByteAsInteger(refByteIndex + refRowStride + yOffset)
: 0);
}
for (int minorX = 0; minorX < minorWidth; minorX++)
{
boolean isPixelTypicalPredicted = false;
int bit = 0;
// i)
final int bitmapValue = (context >> 4) & 0x1FF;
if (bitmapValue == 0x1ff)
{
isPixelTypicalPredicted = true;
bit = 1;
}
else if (bitmapValue == 0x00)
{
isPixelTypicalPredicted = true;
bit = 0;
}
if (!isPixelTypicalPredicted)
{
// iii) - is like 3 c) but for one pixel only
if (override)
{
overriddenContext = overrideAtTemplate0(context, x + minorX, lineNumber,
result, minorX);
cx.setIndex(overriddenContext);
}
else
{
cx.setIndex(context);
}
bit = arithDecoder.decode(cx);
}
final int toShift = 7 - minorX;
result |= bit << toShift;
context = ((context & 0xdb6) << 1) | bit | ((previousLine >> toShift + 5) & 0x002)
| ((nextReferenceLine >> toShift + 2) & 0x010)
| ((currentReferenceLine >> toShift) & 0x080)
| ((previousReferenceLine >> toShift) & 0x400);
}
regionBitmap.setByte(byteIndex++, result);
refByteIndex++;
}
}