/* ProfileHeader.java -- Encapsules ICC Profile header data
   Copyright (C) 2004 Free Software Foundation

   This file is part of GNU Classpath.

   GNU Classpath is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   GNU Classpath is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Classpath; see the file COPYING.  If not, write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.

   Linking this library statically or dynamically with other modules is
   making a combined work based on this library.  Thus, the terms and
   conditions of the GNU General Public License cover the whole
   combination.

   As a special exception, the copyright holders of this library give you
   permission to link this library with independent modules to produce an
   executable, regardless of the license terms of these independent
   modules, and to copy and distribute the resulting executable under
   terms of your choice, provided that you also meet, for each linked
   independent module, the terms and conditions of the license of that
   module.  An independent module is a module which is not derived from
   or based on this library.  If you modify this library, you may extend
   this exception to your version of the library, but you are not
   obligated to do so.  If you do not wish to do so, delete this
   exception statement from your version.
*/

package gnu.java.awt.color;

import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.nio.ByteBuffer;


/**
 * Header, abstracts and validates the header data.
 *
 * @author Sven de Marothy
 */
public class ProfileHeader
{
  /**
   * Magic identifier (ASCII 'acsp')
   */
  private static final int icMagicNumber = 0x61637370;

  /**
   * Mapping from ICC Profile signatures to ColorSpace types
   */
  private static final int[] csTypeMap = 
                                         {
                                           ICC_Profile.icSigXYZData,
                                           ColorSpace.TYPE_XYZ,
                                           ICC_Profile.icSigLabData,
                                           ColorSpace.TYPE_Lab,
                                           ICC_Profile.icSigLuvData,
                                           ColorSpace.TYPE_Luv,
                                           ICC_Profile.icSigYCbCrData,
                                           ColorSpace.TYPE_YCbCr,
                                           ICC_Profile.icSigYxyData,
                                           ColorSpace.TYPE_Yxy,
                                           ICC_Profile.icSigRgbData,
                                           ColorSpace.TYPE_RGB,
                                           ICC_Profile.icSigGrayData,
                                           ColorSpace.TYPE_GRAY,
                                           ICC_Profile.icSigHsvData,
                                           ColorSpace.TYPE_HSV,
                                           ICC_Profile.icSigHlsData,
                                           ColorSpace.TYPE_HLS,
                                           ICC_Profile.icSigCmykData,
                                           ColorSpace.TYPE_CMYK,
                                           ICC_Profile.icSigCmyData,
                                           ColorSpace.TYPE_CMY,
                                           ICC_Profile.icSigSpace2CLR,
                                           ColorSpace.TYPE_2CLR,
                                           ICC_Profile.icSigSpace3CLR,
                                           ColorSpace.TYPE_3CLR,
                                           ICC_Profile.icSigSpace4CLR,
                                           ColorSpace.TYPE_4CLR,
                                           ICC_Profile.icSigSpace5CLR,
                                           ColorSpace.TYPE_5CLR,
                                           ICC_Profile.icSigSpace6CLR,
                                           ColorSpace.TYPE_6CLR,
                                           ICC_Profile.icSigSpace7CLR,
                                           ColorSpace.TYPE_7CLR,
                                           ICC_Profile.icSigSpace8CLR,
                                           ColorSpace.TYPE_8CLR,
                                           ICC_Profile.icSigSpace9CLR,
                                           ColorSpace.TYPE_9CLR,
                                           ICC_Profile.icSigSpaceACLR,
                                           ColorSpace.TYPE_ACLR,
                                           ICC_Profile.icSigSpaceBCLR,
                                           ColorSpace.TYPE_BCLR,
                                           ICC_Profile.icSigSpaceCCLR,
                                           ColorSpace.TYPE_CCLR,
                                           ICC_Profile.icSigSpaceDCLR,
                                           ColorSpace.TYPE_DCLR,
                                           ICC_Profile.icSigSpaceECLR,
                                           ColorSpace.TYPE_ECLR,
                                           ICC_Profile.icSigSpaceFCLR,
                                           ColorSpace.TYPE_FCLR
                                         };

  /**
   * Size of an ICC header (128 bytes)
   */
  public static final int HEADERSIZE = 128;

  /**
   * Mapping of ICC class signatures to profile class constants
   */
  private static final int[] classMap = 
                                        {
                                          ICC_Profile.icSigInputClass,
                                          ICC_Profile.CLASS_INPUT,
                                          ICC_Profile.icSigDisplayClass,
                                          ICC_Profile.CLASS_DISPLAY,
                                          ICC_Profile.icSigOutputClass,
                                          ICC_Profile.CLASS_OUTPUT,
                                          ICC_Profile.icSigLinkClass,
                                          ICC_Profile.CLASS_DEVICELINK,
                                          ICC_Profile.icSigColorSpaceClass,
                                          ICC_Profile.CLASS_COLORSPACECONVERSION,
                                          ICC_Profile.icSigAbstractClass,
                                          ICC_Profile.CLASS_ABSTRACT,
                                          ICC_Profile.icSigNamedColorClass,
                                          ICC_Profile.CLASS_NAMEDCOLOR
                                        };
  private int size;
  private int cmmId;

  // Major/Minor version, The ICC-1998 spec is major v2
  private int majorVersion;

  // Major/Minor version, The ICC-1998 spec is major v2
  private int minorVersion;
  private int profileClass; // profile device class
  private int colorSpace; // data color space type
  private int profileColorSpace; // profile connection space (PCS) type
  private byte[] timestamp; // original creation timestamp
  private int platform; // platform signature
  private int flags; // flags
  private int magic; // magic number.
  private int manufacturerSig; // manufacturer sig
  private int modelSig; // model sig
  private byte[] attributes; // Attributes
  private int intent; // rendering intent
  private byte[] illuminant; // illuminant info (Coordinates of D50 in the PCS)
  private int creatorSig; // Creator sig (same type as manufacturer)

  /**
   * Creates a 'default' header for use with our predefined profiles.
   * Note the device and profile color spaces are not set.
   */
  public ProfileHeader()
  {
    creatorSig = 0;
    intent = 0;
    modelSig = manufacturerSig = (int) 0x6E6f6E65; // 'none'
    magic = icMagicNumber;
    cmmId = 0;
    platform = 0; // no preferred platform
    timestamp = new byte[8];
    majorVersion = 2;
    minorVersion = 0x10;
    flags = 0;

    // D50 in XYZ format (encoded)
    illuminant = new byte[]
                 {
                   (byte) 0x00, (byte) 0x00, (byte) 0xf6, (byte) 0xd6,
                   (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
                   (byte) 0x00, (byte) 0x00, (byte) 0xd3, (byte) 0x2d
                 };
    attributes = new byte[8];
    profileClass = ICC_Profile.CLASS_DISPLAY;
  }

  /**
   * Creates a header from profile data. Only the header portion (128 bytes)
   * is read, so the array passed need not be the full profile.
   */
  public ProfileHeader(byte[] data)
  {
    ByteBuffer buf = ByteBuffer.wrap(data);

    // Get size (the sign bit shouldn't matter. 	
    // A valid profile can never be +2Gb)
    size = buf.getInt(ICC_Profile.icHdrSize);

    // CMM ID
    cmmId = buf.getInt(ICC_Profile.icHdrCmmId);

    // Version number
    majorVersion = (int) (data[ICC_Profile.icHdrVersion]);
    minorVersion = (int) (data[ICC_Profile.icHdrVersion + 1]);

    // Profile/Device class
    int classSig = buf.getInt(ICC_Profile.icHdrDeviceClass);
    profileClass = -1;
    for (int i = 0; i < classMap.length; i += 2)
      if (classMap[i] == classSig)
        {
	  profileClass = classMap[i + 1];
	  break;
        }

    // get the data color space
    int csSig = buf.getInt(ICC_Profile.icHdrColorSpace);
    colorSpace = -1;
    for (int i = 0; i < csTypeMap.length; i += 2)
      if (csTypeMap[i] == csSig)
        {
	  colorSpace = csTypeMap[i + 1];
	  break;
        }

    // get the profile color space (PCS), must be xyz or lab except
    // for device-link-class profiles
    int pcsSig = buf.getInt(ICC_Profile.icHdrPcs);
    profileColorSpace = -1;
    if (profileClass != ICC_Profile.CLASS_DEVICELINK)
      {
	if (pcsSig == ICC_Profile.icSigXYZData)
	  profileColorSpace = ColorSpace.TYPE_XYZ;
	if (pcsSig == ICC_Profile.icSigLabData)
	  profileColorSpace = ColorSpace.TYPE_Lab;
      }
    else
      {
	for (int i = 0; i < csTypeMap.length; i += 2)
	  if (csTypeMap[i] == pcsSig)
	    {
	      profileColorSpace = csTypeMap[i + 1];
	      break;
	    }
      }

    // creation timestamp
    timestamp = new byte[8];
    System.arraycopy(data, ICC_Profile.icHdrDate, timestamp, 0, 8);

    // magic number
    magic = buf.getInt(ICC_Profile.icHdrMagic);

    //  platform info
    platform = buf.getInt(ICC_Profile.icHdrPlatform);
    // get flags
    flags = buf.getInt(ICC_Profile.icHdrFlags);
    // get manufacturer sign
    manufacturerSig = buf.getInt(ICC_Profile.icHdrManufacturer);
    // get header model
    modelSig = buf.getInt(ICC_Profile.icHdrModel);
    // attributes
    attributes = new byte[8];
    System.arraycopy(data, ICC_Profile.icHdrAttributes, attributes, 0, 8);
    // rendering intent
    intent = buf.getInt(ICC_Profile.icHdrRenderingIntent);
    // illuminant info 
    illuminant = new byte[12];
    System.arraycopy(data, ICC_Profile.icHdrIlluminant, illuminant, 0, 12);
    // Creator signature
    creatorSig = buf.getInt(ICC_Profile.icHdrCreator);
    // The rest of the header (Total size: 128 bytes) is unused..
  }

  /**
   * Verify that the header is valid
   * @param size equals the file size if it is to be verified, -1 otherwise
   * @throws IllegalArgumentException if the header is found to be invalid.
   */
  public void verifyHeader(int size) throws IllegalArgumentException
  {
    // verify size
    if (size != -1 && this.size != size)
      throw new IllegalArgumentException("Invalid profile length:" + size);

    // Check version number
    if (majorVersion != 2)
      throw new IllegalArgumentException("Wrong major version number:"
                                         + majorVersion);

    // Profile/Device class
    if (profileClass == -1)
      throw new IllegalArgumentException("Invalid profile/device class");

    // get the data color space
    if (colorSpace == -1)
      throw new IllegalArgumentException("Invalid colorspace");

    // profile color space
    if (profileColorSpace == -1)
      throw new IllegalArgumentException("Invalid PCS.");

    // check magic number
    if (magic != icMagicNumber)
      throw new IllegalArgumentException("Invalid magic number!");
  }

  /**
   * Creates a header, setting the header file size at the same time.
   * @param size the profile file size.
   */
  public byte[] getData(int size)
  {
    byte[] data = new byte[HEADERSIZE];
    ByteBuffer buf = ByteBuffer.wrap(data);
    buf.putInt(ICC_Profile.icHdrSize, size);
    buf.putInt(ICC_Profile.icHdrCmmId, cmmId);
    buf.putShort(ICC_Profile.icHdrVersion,
                 (short) (majorVersion << 8 | minorVersion));
    for (int i = 1; i < classMap.length; i += 2)
      if (profileClass == classMap[i])
	buf.putInt(ICC_Profile.icHdrDeviceClass, classMap[i - 1]);
    for (int i = 1; i < csTypeMap.length; i += 2)
      if (csTypeMap[i] == colorSpace)
	buf.putInt(ICC_Profile.icHdrColorSpace, csTypeMap[i - 1]);
    for (int i = 1; i < csTypeMap.length; i += 2)
      if (csTypeMap[i] == profileColorSpace)
	buf.putInt(ICC_Profile.icHdrPcs, csTypeMap[i - 1]);

    System.arraycopy(timestamp, 0, data, ICC_Profile.icHdrDate,
                     timestamp.length);
    buf.putInt(ICC_Profile.icHdrMagic, icMagicNumber);
    buf.putInt(ICC_Profile.icHdrPlatform, platform);
    buf.putInt(ICC_Profile.icHdrFlags, flags);
    buf.putInt(ICC_Profile.icHdrManufacturer, manufacturerSig);
    buf.putInt(ICC_Profile.icHdrModel, modelSig);
    System.arraycopy(attributes, 0, data, ICC_Profile.icHdrAttributes,
                     attributes.length);
    buf.putInt(ICC_Profile.icHdrRenderingIntent, intent);
    System.arraycopy(illuminant, 0, data, ICC_Profile.icHdrIlluminant,
                     illuminant.length);
    buf.putInt(ICC_Profile.icHdrCreator, creatorSig);
    return buf.array();
  }

  public int getSize()
  {
    return size;
  }

  public void setSize(int s)
  {
    size = s;
  }

  public int getMajorVersion()
  {
    return majorVersion;
  }

  public int getMinorVersion()
  {
    return minorVersion;
  }

  public int getProfileClass()
  {
    return profileClass;
  }

  public void setProfileClass(int pc)
  {
    profileClass = pc;
  }

  public int getColorSpace()
  {
    return colorSpace;
  }

  public int getProfileColorSpace()
  {
    return profileColorSpace;
  }

  public void setColorSpace(int cs)
  {
    colorSpace = cs;
  }

  public void setProfileColorSpace(int pcs)
  {
    profileColorSpace = pcs;
  }

}
