public static byte[] decompressT6(final byte[] compressed, final int width, final int height) throws ImagingException {
        try (BitInputStreamFlexible inputStream = new BitInputStreamFlexible(new ByteArrayInputStream(compressed));
                BitArrayOutputStream outputStream = new BitArrayOutputStream()) {
            final int[] referenceLine = Allocator.intArray(width);
            for (int y = 0; y < height; y++) {
                int rowLength = 0;
                int codingA0Color = WHITE;
                int referenceA0Color = WHITE;
                int b1 = nextChangingElement(referenceLine, referenceA0Color, 0);
                int b2 = nextChangingElement(referenceLine, 1 - referenceA0Color, b1 + 1);
                for (int a0 = 0; a0 < width;) {
                    final int a1;
                    final int a2;
                    final T4_T6_Tables.Entry entry = CONTROL_CODES.decode(inputStream);
                    if (entry == T4_T6_Tables.P) {
                        fillRange(outputStream, referenceLine, a0, b2, codingA0Color);
                        a0 = b2;
                    } else if (entry == T4_T6_Tables.H) {
                        final int a0a1 = readTotalRunLength(inputStream, codingA0Color);
                        a1 = a0 + a0a1;
                        fillRange(outputStream, referenceLine, a0, a1, codingA0Color);
                        final int a1a2 = readTotalRunLength(inputStream, 1 - codingA0Color);
                        a2 = a1 + a1a2;
                        fillRange(outputStream, referenceLine, a1, a2, 1 - codingA0Color);
                        a0 = a2;
                    } else {
                        final int a1b1;
                        if (entry == T4_T6_Tables.V0) {
                            a1b1 = 0;
                        } else if (entry == T4_T6_Tables.VL1) {
                            a1b1 = -1;
                        } else if (entry == T4_T6_Tables.VL2) {
                            a1b1 = -2;
                        } else if (entry == T4_T6_Tables.VL3) {
                            a1b1 = -3;
                        } else if (entry == T4_T6_Tables.VR1) {
                            a1b1 = 1;
                        } else if (entry == T4_T6_Tables.VR2) {
                            a1b1 = 2;
                        } else if (entry == T4_T6_Tables.VR3) {
                            a1b1 = 3;
                        } else {
                            throw new ImagingException("Invalid/unknown T.6 control code " + entry.bitString);
                        }
                        a1 = b1 + a1b1;
                        fillRange(outputStream, referenceLine, a0, a1, codingA0Color);
                        a0 = a1;
                        codingA0Color = 1 - codingA0Color;
                    }
                    referenceA0Color = changingElementAt(referenceLine, a0);
                    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);
                    rowLength = a0;
                }
                if (rowLength == width) {
                    outputStream.flush();
                } else if (rowLength > width) {
                    throw new ImagingException("Unrecoverable row length error in image row " + y);
                }
            }
            return outputStream.toByteArray();
        } catch (final IOException e) {
            if (e instanceof ImagingException) {
                throw (ImagingException) e;
            }
            // IOException cannot happen because the close() methods in use here do not throw
            throw new ImagingException("Closing stream", e);
        }
    }
Decompress T.6 encoded data. No EOLs, except for 2 consecutive ones at the end (the EOFB, end of fax block). No RTC. No fill bits anywhere. All data is
2D encoded.

@param compressed compressed byte data
@param width      image width
@param height     image height
@return the decompressed data
@throws ImagingException if it fails to read the compressed data
src/main/java/org/apache/commons/imaging/formats/tiff/itu_t4/T4AndT6Compression.java