/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.imaging.formats.psd;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.imaging.ImageFormat;
import org.apache.commons.imaging.ImageFormats;
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.ImageParser;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.ByteOrder;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParser;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserBitmap;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserCmyk;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserGrayscale;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserIndexed;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserLab;
import org.apache.commons.imaging.formats.psd.dataparsers.DataParserRgb;
import org.apache.commons.imaging.formats.psd.datareaders.CompressedDataReader;
import org.apache.commons.imaging.formats.psd.datareaders.DataReader;
import org.apache.commons.imaging.formats.psd.datareaders.UncompressedDataReader;
import org.apache.commons.imaging.util.IoUtils;

public class PsdImageParser extends ImageParser {

    public PsdImageParser() {
        super.setByteOrder(ByteOrder.MOTOROLA);
        // setDebug(true);
    }

    @Override
    public String getName() {
        return "PSD-Custom";
    }

    @Override
    public String getDefaultExtension() {
        return DEFAULT_EXTENSION;
    }

    private static final String DEFAULT_EXTENSION = ".psd";

    private static final String ACCEPTED_EXTENSIONS[] = { DEFAULT_EXTENSION, };

    @Override
    protected String[] getAcceptedExtensions() {
        return ACCEPTED_EXTENSIONS;
    }

    @Override
    protected ImageFormat[] getAcceptedTypes() {
        return new ImageFormat[] { ImageFormats.PSD, //
        };
    }

    private PsdHeaderInfo readHeader(final ByteSource byteSource)
            throws ImageReadException, IOException {
        InputStream is = null;
        boolean canThrow = false;
        try {
            is = byteSource.getInputStream();

            final PsdHeaderInfo ret = readHeader(is);
            canThrow = true;
            return ret;
        } finally {
            IoUtils.closeQuietly(canThrow, is);
        }
    }

    private PsdHeaderInfo readHeader(final InputStream is) throws ImageReadException,
            IOException {
        readAndVerifyBytes(is, new byte[] { 56, 66, 80, 83 },
                "Not a Valid PSD File");

        final int Version = read2Bytes("Version", is, "Not a Valid PSD File");

        final byte Reserved[] = readBytes("Reserved", is, 6,
                "Not a Valid PSD File");

        final int Channels = read2Bytes("Channels", is, "Not a Valid PSD File");
        final int Rows = read4Bytes("Rows", is, "Not a Valid PSD File");
        final int Columns = read4Bytes("Columns", is, "Not a Valid PSD File");
        final int Depth = read2Bytes("Depth", is, "Not a Valid PSD File");
        final int Mode = read2Bytes("Mode", is, "Not a Valid PSD File");

        final PsdHeaderInfo result = new PsdHeaderInfo(Version, Reserved, Channels,
                Rows, Columns, Depth, Mode);

        return result;
    }

    private ImageContents readImageContents(final InputStream is)
            throws ImageReadException, IOException {
        final PsdHeaderInfo header = readHeader(is);

        final int ColorModeDataLength = read4Bytes("ColorModeDataLength", is,
                "Not a Valid PSD File");
        skipBytes(is, ColorModeDataLength);
        // is.skip(ColorModeDataLength);
        // byte ColorModeData[] = readByteArray("ColorModeData",
        // ColorModeDataLength, is, "Not a Valid PSD File");

        final int ImageResourcesLength = read4Bytes("ImageResourcesLength", is,
                "Not a Valid PSD File");
        skipBytes(is, ImageResourcesLength);
        // long skipped = is.skip(ImageResourcesLength);
        // byte ImageResources[] = readByteArray("ImageResources",
        // ImageResourcesLength, is, "Not a Valid PSD File");

        final int LayerAndMaskDataLength = read4Bytes("LayerAndMaskDataLength", is,
                "Not a Valid PSD File");
        skipBytes(is, LayerAndMaskDataLength);
        // is.skip(LayerAndMaskDataLength);
        // byte LayerAndMaskData[] = readByteArray("LayerAndMaskData",
        // LayerAndMaskDataLength, is, "Not a Valid PSD File");

        final int Compression = read2Bytes("Compression", is, "Not a Valid PSD File");

        // skip_bytes(is, LayerAndMaskDataLength);
        // byte ImageData[] = readByteArray("ImageData", LayerAndMaskDataLength,
        // is, "Not a Valid PSD File");

        // System.out.println("Compression: " + Compression);

        final ImageContents result = new ImageContents(header, ColorModeDataLength,
        // ColorModeData,
                ImageResourcesLength,
                // ImageResources,
                LayerAndMaskDataLength,
                // LayerAndMaskData,
                Compression);

        return result;
    }

    private List<ImageResourceBlock> readImageResourceBlocks(final byte bytes[],
            final int imageResourceIDs[], final int maxBlocksToRead)
            throws ImageReadException, IOException {
        return readImageResourceBlocks(new ByteArrayInputStream(bytes),
                imageResourceIDs, maxBlocksToRead, bytes.length);
    }

    private boolean keepImageResourceBlock(final int ID, final int imageResourceIDs[]) {
        if (imageResourceIDs == null) {
            return true;
        }

        for (final int imageResourceID : imageResourceIDs) {
            if (ID == imageResourceID) {
                return true;
            }
        }

        return false;
    }

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

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

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

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

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

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

            if ((DataSize % 2) != 0) {
                //final int DataDiscard =
                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;
    }

    private List<ImageResourceBlock> readImageResourceBlocks(
            final ByteSource byteSource, final int imageResourceIDs[], final int maxBlocksToRead)
            throws ImageReadException, IOException {
        InputStream imageStream = null;
        InputStream resourceStream = null;
        boolean canThrow = false;
        try {
            imageStream = byteSource.getInputStream();

            final ImageContents imageContents = readImageContents(imageStream);

            resourceStream = this.getInputStream(byteSource, PSD_SECTION_IMAGE_RESOURCES);
            final byte ImageResources[] = readBytes("ImageResources",
                    resourceStream, imageContents.ImageResourcesLength,
                    "Not a Valid PSD File");

            final List<ImageResourceBlock> ret = readImageResourceBlocks(ImageResources, imageResourceIDs,
                    maxBlocksToRead);
            canThrow = true;
            return ret;
        } finally {
            IoUtils.closeQuietly(canThrow, imageStream, resourceStream);
        }
    }

    private static final int PSD_SECTION_HEADER = 0;
    private static final int PSD_SECTION_COLOR_MODE = 1;
    private static final int PSD_SECTION_IMAGE_RESOURCES = 2;
    private static final int PSD_SECTION_LAYER_AND_MASK_DATA = 3;
    private static final int PSD_SECTION_IMAGE_DATA = 4;

    private static final int PSD_HEADER_LENGTH = 26;

    private InputStream getInputStream(final ByteSource byteSource, final int section)
            throws ImageReadException, IOException {
        InputStream is = null;
        boolean notFound = false;
        try {
            is = byteSource.getInputStream();

            if (section == PSD_SECTION_HEADER) {
                return is;
            }

            skipBytes(is, PSD_HEADER_LENGTH);
            // is.skip(kHeaderLength);

            final int ColorModeDataLength = read4Bytes("ColorModeDataLength", is,
                    "Not a Valid PSD File");

            if (section == PSD_SECTION_COLOR_MODE) {
                return is;
            }

            skipBytes(is, ColorModeDataLength);
            // byte ColorModeData[] = readByteArray("ColorModeData",
            // ColorModeDataLength, is, "Not a Valid PSD File");

            final int ImageResourcesLength = read4Bytes("ImageResourcesLength", is,
                    "Not a Valid PSD File");

            if (section == PSD_SECTION_IMAGE_RESOURCES) {
                return is;
            }

            skipBytes(is, ImageResourcesLength);
            // byte ImageResources[] = readByteArray("ImageResources",
            // ImageResourcesLength, is, "Not a Valid PSD File");

            final int LayerAndMaskDataLength = read4Bytes("LayerAndMaskDataLength",
                    is, "Not a Valid PSD File");

            if (section == PSD_SECTION_LAYER_AND_MASK_DATA) {
                return is;
            }

            skipBytes(is, LayerAndMaskDataLength);
            // byte LayerAndMaskData[] = readByteArray("LayerAndMaskData",
            // LayerAndMaskDataLength, is, "Not a Valid PSD File");

            read2Bytes("Compression", is, "Not a Valid PSD File");

            // byte ImageData[] = readByteArray("ImageData",
            // LayerAndMaskDataLength, is, "Not a Valid PSD File");

            if (section == PSD_SECTION_IMAGE_DATA) {
                return is;
            }
            notFound = true;
        } finally {
            if (notFound && is != null) {
                is.close();
            }
        }
        throw new ImageReadException("getInputStream: Unknown Section: "
                + section);
    }

    private byte[] getData(final ByteSource byteSource, final int section)
            throws ImageReadException, IOException {
        InputStream is = null;
        boolean canThrow = false;
        try {
            is = byteSource.getInputStream();

            // PsdHeaderInfo header = readHeader(is);
            if (section == PSD_SECTION_HEADER) {
                canThrow = true;
                return readBytes("Header", is, PSD_HEADER_LENGTH,
                        "Not a Valid PSD File");
            }
            skipBytes(is, PSD_HEADER_LENGTH);

            final int ColorModeDataLength = read4Bytes("ColorModeDataLength", is,
                    "Not a Valid PSD File");

            if (section == PSD_SECTION_COLOR_MODE) {
                canThrow = true;
                return readBytes("ColorModeData", is, ColorModeDataLength,
                        "Not a Valid PSD File");
            }

            skipBytes(is, ColorModeDataLength);
            // byte ColorModeData[] = readByteArray("ColorModeData",
            // ColorModeDataLength, is, "Not a Valid PSD File");

            final int ImageResourcesLength = read4Bytes("ImageResourcesLength", is,
                    "Not a Valid PSD File");

            if (section == PSD_SECTION_IMAGE_RESOURCES) {
                canThrow = true;
                return readBytes("ImageResources", is,
                        ImageResourcesLength, "Not a Valid PSD File");
            }

            skipBytes(is, ImageResourcesLength);
            // byte ImageResources[] = readByteArray("ImageResources",
            // ImageResourcesLength, is, "Not a Valid PSD File");

            final int LayerAndMaskDataLength = read4Bytes("LayerAndMaskDataLength",
                    is, "Not a Valid PSD File");

            if (section == PSD_SECTION_LAYER_AND_MASK_DATA) {
                canThrow = true;
                return readBytes("LayerAndMaskData",
                        is, LayerAndMaskDataLength, "Not a Valid PSD File");
            }

            skipBytes(is, LayerAndMaskDataLength);
            // byte LayerAndMaskData[] = readByteArray("LayerAndMaskData",
            // LayerAndMaskDataLength, is, "Not a Valid PSD File");

            read2Bytes("Compression", is, "Not a Valid PSD File");

            // byte ImageData[] = readByteArray("ImageData",
            // LayerAndMaskDataLength, is, "Not a Valid PSD File");

            // if (section == kPSD_SECTION_IMAGE_DATA)
            // return readByteArray("LayerAndMaskData", LayerAndMaskDataLength,
            // is,
            // "Not a Valid PSD File");
            canThrow = true;
        } finally {
            IoUtils.closeQuietly(canThrow, is);
        }
        throw new ImageReadException("getInputStream: Unknown Section: "
                + section);
    }

    private ImageContents readImageContents(final ByteSource byteSource)
            throws ImageReadException, IOException {
        InputStream is = null;
        boolean canThrow = false;
        try {
            is = byteSource.getInputStream();

            final ImageContents imageContents = readImageContents(is);
            canThrow = true;
            return imageContents;
        } finally {
            IoUtils.closeQuietly(canThrow, is);
        }

    }

    public final static int IMAGE_RESOURCE_ID_ICC_PROFILE = 0x040F;

    @Override
    public byte[] getICCProfileBytes(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        final List<ImageResourceBlock> blocks = readImageResourceBlocks(byteSource,
                new int[] { IMAGE_RESOURCE_ID_ICC_PROFILE, }, 1);

        if ((blocks == null) || (blocks.size() < 1)) {
            return null;
        }

        final ImageResourceBlock irb = blocks.get(0);
        final byte bytes[] = irb.data;
        if ((bytes == null) || (bytes.length < 1)) {
            return null;
        }
        return bytes;
    }

    @Override
    public Dimension getImageSize(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        final PsdHeaderInfo bhi = readHeader(byteSource);
        if (bhi == null) {
            throw new ImageReadException("PSD: couldn't read header");
        }

        return new Dimension(bhi.Columns, bhi.Rows);

    }

    public byte[] embedICCProfile(final byte image[], final byte profile[]) {
        return null;
    }

    @Override
    public boolean embedICCProfile(final File src, final File dst, final byte profile[]) {
        return false;
    }

    @Override
    public IImageMetadata getMetadata(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        return null;
    }

    private int getChannelsPerMode(final int mode) {
        switch (mode) {
        case 0: // Bitmap
            return 1;
        case 1: // Grayscale
            return 1;
        case 2: // Indexed
            return -1;
        case 3: // RGB
            return 3;
        case 4: // CMYK
            return 4;
        case 7: // Multichannel
            return -1;
        case 8: // Duotone
            return -1;
        case 9: // Lab
            return 4;
        default:
            return -1;

        }
    }

    @Override
    public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        final ImageContents imageContents = readImageContents(byteSource);
        // ImageContents imageContents = readImage(byteSource, false);

        if (imageContents == null) {
            throw new ImageReadException("PSD: Couldn't read blocks");
        }

        final PsdHeaderInfo header = imageContents.header;
        if (header == null) {
            throw new ImageReadException("PSD: Couldn't read Header");
        }

        final int Width = header.Columns;
        final int Height = header.Rows;

        final List<String> Comments = new ArrayList<String>();
        // TODO: comments...

        int BitsPerPixel = header.Depth * getChannelsPerMode(header.Mode);
        // System.out.println("header.Depth: " + header.Depth);
        // System.out.println("header.Mode: " + header.Mode);
        // System.out.println("getChannelsPerMode(header.Mode): " +
        // getChannelsPerMode(header.Mode));
        if (BitsPerPixel < 0) {
            BitsPerPixel = 0;
        }
        final ImageFormat Format = ImageFormats.PSD;
        final String FormatName = "Photoshop";
        final String MimeType = "image/x-photoshop";
        // we ought to count images, but don't yet.
        final int NumberOfImages = -1;
        // not accurate ... only reflects first
        final boolean isProgressive = false;

        final int PhysicalWidthDpi = 72;
        final float PhysicalWidthInch = (float) ((double) Width / (double) PhysicalWidthDpi);
        final int PhysicalHeightDpi = 72;
        final float PhysicalHeightInch = (float) ((double) Height / (double) PhysicalHeightDpi);

        final String FormatDetails = "Psd";

        final boolean isTransparent = false; // TODO: inaccurate.
        final boolean usesPalette = header.Mode == COLOR_MODE_INDEXED;
        final int ColorType = ImageInfo.COLOR_TYPE_UNKNOWN;

        String compressionAlgorithm;
        switch (imageContents.Compression) {
        case 0:
            compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_NONE;
            break;
        case 1:
            compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_PSD;
            break;
        default:
            compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_UNKNOWN;
        }

        final ImageInfo result = new ImageInfo(FormatDetails, BitsPerPixel, Comments,
                Format, FormatName, Height, MimeType, NumberOfImages,
                PhysicalHeightDpi, PhysicalHeightInch, PhysicalWidthDpi,
                PhysicalWidthInch, Width, isProgressive, isTransparent,
                usesPalette, ColorType, compressionAlgorithm);

        return result;
    }

//    // TODO not used
//    private ImageResourceBlock findImageResourceBlock(
//            final List<ImageResourceBlock> blocks, final int ID) {
//        for (int i = 0; i < blocks.size(); i++) {
//            final ImageResourceBlock block = blocks.get(i);
//
//            if (block.id == ID) {
//                return block;
//            }
//        }
//        return null;
//    }

    @Override
    public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource)
            throws ImageReadException, IOException {
        pw.println("gif.dumpImageFile");

        final ImageInfo fImageData = getImageInfo(byteSource);
        if (fImageData == null) {
            return false;
        }

        fImageData.toString(pw, "");
        final ImageContents imageContents = readImageContents(byteSource);

        imageContents.dump(pw);
        imageContents.header.dump(pw);

        final List<ImageResourceBlock> blocks = readImageResourceBlocks(
                byteSource,
                // fImageContents.ImageResources,
                null, -1);

        pw.println("blocks.size(): " + blocks.size());

        // System.out.println("gif.blocks: " + blocks.blocks.size());
        for (int i = 0; i < blocks.size(); i++) {
            final ImageResourceBlock block = blocks.get(i);
            pw.println("\t" + i + " (" + Integer.toHexString(block.id)
                    + ", " + "'"
                    + new String(block.nameData, "ISO-8859-1")
                    + "' ("
                    + block.nameData.length
                    + "), "
                    // + block.getClass().getName()
                    // + ", "
                    + " data: " + block.data.length + " type: '"
                    + new PsdConstants().getDescription(block.id) + "' "
                    + ")");

        }

        pw.println("");

        return true;
    }

    private static final int COLOR_MODE_INDEXED = 2;

    @Override
    public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {
        final ImageContents imageContents = readImageContents(byteSource);
        // ImageContents imageContents = readImage(byteSource, false);

        if (imageContents == null) {
            throw new ImageReadException("PSD: Couldn't read blocks");
        }

        final PsdHeaderInfo header = imageContents.header;
        if (header == null) {
            throw new ImageReadException("PSD: Couldn't read Header");
        }

        // ImageDescriptor id = (ImageDescriptor)
        // findBlock(fImageContents.blocks,
        // kImageSeperator);
        // if (id == null)
        // throw new ImageReadException("PSD: Couldn't read Image Descriptor");
        // GraphicControlExtension gce = (GraphicControlExtension) findBlock(
        // fImageContents.blocks, kGraphicControlExtension);

        readImageResourceBlocks(byteSource,
        // fImageContents.ImageResources,
                null, -1);

        final int width = header.Columns;
        final int height = header.Rows;
        // int height = header.Columns;

        // int transfer_type;

        // transfer_type = DataBuffer.TYPE_BYTE;

        final boolean hasAlpha = false;
        final BufferedImage result = getBufferedImageFactory(params)
                .getColorBufferedImage(width, height, hasAlpha);

        DataParser dataParser;
        switch (imageContents.header.Mode) {
        case 0: // bitmap
            dataParser = new DataParserBitmap();
            break;
        case 1:
        case 8: // Duotone=8;
            dataParser = new DataParserGrayscale();
            break;
        case 3:
            dataParser = new DataParserRgb();
            break;
        case 4:
            dataParser = new DataParserCmyk();
            break;
        case 9:
            dataParser = new DataParserLab();
            break;
        case COLOR_MODE_INDEXED:
        // case 2 : // Indexed=2;
        {

            final byte ColorModeData[] = getData(byteSource, PSD_SECTION_COLOR_MODE);

            // ImageResourceBlock block = findImageResourceBlock(blocks,
            // 0x03EB);
            // if (block == null)
            // throw new ImageReadException(
            // "Missing: Indexed Color Image Resource Block");

            dataParser = new DataParserIndexed(ColorModeData);
            break;
        }
        case 7: // Multichannel=7;
            // fDataParser = new DataParserStub();
            // break;

            // case 1 :
            // fDataReader = new CompressedDataReader();
            // break;
        default:
            throw new ImageReadException("Unknown Mode: "
                    + imageContents.header.Mode);
        }
        DataReader fDataReader;
        switch (imageContents.Compression) {
        case 0:
            fDataReader = new UncompressedDataReader(dataParser);
            break;
        case 1:
            fDataReader = new CompressedDataReader(dataParser);
            break;
        default:
            throw new ImageReadException("Unknown Compression: "
                    + imageContents.Compression);
        }
        
        InputStream is = null;
        boolean canThrow = false;
        try {
            is = getInputStream(byteSource, PSD_SECTION_IMAGE_DATA);
            fDataReader.readData(is, result, imageContents, this);

            fDataReader.dump();
            canThrow = true;
            // is.
            // ImageContents imageContents = readImageContents(is);
            // return imageContents;
        } finally {
            IoUtils.closeQuietly(canThrow, is);
        }

        return result;

    }

    public final static int IMAGE_RESOURCE_ID_XMP = 0x0424;

    public final static String BLOCK_NAME_XMP = "XMP";

    /**
     * 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.
     */
    @Override
    public String getXmpXml(final ByteSource byteSource, final Map<String,Object> params)
            throws ImageReadException, IOException {

        final ImageContents imageContents = readImageContents(byteSource);

        if (imageContents == null) {
            throw new ImageReadException("PSD: Couldn't read blocks");
        }

        final PsdHeaderInfo header = imageContents.header;
        if (header == null) {
            throw new ImageReadException("PSD: Couldn't read Header");
        }

        final List<ImageResourceBlock> blocks = readImageResourceBlocks(byteSource,
                new int[] { IMAGE_RESOURCE_ID_XMP, }, -1);

        if ((blocks == null) || (blocks.size() < 1)) {
            return null;
        }

        final List<ImageResourceBlock> xmpBlocks = new ArrayList<ImageResourceBlock>();
//        if (false) {
//            // TODO: for PSD 7 and later, verify "XMP" name.
//            for (int i = 0; i < blocks.size(); i++) {
//                final ImageResourceBlock block = blocks.get(i);
//                if (!block.getName().equals(BLOCK_NAME_XMP)) {
//                    continue;
//                }
//                xmpBlocks.add(block);
//            }
//        } else {
            xmpBlocks.addAll(blocks);
//        }

        if (xmpBlocks.size() < 1) {
            return null;
        }
        if (xmpBlocks.size() > 1) {
            throw new ImageReadException(
                    "PSD contains more than one XMP block.");
        }

        final ImageResourceBlock block = xmpBlocks.get(0);

        try {
            // segment data is UTF-8 encoded xml.
            final String xml = new String(block.data, 0, block.data.length, "utf-8");
            return xml;
        } catch (final UnsupportedEncodingException e) {
            throw new ImageReadException("Invalid JPEG XMP Segment.");
        }
    }

}
