/* ICC_Profile.java -- color space profiling
   Copyright (C) 2000, 2002, 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 java.awt.color;

import gnu.java.awt.color.ProfileHeader;
import gnu.java.awt.color.TagEntry;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * ICC Profile - represents an ICC Color profile.
 * The ICC profile format is a standard file format which maps the transform
 * from a device color space to a standard Profile Color Space (PCS), which
 * can either be CIE L*a*b or CIE XYZ.
 * (With the exception of device link profiles which map from one device space
 * to another)
 *
 * ICC profiles calibrated to specific input/output devices are used when color
 * fidelity is of importance.
 *
 * An instance of ICC_Profile can be created using the getInstance() methods,
 * either using one of the predefined color spaces enumerated in ColorSpace,
 * or from an ICC profile file, or from an input stream.
 *
 * An ICC_ColorSpace object can then be created to transform color values
 * through the profile.
 *
 * The ICC_Profile class implements the version 2 format specified by
 * International Color Consortium Specification ICC.1:1998-09,
 * and its addendum ICC.1A:1999-04, April 1999
 * (available at www.color.org)
 *
 * @author Sven de Marothy
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
 * @since 1.2
 */
public class ICC_Profile implements Serializable
{
  /**
   * Compatible with JDK 1.2+.
   */
  private static final long serialVersionUID = -3938515861990936766L;

  /**
   * ICC Profile classes
   */
  public static final int CLASS_INPUT = 0;
  public static final int CLASS_DISPLAY = 1;
  public static final int CLASS_OUTPUT = 2;
  public static final int CLASS_DEVICELINK = 3;
  public static final int CLASS_COLORSPACECONVERSION = 4;
  public static final int CLASS_ABSTRACT = 5;
  public static final int CLASS_NAMEDCOLOR = 6;

  /**
   * ICC Profile class signatures
   */
  public static final int icSigInputClass = 0x73636e72; // 'scnr'
  public static final int icSigDisplayClass = 0x6d6e7472; // 'mntr'
  public static final int icSigOutputClass = 0x70727472; // 'prtr'
  public static final int icSigLinkClass = 0x6c696e6b; // 'link'
  public static final int icSigColorSpaceClass = 0x73706163; // 'spac'
  public static final int icSigAbstractClass = 0x61627374; // 'abst'
  public static final int icSigNamedColorClass = 0x6e6d636c; // 'nmcl'

  /**
   * Color space signatures
   */
  public static final int icSigXYZData = 0x58595A20; // 'XYZ ' 
  public static final int icSigLabData = 0x4C616220; // 'Lab '
  public static final int icSigLuvData = 0x4C757620; // 'Luv '
  public static final int icSigYCbCrData = 0x59436272; // 'YCbr'
  public static final int icSigYxyData = 0x59787920; // 'Yxy '
  public static final int icSigRgbData = 0x52474220; // 'RGB '
  public static final int icSigGrayData = 0x47524159; // 'GRAY'
  public static final int icSigHsvData = 0x48535620; // 'HSV '
  public static final int icSigHlsData = 0x484C5320; // 'HLS '
  public static final int icSigCmykData = 0x434D594B; // 'CMYK'
  public static final int icSigCmyData = 0x434D5920; // 'CMY '
  public static final int icSigSpace2CLR = 0x32434C52; // '2CLR'
  public static final int icSigSpace3CLR = 0x33434C52; // '3CLR'
  public static final int icSigSpace4CLR = 0x34434C52; // '4CLR'
  public static final int icSigSpace5CLR = 0x35434C52; // '5CLR'
  public static final int icSigSpace6CLR = 0x36434C52; // '6CLR'
  public static final int icSigSpace7CLR = 0x37434C52; // '7CLR'
  public static final int icSigSpace8CLR = 0x38434C52; // '8CLR'
  public static final int icSigSpace9CLR = 0x39434C52; // '9CLR'
  public static final int icSigSpaceACLR = 0x41434C52; // 'ACLR'
  public static final int icSigSpaceBCLR = 0x42434C52; // 'BCLR'
  public static final int icSigSpaceCCLR = 0x43434C52; // 'CCLR'
  public static final int icSigSpaceDCLR = 0x44434C52; // 'DCLR'
  public static final int icSigSpaceECLR = 0x45434C52; // 'ECLR'
  public static final int icSigSpaceFCLR = 0x46434C52; // 'FCLR'

  /**
   * Rendering intents
   */
  public static final int icPerceptual = 0;
  public static final int icRelativeColorimetric = 1;
  public static final int icSaturation = 2;
  public static final int icAbsoluteColorimetric = 3;

  /**
   * Tag signatures
   */
  public static final int icSigAToB0Tag = 0x41324230; // 'A2B0' 
  public static final int icSigAToB1Tag = 0x41324231; // 'A2B1' 
  public static final int icSigAToB2Tag = 0x41324232; // 'A2B2' 
  public static final int icSigBlueColorantTag = 0x6258595A; // 'bXYZ' 
  public static final int icSigBlueTRCTag = 0x62545243; // 'bTRC' 
  public static final int icSigBToA0Tag = 0x42324130; // 'B2A0' 
  public static final int icSigBToA1Tag = 0x42324131; // 'B2A1' 
  public static final int icSigBToA2Tag = 0x42324132; // 'B2A2' 
  public static final int icSigCalibrationDateTimeTag = 0x63616C74; // 'calt' 
  public static final int icSigCharTargetTag = 0x74617267; // 'targ' 
  public static final int icSigCopyrightTag = 0x63707274; // 'cprt' 
  public static final int icSigCrdInfoTag = 0x63726469; // 'crdi' 
  public static final int icSigDeviceMfgDescTag = 0x646D6E64; // 'dmnd' 
  public static final int icSigDeviceModelDescTag = 0x646D6464; // 'dmdd' 
  public static final int icSigDeviceSettingsTag = 0x64657673; // 'devs' 
  public static final int icSigGamutTag = 0x67616D74; // 'gamt' 
  public static final int icSigGrayTRCTag = 0x6b545243; // 'kTRC' 
  public static final int icSigGreenColorantTag = 0x6758595A; // 'gXYZ' 
  public static final int icSigGreenTRCTag = 0x67545243; // 'gTRC' 
  public static final int icSigLuminanceTag = 0x6C756d69; // 'lumi' 
  public static final int icSigMeasurementTag = 0x6D656173; // 'meas' 
  public static final int icSigMediaBlackPointTag = 0x626B7074; // 'bkpt' 
  public static final int icSigMediaWhitePointTag = 0x77747074; // 'wtpt' 
  public static final int icSigNamedColor2Tag = 0x6E636C32; // 'ncl2' 
  public static final int icSigOutputResponseTag = 0x72657370; // 'resp' 
  public static final int icSigPreview0Tag = 0x70726530; // 'pre0' 
  public static final int icSigPreview1Tag = 0x70726531; // 'pre1' 
  public static final int icSigPreview2Tag = 0x70726532; // 'pre2' 
  public static final int icSigProfileDescriptionTag = 0x64657363; // 'desc' 
  public static final int icSigProfileSequenceDescTag = 0x70736571; // 'pseq' 
  public static final int icSigPs2CRD0Tag = 0x70736430; // 'psd0' 
  public static final int icSigPs2CRD1Tag = 0x70736431; // 'psd1' 
  public static final int icSigPs2CRD2Tag = 0x70736432; // 'psd2' 
  public static final int icSigPs2CRD3Tag = 0x70736433; // 'psd3' 
  public static final int icSigPs2CSATag = 0x70733273; // 'ps2s' 
  public static final int icSigPs2RenderingIntentTag = 0x70733269; // 'ps2i' 
  public static final int icSigRedColorantTag = 0x7258595A; // 'rXYZ' 
  public static final int icSigRedTRCTag = 0x72545243; // 'rTRC' 
  public static final int icSigScreeningDescTag = 0x73637264; // 'scrd' 
  public static final int icSigScreeningTag = 0x7363726E; // 'scrn' 
  public static final int icSigTechnologyTag = 0x74656368; // 'tech' 
  public static final int icSigUcrBgTag = 0x62666420; // 'bfd ' 
  public static final int icSigViewingCondDescTag = 0x76756564; // 'vued' 
  public static final int icSigViewingConditionsTag = 0x76696577; // 'view' 
  public static final int icSigChromaticityTag = 0x6368726D; // 'chrm'

  /**
   * Non-ICC tag 'head' for use in retrieving the header with getData()
   */
  public static final int icSigHead = 0x68656164;

  /**
   * Header offsets
   */
  public static final int icHdrSize = 0;
  public static final int icHdrCmmId = 4;
  public static final int icHdrVersion = 8;
  public static final int icHdrDeviceClass = 12;
  public static final int icHdrColorSpace = 16;
  public static final int icHdrPcs = 20;
  public static final int icHdrDate = 24;
  public static final int icHdrMagic = 36;
  public static final int icHdrPlatform = 40;
  public static final int icHdrFlags = 44;
  public static final int icHdrManufacturer = 48;
  public static final int icHdrModel = 52;
  public static final int icHdrAttributes = 56;
  public static final int icHdrRenderingIntent = 64;
  public static final int icHdrIlluminant = 68;
  public static final int icHdrCreator = 80;

  /**
   *
   */
  public static final int icTagType = 0;
  public static final int icTagReserved = 4;
  public static final int icCurveCount = 8;
  public static final int icCurveData = 12;
  public static final int icXYZNumberX = 8;

  /**
   * offset of the Tag table
   */
  private static final int tagTableOffset = 128;

  /**
   * @serial
   */
  private static final int iccProfileSerializedDataVersion = 1;

  /**
   * Constants related to generating profiles for
   * built-in colorspace profiles
   */
  /**
   * Copyright notice to stick into built-in-profile files.
   */
  private static final String copyrightNotice = "Generated by GNU Classpath.";

  /**
   * Resolution of the TRC to use for predefined profiles.
   * 1024 should suffice.
   */
  private static final int TRC_POINTS = 1024;

  /**
   * CIE 1931 D50 white point (in Lab coordinates)
   */
  private static final float[] D50 = { 0.96422f, 1.00f, 0.82521f };

  /**
   * Color space profile ID
   * Set to the predefined profile class (e.g. CS_sRGB) if a predefined
   * color space is used, set to -1 otherwise.
   * (or if the profile has been modified)
   */
  private transient int profileID;

  /**
   * The profile header data
   */
  private transient ProfileHeader header;

  /**
   * A hashtable containing the profile tags as TagEntry objects
   */
  private transient Hashtable tagTable;

  /**
   * Contructor for predefined colorspaces
   */
  ICC_Profile(int profileID)
  {
    header = null;
    tagTable = null;
    createProfile(profileID);
  }

  /**
   * Constructs an ICC_Profile from a header and a table of loaded tags.
   */
  ICC_Profile(ProfileHeader h, Hashtable tags) throws IllegalArgumentException
  {
    header = h;
    tagTable = tags;
    profileID = -1; // Not a predefined color space
  }

  /**
   * Constructs an ICC_Profile from a byte array of data.
   */
  ICC_Profile(byte[] data) throws IllegalArgumentException
  {
    // get header and verify it
    header = new ProfileHeader(data);
    header.verifyHeader(data.length);
    tagTable = createTagTable(data);
    profileID = -1; // Not a predefined color space
  }

  /**
   * Free up the used memory.
   */
  protected void finalize()
  {
  }

  /**
   * Returns an ICC_Profile instance from a byte array of profile data.
   *
   * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
   * may be returned if appropriate.
   *
   * @throws IllegalArgumentException if the profile data is an invalid
   * v2 profile.
   *
   * @param data - the profile data
   * @return An ICC_Profile object
   */
  public static ICC_Profile getInstance(byte[] data)
  {
    ProfileHeader header = new ProfileHeader(data);

    // verify it as a correct ICC header, including size
    header.verifyHeader(data.length);

    Hashtable tags = createTagTable(data);

    if (isRGBProfile(header, tags))
      return new ICC_ProfileRGB(data);
    if (isGrayProfile(header, tags))
      return new ICC_ProfileGray(data);

    return new ICC_Profile(header, tags);
  }

  /**
   * Returns an predefined ICC_Profile instance.
   *
   * This will construct an ICC_Profile instance from one of the predefined
   * color spaces in the ColorSpace class. (e.g. CS_sRGB, CS_GRAY, etc)
   *
   * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
   * may be returned if appropriate.
   *
   * @return An ICC_Profile object
   */
  public static ICC_Profile getInstance(int cspace)
  {
    if (cspace == ColorSpace.CS_sRGB || cspace == ColorSpace.CS_LINEAR_RGB)
      return new ICC_ProfileRGB(cspace);
    if (cspace == ColorSpace.CS_GRAY)
      return new ICC_ProfileGray(cspace);
    return new ICC_Profile(cspace);
  }

  /**
   * Returns an ICC_Profile instance from an ICC Profile file.
   *
   * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
   * may be returned if appropriate.
   *
   * @throws IllegalArgumentException if the profile data is an invalid
   * v2 profile.
   * @throws IOException if the file could not be read.
   *
   * @param filename - the file name of the profile file.
   * @return An ICC_Profile object
   */
  public static ICC_Profile getInstance(String filename)
                                 throws IOException
  {
    return getInstance(new FileInputStream(filename));
  }

  /**
   * Returns an ICC_Profile instance from an InputStream.
   *
   * This method can be used for reading ICC profiles embedded in files
   * which support this. (JPEG and SVG for instance).
   *
   * The stream is treated in the following way: The profile header
   * (128 bytes) is read first, and the header is validated. If the profile
   * header is valid, it will then attempt to read the rest of the profile
   * from the stream. The stream is not closed after reading.
   *
   * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
   * may be returned if appropriate.
   *
   * @throws IllegalArgumentException if the profile data is an invalid
   * v2 profile.
   * @throws IOException if the stream could not be read.
   *
   * @param in - the input stream to read the profile from.
   * @return An ICC_Profile object
   */
  public static ICC_Profile getInstance(InputStream in)
                                 throws IOException
  {
    // read the header
    byte[] headerData = new byte[ProfileHeader.HEADERSIZE];
    if (in.read(headerData) != ProfileHeader.HEADERSIZE)
      throw new IllegalArgumentException("Invalid profile header");

    ProfileHeader header = new ProfileHeader(headerData);

    // verify it as a correct ICC header, but do not verify the
    // size as we are reading from a stream.
    header.verifyHeader(-1);

    // get the size
    byte[] data = new byte[header.getSize()];
    System.arraycopy(headerData, 0, data, 0, ProfileHeader.HEADERSIZE);

    // read the rest
    if (in.read(data, ProfileHeader.HEADERSIZE,
                header.getSize() - ProfileHeader.HEADERSIZE) != header.getSize()
        - ProfileHeader.HEADERSIZE)
      throw new IOException("Incorrect profile size");

    return getInstance(data);
  }

  /**
   * Returns the major version number
   */
  public int getMajorVersion()
  {
    return header.getMajorVersion();
  }

  /**
   * Returns the minor version number.
   *
   * Only the least-significant byte contains data, in BCD form:
   * the least-significant nibble is the BCD bug fix revision,
   * the most-significant nibble is the BCD minor revision number.
   *
   * (E.g. For a v2.1.0 profile this will return <code>0x10</code>)
   */
  public int getMinorVersion()
  {
    return header.getMinorVersion();
  }

  /**
   * Returns the device class of this profile,
   *
   * (E.g. CLASS_INPUT for a scanner profile,
   * CLASS_OUTPUT for a printer)
   */
  public int getProfileClass()
  {
    return header.getProfileClass();
  }

  /**
   * Returns the color space of this profile, in terms
   * of the color space constants defined in ColorSpace.
   * (For example, it may be a ColorSpace.TYPE_RGB)
   */
  public int getColorSpaceType()
  {
    return header.getColorSpace();
  }

  /**
   * Returns the color space of this profile's Profile Connection Space (OCS)
   *
   * In terms of the color space constants defined in ColorSpace.
   * This may be TYPE_XYZ or TYPE_Lab
   */
  public int getPCSType()
  {
    return header.getProfileColorSpace();
  }

  /**
   * Writes the profile data to an ICC profile file.
   * @param filename - The name of the file to write
   * @throws IOException if the write failed.
   */
  public void write(String filename) throws IOException
  {
    FileOutputStream out = new FileOutputStream(filename);
    write(out);
    out.flush();
    out.close();
  }

  /**
   * Writes the profile data in ICC profile file-format to a stream.
   * This is useful for embedding ICC profiles in file formats which
   * support this (such as JPEG and SVG).
   *
   * The stream is not closed after writing.
   * @param out - The outputstream to which the profile data should be written
   * @throws IOException if the write failed.
   */
  public void write(OutputStream out) throws IOException
  {
    out.write(getData());
  }

  /**
   * Returns the data corresponding to this ICC_Profile as a byte array.
   *
   * @return The data in a byte array,
   * where the first element corresponds to first byte of the profile file.
   */
  public byte[] getData()
  {
    int size = getSize();
    byte[] data = new byte[size];

    // Header
    System.arraycopy(header.getData(size), 0, data, 0, ProfileHeader.HEADERSIZE);
    // # of tags
    byte[] tt = getTagTable();
    System.arraycopy(tt, 0, data, ProfileHeader.HEADERSIZE, tt.length);

    Enumeration e = tagTable.elements();
    while (e.hasMoreElements())
      {
	TagEntry tag = (TagEntry) e.nextElement();
	System.arraycopy(tag.getData(), 0, 
			 data, tag.getOffset(), tag.getSize());
      }
    return data;
  }

  /**
   * Returns the ICC profile tag data
   * The non ICC-tag icSigHead is also permitted to request the header data.
   *
   * @param tagSignature The ICC signature of the requested tag
   * @return A byte array containing the tag data
   */
  public byte[] getData(int tagSignature)
  {
    if (tagSignature == icSigHead)
      return header.getData(getSize());

    TagEntry t = (TagEntry) tagTable.get(TagEntry.tagHashKey(tagSignature));
    if (t == null)
      return null;
    return t.getData();
  }

  /**
   * Sets the ICC profile tag data.
   *
   * Note that an ICC profile can only contain one tag of each type, if
   * a tag already exists with the given signature, it is replaced.
   *
   * @param tagSignature - The signature of the tag to set
   * @param data - A byte array containing the tag data
   */
  public void setData(int tagSignature, byte[] data)
  {
    profileID = -1; // Not a predefined color space if modified.

    if (tagSignature == icSigHead)
      header = new ProfileHeader(data);
    else
      {
	TagEntry t = new TagEntry(tagSignature, data);
	tagTable.put(t.hashKey(), t);
      }
  }

  /**
   * Get the number of components in the profile's device color space.
   */
  public int getNumComponents()
  {
    int[] lookup = 
                   {
                     ColorSpace.TYPE_RGB, 3, ColorSpace.TYPE_CMY, 3,
                     ColorSpace.TYPE_CMYK, 4, ColorSpace.TYPE_GRAY, 1,
                     ColorSpace.TYPE_YCbCr, 3, ColorSpace.TYPE_XYZ, 3,
                     ColorSpace.TYPE_Lab, 3, ColorSpace.TYPE_HSV, 3,
                     ColorSpace.TYPE_2CLR, 2, ColorSpace.TYPE_Luv, 3,
                     ColorSpace.TYPE_Yxy, 3, ColorSpace.TYPE_HLS, 3,
                     ColorSpace.TYPE_3CLR, 3, ColorSpace.TYPE_4CLR, 4,
                     ColorSpace.TYPE_5CLR, 5, ColorSpace.TYPE_6CLR, 6,
                     ColorSpace.TYPE_7CLR, 7, ColorSpace.TYPE_8CLR, 8,
                     ColorSpace.TYPE_9CLR, 9, ColorSpace.TYPE_ACLR, 10,
                     ColorSpace.TYPE_BCLR, 11, ColorSpace.TYPE_CCLR, 12,
                     ColorSpace.TYPE_DCLR, 13, ColorSpace.TYPE_ECLR, 14,
                     ColorSpace.TYPE_FCLR, 15
                   };
    for (int i = 0; i < lookup.length; i += 2)
      if (header.getColorSpace() == lookup[i])
	return lookup[i + 1];
    return 3; // should never happen.
  }

  /**
   * After deserializing we must determine if the class we want
   * is really one of the more specialized ICC_ProfileRGB or
   * ICC_ProfileGray classes.
   */
  protected Object readResolve() throws ObjectStreamException
  {
    if (isRGBProfile(header, tagTable))
      return new ICC_ProfileRGB(getData());
    if (isGrayProfile(header, tagTable))
      return new ICC_ProfileGray(getData());
    return this;
  }

  /**
   * Deserializes an instance
   */
  private void readObject(ObjectInputStream s)
                   throws IOException, ClassNotFoundException
  {
    s.defaultReadObject();
    String predef = (String) s.readObject();
    byte[] data = (byte[]) s.readObject();

    if (data != null)
      {
	header = new ProfileHeader(data);
	tagTable = createTagTable(data);
	profileID = -1; // Not a predefined color space
      }

    if (predef != null)
      {
	predef = predef.intern();
	if (predef.equals("CS_sRGB"))
	  createProfile(ColorSpace.CS_sRGB);
	if (predef.equals("CS_LINEAR_RGB"))
	  createProfile(ColorSpace.CS_LINEAR_RGB);
	if (predef.equals("CS_CIEXYZ"))
	  createProfile(ColorSpace.CS_CIEXYZ);
	if (predef.equals("CS_GRAY"))
	  createProfile(ColorSpace.CS_GRAY);
	if (predef.equals("CS_PYCC"))
	  createProfile(ColorSpace.CS_PYCC);
      }
  }

  /**
   * Serializes an instance
   * The format is a String and a byte array,
   * The string is non-null if the instance is one of the built-in profiles.
   * Otherwise the byte array is non-null and represents the profile data.
   */
  private void writeObject(ObjectOutputStream s) throws IOException
  {
    s.defaultWriteObject();
    if (profileID == ColorSpace.CS_sRGB)
      s.writeObject("CS_sRGB");
    else if (profileID == ColorSpace.CS_LINEAR_RGB)
      s.writeObject("CS_LINEAR_RGB");
    else if (profileID == ColorSpace.CS_CIEXYZ)
      s.writeObject("CS_CIEXYZ");
    else if (profileID == ColorSpace.CS_GRAY)
      s.writeObject("CS_GRAY");
    else if (profileID == ColorSpace.CS_PYCC)
      s.writeObject("CS_PYCC");
    else
      {
	s.writeObject(null); // null string
	s.writeObject(getData()); // data
	return;
      }
    s.writeObject(null); // null data
  }

  /**
   * Sorts a ICC profile byte array into TagEntry objects stored in
   * a hash table.
   */
  private static Hashtable createTagTable(byte[] data)
                                   throws IllegalArgumentException
  {
    ByteBuffer buf = ByteBuffer.wrap(data);
    int nTags = buf.getInt(tagTableOffset);

    Hashtable tagTable = new Hashtable();
    for (int i = 0; i < nTags; i++)
      {
	TagEntry te = new TagEntry(buf.getInt(tagTableOffset
	                                      + i * TagEntry.entrySize + 4),
	                           buf.getInt(tagTableOffset
	                                      + i * TagEntry.entrySize + 8),
	                           buf.getInt(tagTableOffset
	                                      + i * TagEntry.entrySize + 12),
	                           data);

	if (tagTable.put(te.hashKey(), te) != null)
	  throw new IllegalArgumentException("Duplicate tag in profile:" + te);
      }
    return tagTable;
  }

  /**
   * Returns the total size of the padded, stored data
   * Note: Tags must be stored on 4-byte aligned offsets.
   */
  private int getSize()
  {
    int totalSize = ProfileHeader.HEADERSIZE; // size of header

    int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize; // size of tag table	
    if ((tagTableSize & 0x0003) != 0)
      tagTableSize += 4 - (tagTableSize & 0x0003); // pad
    totalSize += tagTableSize;

    Enumeration e = tagTable.elements();
    while (e.hasMoreElements())
      { // tag data
	int tagSize = ((TagEntry) e.nextElement()).getSize();
	if ((tagSize & 0x0003) != 0)
	  tagSize += 4 - (tagSize & 0x0003); // pad
	totalSize += tagSize;
      }
    return totalSize;
  }

  /**
   * Generates the tag index table
   */
  private byte[] getTagTable()
  {
    int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize;
    if ((tagTableSize & 0x0003) != 0)
      tagTableSize += 4 - (tagTableSize & 0x0003); // pad 

    int offset = 4;
    int tagOffset = ProfileHeader.HEADERSIZE + tagTableSize;
    ByteBuffer buf = ByteBuffer.allocate(tagTableSize);
    buf.putInt(tagTable.size()); // number of tags

    Enumeration e = tagTable.elements();
    while (e.hasMoreElements())
      {
	TagEntry tag = (TagEntry) e.nextElement();
	buf.putInt(offset, tag.getSignature());
	buf.putInt(offset + 4, tagOffset);
	buf.putInt(offset + 8, tag.getSize());
	tag.setOffset(tagOffset);
	int tagSize = tag.getSize();
	if ((tagSize & 0x0003) != 0)
	  tagSize += 4 - (tagSize & 0x0003); // pad	    
	tagOffset += tagSize;
	offset += 12;
      }
    return buf.array();
  }

  /**
   * Returns if the criteria for an ICC_ProfileRGB are met.
   * This means:
   * Color space is TYPE_RGB
   * (r,g,b)ColorantTags included
   * (r,g,b)TRCTags included
   * mediaWhitePointTag included
   */
  private static boolean isRGBProfile(ProfileHeader header, Hashtable tags)
  {
    if (header.getColorSpace() != ColorSpace.TYPE_RGB)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigRedColorantTag)) == null)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigGreenColorantTag)) == null)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigBlueColorantTag)) == null)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigRedTRCTag)) == null)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigGreenTRCTag)) == null)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigBlueTRCTag)) == null)
      return false;
    return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
  }

  /**
   * Returns if the criteria for an ICC_ProfileGray are met.
   * This means:
   * Colorspace is TYPE_GRAY
   * grayTRCTag included
   * mediaWhitePointTag included
   */
  private static boolean isGrayProfile(ProfileHeader header, Hashtable tags)
  {
    if (header.getColorSpace() != ColorSpace.TYPE_GRAY)
      return false;
    if (tags.get(TagEntry.tagHashKey(icSigGrayTRCTag)) == null)
      return false;
    return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
  }

  /**
   * Returns curve data for a 'curv'-type tag
   * If it's a gamma curve, a single entry will be returned with the
   * gamma value (including 1.0 for linear response)
   * Otherwise the TRC table is returned.
   *
   * (Package private - used by ICC_ProfileRGB and ICC_ProfileGray)
   */
  short[] getCurve(int signature)
  {
    byte[] data = getData(signature);
    short[] curve;

    // can't find tag?
    if (data == null)
      return null;

    // not an curve type tag?
    ByteBuffer buf = ByteBuffer.wrap(data);
    if (buf.getInt(0) != 0x63757276) // 'curv' type
      return null;
    int count = buf.getInt(8);
    if (count == 0)
      {
	curve = new short[1];
	curve[0] = 0x0100; // 1.00 in u8fixed8
	return curve;
      }
    if (count == 1)
      {
	curve = new short[1];
	curve[0] = buf.getShort(12); // other u8fixed8 gamma
	return curve;
      }
    curve = new short[count];
    for (int i = 0; i < count; i++)
      curve[i] = buf.getShort(12 + i * 2);
    return curve;
  }

  /**
   * Returns XYZ tristimulus values for an 'XYZ ' type tag
   * @return the XYZ values, or null if the tag was not an 'XYZ ' type tag.
   *
   * (Package private - used by ICC_ProfileXYZ and ICC_ProfileGray)
   */
  float[] getXYZData(int signature)
  {
    byte[] data = getData(signature);

    // can't find tag?
    if (data == null)
      return null;

    // not an XYZData type tag?
    ByteBuffer buf = ByteBuffer.wrap(data);
    if (buf.getInt(0) != icSigXYZData) // 'XYZ ' type
      return null;

    float[] point = new float[3];

    // get the X,Y,Z tristimulus values
    point[0] = ((float) buf.getInt(8)) / 65536f;
    point[1] = ((float) buf.getInt(12)) / 65536f;
    point[2] = ((float) buf.getInt(16)) / 65536f;
    return point;
  }

  /**
   * Returns the profile ID if it's a predefined profile
   * Or -1 for a profile loaded from an ICC profile
   *
   * (Package private - used by ICC_ColorSpace)
   */
  int isPredefined()
  {
    return profileID;
  }

  /**
   * Creates a tag of XYZ-value type.
   */
  private byte[] makeXYZData(float[] values)
  {
    ByteBuffer buf = ByteBuffer.allocate(20);
    buf.putInt(0, icSigXYZData); // 'XYZ '
    buf.putInt(4, 0);
    buf.putInt(8, (int) (values[0] * 65536.0));
    buf.putInt(12, (int) (values[1] * 65536.0));
    buf.putInt(16, (int) (values[2] * 65536.0));
    return buf.array();
  }

  /**
   * Creates a tag of text type
   */
  private byte[] makeTextTag(String text)
  {
    int length = text.length();
    ByteBuffer buf = ByteBuffer.allocate(8 + length + 1);
    byte[] data;
    try
      {
	data = text.getBytes("US-ASCII");
      }
    catch (UnsupportedEncodingException e)
      {
	data = new byte[length]; // shouldn't happen
      }

    buf.putInt(0, (int) 0x74657874); // 'text'
    buf.putInt(4, 0);
    for (int i = 0; i < length; i++)
      buf.put(8 + i, data[i]);
    buf.put(8 + length, (byte) 0); // null-terminate
    return buf.array();
  }

  /**
   * Creates a tag of textDescriptionType
   */
  private byte[] makeDescTag(String text)
  {
    int length = text.length();
    ByteBuffer buf = ByteBuffer.allocate(90 + length + 1);
    buf.putInt(0, (int) 0x64657363); // 'desc'
    buf.putInt(4, 0); // reserved 
    buf.putInt(8, length + 1); // ASCII length, including null termination
    byte[] data;

    try
      {
	data = text.getBytes("US-ASCII");
      }
    catch (UnsupportedEncodingException e)
      {
	data = new byte[length]; // shouldn't happen
      }

    for (int i = 0; i < length; i++)
      buf.put(12 + i, data[i]);
    buf.put(12 + length, (byte) 0); // null-terminate

    for (int i = 0; i < 39; i++)
      buf.putShort(13 + length + (i * 2), (short) 0); // 78 bytes we can ignore

    return buf.array();
  }

  /**
   * Creates a tag of TRC type (linear curve)
   */
  private byte[] makeTRC()
  {
    ByteBuffer buf = ByteBuffer.allocate(12);
    buf.putInt(0, 0x63757276); // 'curv' type
    buf.putInt(4, 0); // reserved
    buf.putInt(8, 0);
    return buf.array();
  }

  /**
   * Creates a tag of TRC type (single gamma value)
   */
  private byte[] makeTRC(float gamma)
  {
    short gammaValue = (short) (gamma * 256f);
    ByteBuffer buf = ByteBuffer.allocate(14);
    buf.putInt(0, 0x63757276); // 'curv' type
    buf.putInt(4, 0); // reserved
    buf.putInt(8, 1);
    buf.putShort(12, gammaValue); // 1.00 in u8fixed8
    return buf.array();
  }

  /**
   * Creates a tag of TRC type (TRC curve points)
   */
  private byte[] makeTRC(float[] trc)
  {
    ByteBuffer buf = ByteBuffer.allocate(12 + 2 * trc.length);
    buf.putInt(0, 0x63757276); // 'curv' type
    buf.putInt(4, 0); // reserved
    buf.putInt(8, trc.length); // number of points

    // put the curve values 
    for (int i = 0; i < trc.length; i++)
      buf.putShort(12 + i * 2, (short) (trc[i] * 65535f));

    return buf.array();
  }

  /**
   * Creates an identity color lookup table.
   */
  private byte[] makeIdentityClut()
  {
    final int nIn = 3;
    final int nOut = 3;
    final int nInEntries = 256;
    final int nOutEntries = 256;
    final int gridpoints = 16;

    // gridpoints**nIn
    final int clutSize = 2 * nOut * gridpoints * gridpoints * gridpoints;
    final int totalSize = clutSize + 2 * nInEntries * nIn
                          + 2 * nOutEntries * nOut + 52;

    ByteBuffer buf = ByteBuffer.allocate(totalSize);
    buf.putInt(0, 0x6D667432); // 'mft2'
    buf.putInt(4, 0); // reserved
    buf.put(8, (byte) nIn); // number input channels
    buf.put(9, (byte) nOut); // number output channels
    buf.put(10, (byte) gridpoints); // number gridpoints
    buf.put(11, (byte) 0); // padding

    // identity matrix
    buf.putInt(12, 65536); // = 1 in s15.16 fixed point
    buf.putInt(16, 0);
    buf.putInt(20, 0);
    buf.putInt(24, 0);
    buf.putInt(28, 65536);
    buf.putInt(32, 0);
    buf.putInt(36, 0);
    buf.putInt(40, 0);
    buf.putInt(44, 65536);

    buf.putShort(48, (short) nInEntries); // input table entries
    buf.putShort(50, (short) nOutEntries); // output table entries

    // write the linear input channels, unsigned 16.16 fixed point,
    // from 0.0 to FF.FF
    for (int channel = 0; channel < 3; channel++)
      for (int i = 0; i < nInEntries; i++)
        {
	  short n = (short) ((i << 8) | i); // assumes 256 entries
	  buf.putShort(52 + (channel * nInEntries + i) * 2, n);
        }
    int clutOffset = 52 + nInEntries * nIn * 2;

    for (int x = 0; x < gridpoints; x++)
      for (int y = 0; y < gridpoints; y++)
	for (int z = 0; z < gridpoints; z++)
	  {
	    int offset = clutOffset + z * 2 * nOut + y * gridpoints * 2 * nOut
	                 + x * gridpoints * gridpoints * 2 * nOut;
	    double xf = ((double) x) / ((double) gridpoints - 1.0);
	    double yf = ((double) y) / ((double) gridpoints - 1.0);
	    double zf = ((double) z) / ((double) gridpoints - 1.0);
	    buf.putShort(offset, (short) (xf * 65535.0));
	    buf.putShort(offset + 2, (short) (yf * 65535.0));
	    buf.putShort(offset + 4, (short) (zf * 65535.0));
	  }

    for (int channel = 0; channel < 3; channel++)
      for (int i = 0; i < nOutEntries; i++)
        {
	  short n = (short) ((i << 8) | i); // assumes 256 entries
	  buf.putShort(clutOffset + clutSize + (channel * nOutEntries + i) * 2,
	               n);
        }

    return buf.array();
  }

  /**
   * Creates profile data corresponding to the built-in colorspaces.
   */
  private void createProfile(int colorSpace) throws IllegalArgumentException
  {
    this.profileID = colorSpace;
    header = new ProfileHeader();
    tagTable = new Hashtable();

    switch (colorSpace)
      {
      case ColorSpace.CS_sRGB:
	createRGBProfile();
	return;
      case ColorSpace.CS_LINEAR_RGB:
	createLinearRGBProfile();
	return;
      case ColorSpace.CS_CIEXYZ:
	createCIEProfile();
	return;
      case ColorSpace.CS_GRAY:
	createGrayProfile();
	return;
      case ColorSpace.CS_PYCC:
	createPyccProfile();
	return;
      default:
	throw new IllegalArgumentException("Not a predefined color space!");
      }
  }

  /**
   * Creates an ICC_Profile representing the sRGB color space
   */
  private void createRGBProfile()
  {
    header.setColorSpace( ColorSpace.TYPE_RGB );
    header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
    ICC_ColorSpace cs = new ICC_ColorSpace(this);

    float[] r = { 1f, 0f, 0f };
    float[] g = { 0f, 1f, 0f };
    float[] b = { 0f, 0f, 1f };
    float[] black = { 0f, 0f, 0f };

    // CIE 1931 D50 white point (in Lab coordinates)
    float[] white = D50;

    // Get tristimulus values (matrix elements)
    r = cs.toCIEXYZ(r);
    g = cs.toCIEXYZ(g);
    b = cs.toCIEXYZ(b);

    // Generate the sRGB TRC curve, this is the linear->nonlinear
    // RGB transform.
    cs = new ICC_ColorSpace(getInstance(ICC_ColorSpace.CS_LINEAR_RGB));
    float[] points = new float[TRC_POINTS];
    float[] in = new float[3];
    for (int i = 0; i < TRC_POINTS; i++)
      {
	in[0] = in[1] = in[2] = ((float) i) / ((float) TRC_POINTS - 1);
	in = cs.fromRGB(in);
	// Note this value is the same for all components.
	points[i] = in[0];
      }

    setData(icSigRedColorantTag, makeXYZData(r));
    setData(icSigGreenColorantTag, makeXYZData(g));
    setData(icSigBlueColorantTag, makeXYZData(b));
    setData(icSigMediaWhitePointTag, makeXYZData(white));
    setData(icSigMediaBlackPointTag, makeXYZData(black));
    setData(icSigRedTRCTag, makeTRC(points));
    setData(icSigGreenTRCTag, makeTRC(points));
    setData(icSigBlueTRCTag, makeTRC(points));
    setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
    setData(icSigProfileDescriptionTag, makeDescTag("Generic sRGB"));
    this.profileID = ColorSpace.CS_sRGB;
  }

  /**
   * Creates an linear sRGB profile
   */
  private void createLinearRGBProfile()
  {
    header.setColorSpace(ColorSpace.TYPE_RGB);
    header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
    ICC_ColorSpace cs = new ICC_ColorSpace(this);

    float[] r = { 1f, 0f, 0f };
    float[] g = { 0f, 1f, 0f };
    float[] b = { 0f, 0f, 1f };
    float[] black = { 0f, 0f, 0f };

    float[] white = D50;

    // Get tristimulus values (matrix elements)
    r = cs.toCIEXYZ(r);
    g = cs.toCIEXYZ(g);
    b = cs.toCIEXYZ(b);

    setData(icSigRedColorantTag, makeXYZData(r));
    setData(icSigGreenColorantTag, makeXYZData(g));
    setData(icSigBlueColorantTag, makeXYZData(b));

    setData(icSigMediaWhitePointTag, makeXYZData(white));
    setData(icSigMediaBlackPointTag, makeXYZData(black));

    setData(icSigRedTRCTag, makeTRC());
    setData(icSigGreenTRCTag, makeTRC());
    setData(icSigBlueTRCTag, makeTRC());
    setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
    setData(icSigProfileDescriptionTag, makeDescTag("Linear RGB"));
    this.profileID = ColorSpace.CS_LINEAR_RGB;
  }

  /**
   * Creates an CIE XYZ identity profile
   */
  private void createCIEProfile()
  {
    header.setColorSpace( ColorSpace.TYPE_XYZ );
    header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
    header.setProfileClass( CLASS_COLORSPACECONVERSION );
    ICC_ColorSpace cs = new ICC_ColorSpace(this);

    float[] white = D50;

    setData(icSigMediaWhitePointTag, makeXYZData(white));
    setData(icSigAToB0Tag, makeIdentityClut());
    setData(icSigBToA0Tag, makeIdentityClut());
    setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
    setData(icSigProfileDescriptionTag, makeDescTag("CIE XYZ identity profile"));
    this.profileID = ColorSpace.CS_CIEXYZ;
  }

  /**
   * Creates a linear gray ICC_Profile
   */
  private void createGrayProfile()
  {
    header.setColorSpace(ColorSpace.TYPE_GRAY);
    header.setProfileColorSpace(ColorSpace.TYPE_XYZ);

    // CIE 1931 D50 white point (in Lab coordinates)
    float[] white = D50;

    setData(icSigMediaWhitePointTag, makeXYZData(white));
    setData(icSigGrayTRCTag, makeTRC(1.0f));
    setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
    setData(icSigProfileDescriptionTag, makeDescTag("Linear grayscale"));
    this.profileID = ColorSpace.CS_GRAY;
  }

  /**
   * XXX Implement me
   */
  private void createPyccProfile()
  {
    header.setColorSpace(ColorSpace.TYPE_3CLR);
    header.setProfileColorSpace(ColorSpace.TYPE_XYZ);

    // Create CLUTs here. :-)

    setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
    setData(icSigProfileDescriptionTag, makeDescTag("Photo YCC"));
    this.profileID = ColorSpace.CS_PYCC;
  }
} // class ICC_Profile
