public int readBits(final int count) throws IOException {
        if (count < 8) {
            if (cacheBitsRemaining == 0) {
                // fill cache
                cache = in.read();
                cacheBitsRemaining = 8;
                bytesRead++;
            }
            if (count > cacheBitsRemaining) {
                throw new ImagingException("BitInputStream: can't read bit fields across bytes");
            }

            // int bits_to_shift = cache_bits_remaining - count;
            cacheBitsRemaining -= count;
            final int bits = cache >> cacheBitsRemaining;

            switch (count) {
            case 1:
                return bits & 1;
            case 2:
                return bits & 3;
            case 3:
                return bits & 7;
            case 4:
                return bits & 15;
            case 5:
                return bits & 31;
            case 6:
                return bits & 63;
            case 7:
                return bits & 127;
            }

        }
        if (cacheBitsRemaining > 0) {
            throw new ImagingException("BitInputStream: incomplete bit read");
        }

        if (count == 8) {
            bytesRead++;
            return in.read();
        }

        /**
         * Taking default order of the TIFF to be Little Endian and reversing the bytes in the end if its Big Endian.This is done because majority (may be all)
         * of the files will be of Little Endian.
         */
        if (byteOrder == ByteOrder.BIG_ENDIAN) {
            switch (count) {
            case 16:
                bytesRead += 2;
                return in.read() << 8 | in.read() << 0;
            case 24:
                bytesRead += 3;
                return in.read() << 16 | in.read() << 8 | in.read() << 0;
            case 32:
                bytesRead += 4;
                return in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read() << 0;
            default:
                break;
            }
        } else {
            switch (count) {
            case 16:
                bytesRead += 2;
                return in.read() << 0 | in.read() << 8;
            case 24:
                bytesRead += 3;
                return in.read() << 0 | in.read() << 8 | in.read() << 16;
            case 32:
                bytesRead += 4;
                return in.read() << 0 | in.read() << 8 | in.read() << 16 | in.read() << 24;
            default:
                break;
            }
        }

        throw new ImagingException("BitInputStream: unknown error");
    }
Input stream reading 1-8, 16, 24 or 32 bits, starting from the most significant bit, but incapable of reading non-aligned and < 8 bit fields across byte
boundaries.
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/BitInputStream.java