/*
 * 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.sanselan.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.sanselan.ImageFormat;
import org.apache.commons.sanselan.ImageInfo;
import org.apache.commons.sanselan.ImageParser;
import org.apache.commons.sanselan.ImageReadException;
import org.apache.commons.sanselan.common.IImageMetadata;
import org.apache.commons.sanselan.common.bytesource.ByteSource;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParser;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserBitmap;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserCmyk;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserGrayscale;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserIndexed;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserLab;
import org.apache.commons.sanselan.formats.psd.dataparsers.DataParserRgb;
import org.apache.commons.sanselan.formats.psd.datareaders.CompressedDataReader;
import org.apache.commons.sanselan.formats.psd.datareaders.DataReader;
import org.apache.commons.sanselan.formats.psd.datareaders.UncompressedDataReader;
import org.apache.commons.sanselan.util.Debug;

public class PsdImageParser extends ImageParser
{

    public PsdImageParser()
    {
        super.setByteOrder(BYTE_ORDER_MSB);
        // 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[] { ImageFormat.IMAGE_FORMAT_PSD, //
        };
    }

    private PsdHeaderInfo readHeader(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        InputStream is = null;

        try
        {
            is = byteSource.getInputStream();

            return readHeader(is);
        } finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e)
            {
                Debug.debug(e);
            }

        }
    }

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

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

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

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

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

        return result;
    }

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

        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");

        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");

        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");

        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);

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

        return result;
    }

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

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

        for (int i = 0; i < imageResourceIDs.length; i++)
            if (ID == imageResourceIDs[i])
                return true;

        return false;
    }

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

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

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

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

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

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

            if ((DataSize % 2) != 0)
            {
                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(ByteSource byteSource,
                                                             int imageResourceIDs[], int maxBlocksToRead)
            throws ImageReadException, IOException
    {
        InputStream is = null;

        try
        {
            is = byteSource.getInputStream();

            ImageContents imageContents = readImageContents(is);

            is.close();

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

            return readImageResourceBlocks(ImageResources, imageResourceIDs,
                    maxBlocksToRead);
        } finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e)
            {
                Debug.debug(e);
            }

        }
    }

    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(ByteSource byteSource, 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);
    
            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");
    
            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");
    
            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");
    
            int Compression = 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) {
                try {
                    is.close();
                } catch (IOException ignore) {
                }
            }
        }
        throw new ImageReadException("getInputStream: Unknown Section: "
                + section);
    }

    private byte[] getData(ByteSource byteSource, int section)
            throws ImageReadException, IOException
    {
        InputStream is = null;

        try
        {
            is = byteSource.getInputStream();

            // PsdHeaderInfo header = readHeader(is);
            if (section == PSD_SECTION_HEADER)
                return readByteArray("Header", PSD_HEADER_LENGTH, is,
                        "Not a Valid PSD File");
            skipBytes(is, PSD_HEADER_LENGTH);

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

            if (section == PSD_SECTION_COLOR_MODE)
                return readByteArray("ColorModeData", ColorModeDataLength, is,
                        "Not a Valid PSD File");

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

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

            if (section == PSD_SECTION_IMAGE_RESOURCES)
                return readByteArray("ImageResources", ImageResourcesLength,
                        is, "Not a Valid PSD File");

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

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

            if (section == PSD_SECTION_LAYER_AND_MASK_DATA)
                return readByteArray("LayerAndMaskData",
                        LayerAndMaskDataLength, is, "Not a Valid PSD File");

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

            int Compression = 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");

        } finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e)
            {
                Debug.debug(e);
            }

        }
        throw new ImageReadException("getInputStream: Unknown Section: "
                + section);
    }

    private ImageContents readImageContents(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        InputStream is = null;

        try
        {
            is = byteSource.getInputStream();

            ImageContents imageContents = readImageContents(is);
            return imageContents;
        } finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e)
            {
                Debug.debug(e);
            }

        }

    }

    public final static int IMAGE_RESOURCE_ID_ICC_PROFILE = 0x040F;

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

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

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

    @Override
    public Dimension getImageSize(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        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(byte image[], byte profile[])
    {
        return null;
    }

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

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

    private int getChannelsPerMode(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(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        ImageContents imageContents = readImageContents(byteSource);
        // ImageContents imageContents = readImage(byteSource, false);

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

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

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

        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;
        ImageFormat Format = ImageFormat.IMAGE_FORMAT_PSD;
        String FormatName = "Photoshop";
        String MimeType = "image/x-photoshop";
        // we ought to count images, but don't yet.
        int NumberOfImages = -1;
        // not accurate ... only reflects first
        boolean isProgressive = false;

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

        String FormatDetails = "Psd";

        boolean isTransparent = false; // TODO: inaccurate.
        boolean usesPalette = header.Mode == COLOR_MODE_INDEXED;
        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;
        }

        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(List<ImageResourceBlock> blocks, int ID)
    {
        for (int i = 0; i < blocks.size(); i++)
        {
            ImageResourceBlock block = blocks.get(i);

            if (block.id == ID)
                return block;
        }
        return null;
    }

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

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

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

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

            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++)
            {
                ImageResourceBlock block = blocks.get(i);
                pw.println("\t" + i + " (" + Integer.toHexString(block.id)
                        + ", " + "'"
                        + new String(block.nameData)
                        + "' ("
                        + 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(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        ImageContents imageContents = readImageContents(byteSource);
        // ImageContents imageContents = readImage(byteSource, false);

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

        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);

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

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

        // int transfer_type;

        // transfer_type = DataBuffer.TYPE_BYTE;

        boolean hasAlpha = false;
        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;
        {

            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;

            try
            {
                is = getInputStream(byteSource, PSD_SECTION_IMAGE_DATA);
                fDataReader.readData(is, result, imageContents, this);

                fDataReader.dump();
                // is.
                // ImageContents imageContents = readImageContents(is);
                // return imageContents;
            } finally
            {
                try
                {
                    if (is != null)
                        is.close();
                } catch (Exception e)
                {
                    Debug.debug(e);
                }

            }

        }

        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 SanselanConstants.
     * @return Xmp Xml as String, if present. Otherwise, returns null.
     */
    @Override
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {

        ImageContents imageContents = readImageContents(byteSource);

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

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

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

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

        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++)
            {
                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.");

        ImageResourceBlock block = xmpBlocks.get(0);

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

}