private GifHeaderInfo readHeader(final InputStream is, final FormatCompliance formatCompliance) throws ImagingException, IOException {
        final byte identifier1 = BinaryFunctions.readByte("identifier1", is, "Not a Valid GIF File");
        final byte identifier2 = BinaryFunctions.readByte("identifier2", is, "Not a Valid GIF File");
        final byte identifier3 = BinaryFunctions.readByte("identifier3", is, "Not a Valid GIF File");

        final byte version1 = BinaryFunctions.readByte("version1", is, "Not a Valid GIF File");
        final byte version2 = BinaryFunctions.readByte("version2", is, "Not a Valid GIF File");
        final byte version3 = BinaryFunctions.readByte("version3", is, "Not a Valid GIF File");

        if (formatCompliance != null) {
            formatCompliance.compareBytes("Signature", GIF_HEADER_SIGNATURE, new byte[] { identifier1, identifier2, identifier3 });
            formatCompliance.compare("version", 56, version1);
            formatCompliance.compare("version", new int[] { 55, 57, }, version2);
            formatCompliance.compare("version", 97, version3);
        }

        if (LOGGER.isLoggable(Level.FINEST)) {
            BinaryFunctions.logCharQuad("identifier: ", identifier1 << 16 | identifier2 << 8 | identifier3 << 0);
            BinaryFunctions.logCharQuad("version: ", version1 << 16 | version2 << 8 | version3 << 0);
        }

        final int logicalScreenWidth = BinaryFunctions.read2Bytes("Logical Screen Width", is, "Not a Valid GIF File", getByteOrder());
        final int logicalScreenHeight = BinaryFunctions.read2Bytes("Logical Screen Height", is, "Not a Valid GIF File", getByteOrder());

        if (formatCompliance != null) {
            formatCompliance.checkBounds("Width", 1, Integer.MAX_VALUE, logicalScreenWidth);
            formatCompliance.checkBounds("Height", 1, Integer.MAX_VALUE, logicalScreenHeight);
        }

        final byte packedFields = BinaryFunctions.readByte("Packed Fields", is, "Not a Valid GIF File");
        final byte backgroundColorIndex = BinaryFunctions.readByte("Background Color Index", is, "Not a Valid GIF File");
        final byte pixelAspectRatio = BinaryFunctions.readByte("Pixel Aspect Ratio", is, "Not a Valid GIF File");

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

        final boolean globalColorTableFlag = (packedFields & 128) > 0;
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("GlobalColorTableFlag: " + globalColorTableFlag);
        }
        final byte colorResolution = (byte) (packedFields >> 4 & 7);
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("ColorResolution: " + colorResolution);
        }
        final boolean sortFlag = (packedFields & 8) > 0;
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("SortFlag: " + sortFlag);
        }
        final byte sizeofGlobalColorTable = (byte) (packedFields & 7);
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest("SizeofGlobalColorTable: " + sizeofGlobalColorTable);
        }

        if (formatCompliance != null && globalColorTableFlag && backgroundColorIndex != -1) {
            formatCompliance.checkBounds("Background Color Index", 0, convertColorTableSize(sizeofGlobalColorTable), backgroundColorIndex);
        }

        return new GifHeaderInfo(identifier1, identifier2, identifier3, version1, version2, version3, logicalScreenWidth, logicalScreenHeight, packedFields,
                backgroundColorIndex, pixelAspectRatio, globalColorTableFlag, colorResolution, sortFlag, sizeofGlobalColorTable);
    }
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