{
ArrayList<byte[]> codeTable = createCodeTable();
int chunk = 9;
byte[] inputPattern = null;
MemoryCacheImageOutputStream out = new MemoryCacheImageOutputStream(result);
out.writeBits(CLEAR_TABLE, chunk);
int foundCode = -1;
int r;
while ((r = rawData.read()) != -1)
{
byte by = (byte) r;
if (inputPattern == null)
{
inputPattern = new byte[]
{
by
};
foundCode = by & 0xff;
}
else
{
byte[] inputPatternCopy = new byte[inputPattern.length + 1];
for (int i = 0; i < inputPattern.length; ++i)
inputPatternCopy[i] = inputPattern[i];
inputPattern = inputPatternCopy;
inputPattern[inputPattern.length - 1] = by;
int newFoundCode = findPatternCode(codeTable, inputPattern);
if (newFoundCode == -1)
{
// use previous
chunk = calculateChunk(codeTable.size() - 1);
out.writeBits(foundCode, chunk);
// create new table entry
codeTable.add(inputPattern);
if (codeTable.size() == 4096)
{
// code table is full
out.writeBits(CLEAR_TABLE, chunk);
chunk = 9;
codeTable = createCodeTable();
}
inputPattern = new byte[]
{
by
};
foundCode = by & 0xff;
}
else
{
foundCode = newFoundCode;
}
}
}
if (foundCode != -1)
{
chunk = calculateChunk(codeTable.size() - 1);
out.writeBits(foundCode, chunk);
}
// PPDFBOX-1977: the decoder wouldn't know that the encoder would output
// an EOD as code, so he would have increased his own code table and
// possibly adjusted the chunk. Therefore, the encoder must behave as
// if the code table had just grown and thus it must be checked it is
// needed to adjust the chunk, based on an increased table size parameter
chunk = calculateChunk(codeTable.size());
out.writeBits(EOD, chunk);
out.writeBits(0, 7); // pad with 0
out.flush(); // must do or file will be empty :-(
}