private ImageDescriptor readImageDescriptor(final GifHeaderInfo ghi, final int blockCode, final InputStream is, final boolean stopBeforeImageData,
            final FormatCompliance formatCompliance) throws ImagingException, IOException {
        final int imageLeftPosition = BinaryFunctions.read2Bytes("Image Left Position", is, "Not a Valid GIF File", getByteOrder());
        final int imageTopPosition = BinaryFunctions.read2Bytes("Image Top Position", is, "Not a Valid GIF File", getByteOrder());
        final int imageWidth = BinaryFunctions.read2Bytes("Image Width", is, "Not a Valid GIF File", getByteOrder());
        final int imageHeight = BinaryFunctions.read2Bytes("Image Height", is, "Not a Valid GIF File", getByteOrder());
        final byte packedFields = BinaryFunctions.readByte("Packed Fields", is, "Not a Valid GIF File");

        if (formatCompliance != null) {
            formatCompliance.checkBounds("Width", 1, ghi.logicalScreenWidth, imageWidth);
            formatCompliance.checkBounds("Height", 1, ghi.logicalScreenHeight, imageHeight);
            formatCompliance.checkBounds("Left Position", 0, ghi.logicalScreenWidth - imageWidth, imageLeftPosition);
            formatCompliance.checkBounds("Top Position", 0, ghi.logicalScreenHeight - imageHeight, imageTopPosition);
        }

        if (LOGGER.isLoggable(Level.FINEST)) {
            BinaryFunctions.logByteBits("PackedFields bits", packedFields);
        }

        final boolean localColorTableFlag = (packedFields >> 7 & 1) > 0;
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("LocalColorTableFlag: " + localColorTableFlag);
        }
        final boolean interlaceFlag = (packedFields >> 6 & 1) > 0;
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("Interlace Flag: " + interlaceFlag);
        }
        final boolean sortFlag = (packedFields >> 5 & 1) > 0;
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("Sort Flag: " + sortFlag);
        }

        final byte sizeOfLocalColorTable = (byte) (packedFields & 7);
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("SizeofLocalColorTable: " + sizeOfLocalColorTable);
        }

        byte[] localColorTable = null;
        if (localColorTableFlag) {
            localColorTable = readColorTable(is, sizeOfLocalColorTable);
        }

        byte[] imageData = null;
        if (!stopBeforeImageData) {
            final int lzwMinimumCodeSize = is.read();

            final GenericGifBlock block = readGenericGifBlock(is, -1);
            final byte[] bytes = block.appendSubBlocks();
            final InputStream bais = new ByteArrayInputStream(bytes);

            final int size = imageWidth * imageHeight;
            final MyLzwDecompressor myLzwDecompressor = new MyLzwDecompressor(lzwMinimumCodeSize, ByteOrder.LITTLE_ENDIAN, false);
            imageData = myLzwDecompressor.decompress(bais, size);
        } else {
            final int LZWMinimumCodeSize = is.read();
            if (LOGGER.isLoggable(Level.FINEST)) {
                LOGGER.finest("LZWMinimumCodeSize: " + LZWMinimumCodeSize);
            }

            readGenericGifBlock(is, -1);
        }

        return new ImageDescriptor(blockCode, imageLeftPosition, imageTopPosition, imageWidth, imageHeight, packedFields, localColorTableFlag, interlaceFlag,
                sortFlag, sizeOfLocalColorTable, localColorTable, imageData);
    }
Extracts embedded XML metadata as XML string.
<p>

@param byteSource File containing image data.
@param params     Map of optional parameters, defined in ImagingConstants.
@return Xmp Xml as String, if present. Otherwise, returns null.
src/main/java/org/apache/commons/imaging/formats/gif/GifImageParser.java