for (int y = 0; y < height; y++) {
for (int i = 0; i < width; i++) {
try {
codingLine[i] = inputStream.readBits(1);
} catch (final IOException ioException) {
throw new ImageWriteException("Error reading image to compress", ioException);
}
}
int codingA0Color = WHITE;
int referenceA0Color = WHITE;
int a1 = nextChangingElement(codingLine, codingA0Color, 0);
int b1 = nextChangingElement(referenceLine, referenceA0Color, 0);
int b2 = nextChangingElement(referenceLine, 1 - referenceA0Color, b1 + 1);
for (int a0 = 0; a0 < width;) {
if (b2 < a1) {
T4_T6_Tables.P.writeBits(outputStream);
a0 = b2;
} else {
final int a1b1 = a1 - b1;
if (-3 <= a1b1 && a1b1 <= 3) {
T4_T6_Tables.Entry entry;
if (a1b1 == -3) {
entry = T4_T6_Tables.VL3;
} else if (a1b1 == -2) {
entry = T4_T6_Tables.VL2;
} else if (a1b1 == -1) {
entry = T4_T6_Tables.VL1;
} else if (a1b1 == 0) {
entry = T4_T6_Tables.V0;
} else if (a1b1 == 1) {
entry = T4_T6_Tables.VR1;
} else if (a1b1 == 2) {
entry = T4_T6_Tables.VR2;
} else {
entry = T4_T6_Tables.VR3;
}
entry.writeBits(outputStream);
codingA0Color = 1 - codingA0Color;
a0 = a1;
} else {
final int a2 = nextChangingElement(codingLine, 1 - codingA0Color, a1 + 1);
final int a0a1 = a1 - a0;
final int a1a2 = a2 - a1;
T4_T6_Tables.H.writeBits(outputStream);
writeRunLength(outputStream, a0a1, codingA0Color);
writeRunLength(outputStream, a1a2, 1 - codingA0Color);
a0 = a2;
}
}
referenceA0Color = changingElementAt(referenceLine, a0);
a1 = nextChangingElement(codingLine, codingA0Color, a0 + 1);
if (codingA0Color == referenceA0Color) {
b1 = nextChangingElement(referenceLine, referenceA0Color, a0 + 1);
} else {
b1 = nextChangingElement(referenceLine, referenceA0Color, a0 + 1);
b1 = nextChangingElement(referenceLine, 1 - referenceA0Color, b1 + 1);
}
b2 = nextChangingElement(referenceLine, 1 - codingA0Color, b1 + 1);
}
final int[] swap = referenceLine;
referenceLine = codingLine;
codingLine = swap;
inputStream.flushCache();
}
// EOFB
T4_T6_Tables.EOL.writeBits(outputStream);
T4_T6_Tables.EOL.writeBits(outputStream);
final byte[] ret = outputStream.toByteArray();
canThrow = true;
return ret;
} finally {
try {
IoUtils.closeQuietly(canThrow, inputStream);
} catch (final IOException ioException) {
throw new ImageWriteException("I/O error", ioException);
}
}
}