private List<ImageResourceBlock> readImageResourceBlocks(final InputStream is, final int[] imageResourceIDs, final int maxBlocksToRead, int available)
            throws ImagingException, IOException {
        final List<ImageResourceBlock> result = new ArrayList<>();

        while (available > 0) {
            BinaryFunctions.readAndVerifyBytes(is, new byte[] { 56, 66, 73, 77 }, "Not a Valid PSD File");
            available -= 4;

            final int id = BinaryFunctions.read2Bytes("ID", is, "Not a Valid PSD File", getByteOrder());
            available -= 2;

            final int nameLength = BinaryFunctions.readByte("NameLength", is, "Not a Valid PSD File");

            available -= 1;
            final byte[] nameBytes = BinaryFunctions.readBytes("NameData", is, nameLength, "Not a Valid PSD File");
            available -= nameLength;
            if ((nameLength + 1) % 2 != 0) {
                // final int NameDiscard =
                BinaryFunctions.readByte("NameDiscard", is, "Not a Valid PSD File");
                available -= 1;
            }
            // String Name = readPString("Name", 6, is, "Not a Valid PSD File");
            final int dataSize = BinaryFunctions.read4Bytes("Size", is, "Not a Valid PSD File", getByteOrder());
            available -= 4;
            // int ActualDataSize = ((DataSize % 2) == 0)
            // ? DataSize
            // : DataSize + 1; // pad to make even

            final byte[] data = BinaryFunctions.readBytes("Data", is, dataSize, "Not a Valid PSD File");
            available -= dataSize;

            if (dataSize % 2 != 0) {
                // final int DataDiscard =
                BinaryFunctions.readByte("DataDiscard", is, "Not a Valid PSD File");
                available -= 1;
            }

            if (keepImageResourceBlock(id, imageResourceIDs)) {
                result.add(new ImageResourceBlock(id, nameBytes, data));

                if (maxBlocksToRead >= 0 && result.size() >= maxBlocksToRead) {
                    return result;
                }
            }
            // debugNumber("ID", ID, 2);

        }

        return result;
    }
Extracts embedded XML metadata as XML string.

@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/psd/PsdImageParser.java