Package ucar.jpeg.icc

Source Code of ucar.jpeg.icc.ICCProfile$BoxType

/*****************************************************************************
*
* $Id: ICCProfile.java,v 1.1 2002/07/25 14:56:55 grosbois Exp $
*
* Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650
* $Date $
*****************************************************************************/

package ucar.jpeg.icc;

import java.io.File;
import java.io.RandomAccessFile;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import ucar.jpeg.jj2000.j2k.util.ParameterList;
import ucar.jpeg.jj2000.j2k.decoder.DecoderSpecs;
import ucar.jpeg.jj2000.j2k.codestream.reader.BitstreamReaderAgent;
import ucar.jpeg.colorspace .ColorSpace;
import ucar.jpeg.colorspace .ColorSpaceException;
import ucar.jpeg.icc .types.ICCProfileHeader;
import ucar.jpeg.icc .tags.ICCTag;
import ucar.jpeg.icc .tags.ICCTagTable;
import ucar.jpeg.icc .tags.ICCCurveType;
import ucar.jpeg.icc .tags.ICCXYZType;
import ucar.jpeg.icc .types.XYZNumber;
import ucar.jpeg.icc .types.ICCProfileVersion;
import ucar.jpeg.icc .types.ICCDateTime;
import ucar.jpeg.jj2000.j2k.fileformat.FileFormatBoxes;
import ucar.jpeg.jj2000.j2k.io.RandomAccessIO;
import ucar.jpeg.jj2000.j2k.util.FacilityManager;
import ucar.jpeg.jj2000.j2k.util.MsgLogger;
import ucar.jpeg.jj2000.j2k.fileformat.FileFormatBoxes;

/**
*  This class models the ICCProfile file.  This file is a binary file which is divided
*  into two parts, an ICCProfileHeader followed by an ICCTagTable. The header is a
*  straightforward list of descriptive parameters such as profile size, version, date and various
*  more esoteric parameters.  The tag table is a structured list of more complexly aggragated data
*  describing things such as ICC curves, copyright information, descriptive text blocks, etc.
*
*  Classes exist to model the header and tag table and their various constituent parts the developer
*  is refered to these for further information on the structure and contents of the header and tag table.
*
* @see    jj2000.j2k.icc.types.ICCProfileHeader
* @see    jj2000.j2k.icc.tags.ICCTagTable
* @version  1.0
* @author  Bruce A. Kern
*/

public abstract class ICCProfile {
       
    private static final String eol = System.getProperty("line.separator");

    // Renamed for convenience:
    /** Gray index. */ public static final int GRAY  = 0;
    /** RGB index.  */ public static final int RED   = 0;
    /** RGB index.  */ public static final int GREEN = 1;
    /** RGB index.  */ public static final int BLUE  = 2;

    /** Size of native type */ public final static int boolean_size = 1;
    /** Size of native type */ public final static int byte_size = 1;
    /** Size of native type */ public final static int char_size = 2;
    /** Size of native type */ public final static int short_size = 2;
    /** Size of native type */ public final static int int_size = 4;
    /** Size of native type */ public final static int float_size = 4;
    /** Size of native type */ public final static int long_size = 8;
    /** Size of native type */ public final static int double_size = 8;

    /* Bit twiddling constant for integral types. */ public final static int BITS_PER_BYTE  = 8;
    /* Bit twiddling constant for integral types. */ public final static int BITS_PER_SHORT = 16;
    /* Bit twiddling constant for integral types. */ public final static int BITS_PER_INT   = 32;
    /* Bit twiddling constant for integral types. */ public final static int BITS_PER_LONG  = 64;
    /* Bit twiddling constant for integral types. */ public final static int BYTES_PER_SHORT  = 2;
    /* Bit twiddling constant for integral types. */ public final static int BYTES_PER_INT  = 4;
    /* Bit twiddling constant for integral types. */ public final static int BYTES_PER_LONG  = 8;

    /* JP2 Box structure analysis help */

    private static class BoxType extends java.util.Hashtable {

        private static java.util.Hashtable map = new java.util.Hashtable();

        static {
            put (FileFormatBoxes.BITS_PER_COMPONENT_BOX,"BITS_PER_COMPONENT_BOX");
            put (FileFormatBoxes.CAPTURE_RESOLUTION_BOX,"CAPTURE_RESOLUTION_BOX");
            put (FileFormatBoxes.CHANNEL_DEFINITION_BOX,"CHANNEL_DEFINITION_BOX");
            put (FileFormatBoxes.COLOUR_SPECIFICATION_BOX,"COLOUR_SPECIFICATION_BOX");
            put (FileFormatBoxes.COMPONENT_MAPPING_BOX,"COMPONENT_MAPPING_BOX");
            put (FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX,"CONTIGUOUS_CODESTREAM_BOX");
            put (FileFormatBoxes.DEFAULT_DISPLAY_RESOLUTION_BOX,"DEFAULT_DISPLAY_RESOLUTION_BOX");
            put (FileFormatBoxes.FILE_TYPE_BOX,"FILE_TYPE_BOX");
            put (FileFormatBoxes.IMAGE_HEADER_BOX,"IMAGE_HEADER_BOX");
            put (FileFormatBoxes.INTELLECTUAL_PROPERTY_BOX,"INTELLECTUAL_PROPERTY_BOX");
            put (FileFormatBoxes.JP2_HEADER_BOX,"JP2_HEADER_BOX");
            put (FileFormatBoxes.JP2_SIGNATURE_BOX,"JP2_SIGNATURE_BOX");
            put (FileFormatBoxes.PALETTE_BOX,"PALETTE_BOX");
            put (FileFormatBoxes.RESOLUTION_BOX,"RESOLUTION_BOX");
            put (FileFormatBoxes.URL_BOX,"URL_BOX");
            put (FileFormatBoxes.UUID_BOX,"UUID_BOX");
            put (FileFormatBoxes.UUID_INFO_BOX,"UUID_INFO_BOX");
            put (FileFormatBoxes.UUID_LIST_BOX,"UUID_LIST_BOX");
            put (FileFormatBoxes.XML_BOX,"XML_BOX"); }

        public static void put (int type, String desc) {
            map.put (new Integer (type), desc); }

        public static String get (int type) {
            return (String) map.get (new Integer(type));}

        public static String colorSpecMethod(int meth) {
            switch (meth) {
            case 2: return "Restricted ICC Profile";
            case 1: return "Enumerated Color Space";
            default: return "Undefined Color Spec Method"; }}}


    /**
     * Creates an int from a 4 character String
     *   @param fourChar string representation of an integer
     * @return the integer which is denoted by the input String.
     */
    public static int getIntFromString (String fourChar) {
        byte [] bytes = fourChar.getBytes();
        return getInt (bytes,0); }
    /**
     * Create an XYZNumber from byte [] input
     *   @param data array containing the XYZNumber representation
     *   @param offset start of the rep in the array
     * @return the created XYZNumber
     */
    public static XYZNumber getXYZNumber (byte [] data, int offset) {
        int x,y,z;
        x = getInt (data,offset);
        y = getInt (data,offset+int_size);
        z = getInt (data,offset+2*int_size);
        return new XYZNumber (x,y,z); }

    /**
     * Create an ICCProfileVersion from byte [] input
     *   @param data array containing the ICCProfileVersion representation
     *   @param offset start of the rep in the array
     * @return  the created ICCProfileVersion
     */
    public static ICCProfileVersion getICCProfileVersion (byte [] data, int offset) {
        byte major = data [offset];
        byte minor = data [offset+byte_size];
        byte resv1 = data [offset+2*byte_size];
        byte resv2 = data [offset+3*byte_size];
        return new ICCProfileVersion (major, minor, resv1, resv2); }

    /**
     * Create an ICCDateTime from byte [] input
     *   @param data array containing the ICCProfileVersion representation
     *   @param offset start of the rep in the array
     * @return the created ICCProfileVersion
     */
    public static ICCDateTime getICCDateTime (byte [] data, int offset) {
        short wYear    = getShort(data, offset);     // Number of the actual year (i.e. 1994)
        short wMonth   = getShort(data, offset+ICCProfile.short_size);   // Number of the month (1-12)
        short wDay     = getShort(data, offset+2*ICCProfile.short_size);   // Number of the day
        short wHours   = getShort(data, offset+3*ICCProfile.short_size);   // Number of hours (0-23)
        short wMinutes = getShort(data, offset+4*ICCProfile.short_size);   // Number of minutes (0-59)
        short wSeconds = getShort(data, offset+5*ICCProfile.short_size);   // Number of seconds (0-59)
        return new ICCDateTime (wYear, wMonth, wDay, wHours, wMinutes, wSeconds); }


    /**
     * Create a String from a byte []. Optionally swap adjacent byte
     * pairs.  Intended to be used to create integer String representations
     * allowing for endian translations.
     *   @param bfr data array
     *   @param offset start of data in array
     *   @param length length of data in array
     *   @param swap swap adjacent bytes?
     * @return String rep of data
     */
    public static String getString (byte [] bfr, int offset, int length, boolean swap) {

        byte [] result = new byte [length];
        int incr = swap ? -1 : 1;
        int start = swap ? offset+length-1 : offset;
        for (int i=0, j=start; i<length; ++i) {
            result[i] = bfr [j];
            j += incr; }
        return new String (result); }

    /**
     * Create a short from a two byte [], with optional byte swapping.
     *   @param bfr data array
     *   @param off start of data in array
     *   @param swap swap bytes?
     * @return native type from representation.
     */
    public static short getShort (byte [] bfr, int off, boolean swap) {
           
        int tmp0 = bfr [off] & 0xff; // Clear the sign extended bits in the int.
        int tmp1 = bfr [off+1] & 0xff;
           
           
        return (short) (swap ?
                        (tmp1 << BITS_PER_BYTE | tmp0):
                        (tmp0 << BITS_PER_BYTE | tmp1)); }

    /**
     * Create a short from a two byte [].
     *   @param bfr data array
     *   @param off start of data in array
     * @return native type from representation.
     */
    public static short getShort (byte [] bfr, int off) {
        int tmp0 = bfr [off] & 0xff; // Clear the sign extended bits in the int.
        int tmp1 = bfr [off+1] & 0xff;
        return (short) (tmp0 << BITS_PER_BYTE | tmp1); }

    /**
     * Separate bytes in an int into a byte array lsb to msb order.
     *   @param d integer to separate
     * @return byte [] containing separated int.
     */
    public static byte[] setInt (int d) {
        return setInt(d, new byte [BYTES_PER_INT]); }

    /**
     * Separate bytes in an int into a byte array lsb to msb order.
     * Return the result in the provided array
     *   @param d integer to separate
     *   @param b return output here.
     * @return reference to output.
     */
    public static byte[] setInt (int d, byte [] b) {
        if (b==null) b = new byte [BYTES_PER_INT];
        for (int i=0;i<BYTES_PER_INT;++i) {
            b[i] = (byte) (d & 0x0ff);
            d = d >> BITS_PER_BYTE; }
        return b; }

    /**
     * Separate bytes in a long into a byte array lsb to msb order.
     *   @param d long to separate
     * @return byte [] containing separated int.
     */
    public static byte[] setLong (long d) {
        return setLong(d, new byte [BYTES_PER_INT]); }

    /**
     * Separate bytes in a long into a byte array lsb to msb order.
     * Return the result in the provided array
     *   @param d long to separate
     *   @param b return output here.
     * @return reference to output.
     */
    public static byte[] setLong (long d, byte [] b) {
        if (b==null) b = new byte [BYTES_PER_LONG];
        for (int i=0;i<BYTES_PER_LONG;++i) {
            b[i] = (byte) (d & 0x0ff);
            d = d >> BITS_PER_BYTE; }
        return b; }
       

    /**
     * Create an int from a byte [4], with optional byte swapping.
     *   @param bfr data array
     *   @param off start of data in array
     *   @param swap swap bytes?
     * @return native type from representation.
     */
    public static int getInt (byte [] bfr, int off, boolean swap) {

        int tmp0 = getShort (bfr, off, swap)   & 0xffff; // Clear the sign extended bits in the int.
        int tmp1 = getShort (bfr, off+2, swap) & 0xffff;

        return (int) (swap ?
                      (tmp1 << BITS_PER_SHORT | tmp0):
                      (tmp0 << BITS_PER_SHORT | tmp1)); }

    /**
     * Create an int from a byte [4].
     *   @param bfr data array
     *   @param off start of data in array
     * @return native type from representation.
     */
    public static int getInt (byte [] bfr, int off) {

        int tmp0 = getShort (bfr, off)   & 0xffff; // Clear the sign extended bits in the int.
        int tmp1 = getShort (bfr, off+2) & 0xffff;

        return (int) (tmp0 << BITS_PER_SHORT | tmp1); }

    /**
     * Create an long from a byte [8].
     *   @param bfr data array
     *   @param off start of data in array
     * @return native type from representation.
     */
    public static long getLong (byte [] bfr, int off) {

        long tmp0 = getInt (bfr, off)   & 0xffffffff; // Clear the sign extended bits in the int.
        long tmp1 = getInt (bfr, off+4) & 0xffffffff;

        return (long) (tmp0 << BITS_PER_INT | tmp1); }


    // Define the set of standard signature and type values
    // Because of the endian issues and byte swapping, the profile codes must
    // be stored in memory and be addressed by address. As such, only those
    // codes required for Restricted ICC use are defined here

    /** signature    */ public final static int kdwProfileSignature  = ICCProfile.getInt(new String ("acsp").getBytes(), 0);
    /** signature    */ public final static int kdwProfileSigReverse = ICCProfile.getInt(new String ("psca").getBytes(), 0);
    /** profile type */ public final static int kdwInputProfile      = ICCProfile.getInt(new String ("scnr").getBytes(), 0);
    /** tag type     */ public final static int kdwDisplayProfile    = ICCProfile.getInt(new String ("mntr").getBytes(), 0);
    /** tag type     */ public final static int kdwRGBData       = ICCProfile.getInt(new String ("RGB ").getBytes(), 0);
    /** tag type     */ public final static int kdwGrayData         = ICCProfile.getInt(new String ("GRAY").getBytes(), 0);
    /** tag type     */ public final static int kdwXYZData       = ICCProfile.getInt(new String ("XYZ ").getBytes(), 0);
    /** input type   */ public final static int kMonochromeInput   = 0;
    /** input type   */ public final static int kThreeCompInput     = 1;

    /** tag signature */ public final static int kdwGrayTRCTag      = ICCProfile.getInt(new String ("kTRC").getBytes(), 0);
    /** tag signature */ public final static int kdwRedColorantTag    = ICCProfile.getInt(new String ("rXYZ").getBytes(), 0);
    /** tag signature */ public final static int kdwGreenColorantTag  = ICCProfile.getInt(new String ("gXYZ").getBytes(), 0);
    /** tag signature */ public final static int kdwBlueColorantTag   = ICCProfile.getInt(new String ("bXYZ").getBytes(), 0);
    /** tag signature */ public final static int kdwRedTRCTag      = ICCProfile.getInt(new String ("rTRC").getBytes(), 0);
    /** tag signature */ public final static int kdwGreenTRCTag        = ICCProfile.getInt(new String ("gTRC").getBytes(), 0);
    /** tag signature */ public final static int kdwBlueTRCTag      = ICCProfile.getInt(new String ("bTRC").getBytes(), 0);
    /** tag signature */ public final static int kdwCopyrightTag      = ICCProfile.getInt(new String ("cprt").getBytes(), 0);
    /** tag signature */ public final static int kdwMediaWhiteTag     = ICCProfile.getInt(new String ("wtpt").getBytes(), 0);
    /** tag signature */ public final static int kdwProfileDescTag    = ICCProfile.getInt(new String ("desc").getBytes(), 0);

   
    private ICCProfileHeader header  = null;
    private ICCTagTable      tags    = null;
    private byte []          profile = null;

    private int getProfileSize ()                   { return header.dwProfileSize; }
    private int getCMMTypeSignature ()              { return header.dwCMMTypeSignature; }
    private int getProfileClass ()                  { return header.dwProfileClass ; }
    private int getColorSpaceType ()                { return header.dwColorSpaceType; }
    private int getPCSType ()                       { return header.dwPCSType; }
    private int getProfileSignature ()              { return header.dwProfileSignature; }
    private int getPlatformSignature ()             { return header.dwPlatformSignature; }
    private int getCMMFlags ()                      { return header.dwCMMFlags; }
    private int getDeviceManufacturer ()            { return header.dwDeviceManufacturer; }
    private int getDeviceModel ()                   { return header.dwDeviceModel; }
    private int getDeviceAttributes1 ()             { return header.dwDeviceAttributes1; }
    private int getDeviceAttributesReserved ()      { return header.dwDeviceAttributesReserved; }
    private int getRenderingIntent ()               { return header.dwRenderingIntent; }
    private int getCreatorSig ()                    { return header.dwCreatorSig; }
    private ICCProfileVersion getProfileVersion ()  { return header.profileVersion; }
   
    private void setProfileSignature (int profilesig)           { header.dwProfileSignature = profilesig; }
    private void setProfileSize (int size)                      { header.dwProfileSize = size; }
    private void setCMMTypeSignature (int cmmsig)               { header.dwCMMTypeSignature = cmmsig; }
    private void setProfileClass (int pclass)                   { header.dwProfileClass  = pclass; }
    private void setColorSpaceType (int colorspace)             { header.dwColorSpaceType = colorspace; }
    private void setPCSIlluminant(XYZNumber xyz)                { header.PCSIlluminant = xyz; }
    private void setPCSType (int PCStype)                       { header.dwPCSType = PCStype; }
    private void setPlatformSignature (int platformsig)         { header.dwPlatformSignature = platformsig; }
    private void setCMMFlags (int cmmflags)                     { header.dwCMMFlags = cmmflags; }
    private void setDeviceManufacturer (int manufacturer)       { header.dwDeviceManufacturer = manufacturer; }
    private void setDeviceModel (int model)                     { header.dwDeviceModel = model; }
    private void setDeviceAttributes1 (int attr1)               { header.dwDeviceAttributes1 = attr1; }
    private void setDeviceAttributesReserved (int attrreserved) { header.dwDeviceAttributesReserved = attrreserved; }
    private void setRenderingIntent (int rendering)             { header.dwRenderingIntent = rendering; }
    private void setCreatorSig (int creatorsig)                 { header.dwCreatorSig = creatorsig; }
    private void setProfileVersion (ICCProfileVersion version)  { header.profileVersion = version; }
    private void setDateTime (ICCDateTime datetime)             { header.dateTime = datetime; }

    private byte [] data = null;
    private ParameterList pl = null;

    private ICCProfile () throws ICCProfileException {
        throw new ICCProfileException
            ("illegal to invoke empty constructor"); }

    /**
     * ParameterList constructor
     *   @param csb provides colorspace information
     */
    protected ICCProfile (ColorSpace csm)
        throws ColorSpaceException, ICCProfileInvalidException {
        this.pl = csm.pl;
        profile = csm.getICCProfile();
        initProfile(profile); }

    /**
     * Read the header and tags into memory and verify
     * that the correct type of profile is being used. for encoding.
     *   @param data ICCProfile
     * @exception ICCProfileInvalidException for bad signature and class and bad type
     */
    private void initProfile (byte [] data)
        throws ICCProfileInvalidException {
        header = new ICCProfileHeader (data);
        tags = ICCTagTable.createInstance(data);
               
       
        // Verify that the data pointed to by icc is indeed a valid profile   
        // and that it is possibly of one of the Restricted ICC types. The simplest way to check   
        // this is to verify that the profile signature is correct, that it is an input profile,   
        // and that the PCS used is XYX.   
       
        // However, a common error in profiles will be to create Monitor profiles rather   
        // than input profiles. If this is the only error found, it's still useful to let this 
        // go through with an error written to stderr. 
       
        if (getProfileClass() == kdwDisplayProfile) {
            String message =
                "NOTE!! Technically, this profile is a Display profile, not an" +
                " Input Profile, and thus is not a valid Restricted ICC profile." +
                " However, it is quite possible that this profile is usable as" +
                " a Restricted ICC profile, so this code will ignore this state" +
                " and proceed with processing.";

            FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING,message); }
 
        if ((getProfileSignature() != kdwProfileSignature) ||
            ((getProfileClass()    != kdwInputProfile) &&
             (getProfileClass()    != kdwDisplayProfile)) ||
            (getPCSType()     != kdwXYZData)) {
            throw new ICCProfileInvalidException (); }}


    /** Provide a suitable string representation for the class */
    public String toString () {
        StringBuffer rep = new StringBuffer("[ICCProfile:");
        StringBuffer body = new StringBuffer();
        body.append(eol).append(header);
        body.append(eol).append(eol).append(tags);
        rep.append(ColorSpace.indent("  ", body));
        return rep.append("]").toString(); }


    /**
     * Create a two character hex representation of a byte
     *   @param i byte to represent
     * @return representation
     */
    public static String toHexString(byte i) {
        String rep = (i>=0 && i<16 ? "0" : "") + Integer.toHexString((int)i);
        if (rep.length()>2) rep = rep.substring(rep.length()-2);
        return rep; }

    /**
     * Create a 4 character hex representation of a short
     *   @param i short to represent
     * @return representation
     */
    public static String toHexString(short i) {
        String rep;

        if (i>=0 && i<0x10)        rep = "000" + Integer.toHexString((int)i);
        else if (i>=0 && i<0x100rep = "00"  + Integer.toHexString((int)i);
        else if (i>=0 && i<0x1000) rep = "0"   + Integer.toHexString((int)i);
        else                       rep = ""    + Integer.toHexString((int)i);

        if (rep.length()>4) rep = rep.substring(rep.length()-4);
        return rep; }


    /**
     * Create a 8 character hex representation of a int
     *   @param i int to represent
     * @return representation
     */
    public static String toHexString(int i) {
        String rep;

        if (i>=0 && i<0x10)                rep = "0000000" + Integer.toHexString((int)i);
        else if (i>=0 && i<0x100)          rep = "000000"  + Integer.toHexString((int)i);
        else if (i>=0 && i<0x1000)         rep = "00000"   + Integer.toHexString((int)i);
        else if (i>=0 && i<0x10000)        rep = "0000"    + Integer.toHexString((int)i);
        else if (i>=0 && i<0x100000)       rep = "000"     + Integer.toHexString((int)i);
        else if (i>=0 && i<0x1000000)      rep = "00"      + Integer.toHexString((int)i);
        else if (i>=0 && i<0x10000000)     rep = "0"       + Integer.toHexString((int)i);
        else                               rep = ""        + Integer.toHexString((int)i);

        if (rep.length()>8) rep = rep.substring(rep.length()-8);
        return rep; }

    public static String toString (byte [] data) {

        int i, row,col,rem,rows,cols;

        StringBuffer rep  = new StringBuffer();
        StringBuffer rep0 = null;
        StringBuffer rep1 = null;
        StringBuffer rep2 = null;

        cols = 16;
        rows = data.length/cols;
        rem  = data.length%cols;

        byte [] lbytes = new byte [8];
        for(row=0, i=0; row<rows; ++row) {
            rep1 = new StringBuffer();
            rep2 = new StringBuffer();

            for (i=0;i<8;++i) lbytes[i]=0;
            byte [] tbytes = Integer.toHexString (row*16).getBytes();
            for (int t=0,l=lbytes.length-tbytes.length;
                 t<tbytes.length;
                 ++l,++t) lbytes[l] = tbytes[t];
           
            rep0 = new StringBuffer(new String(lbytes));

            for (col=0; col<cols; ++col) {
                byte b = data[i++];
                rep1 .append(toHexString(b)).append(i%2 == 0 ? " " : "");
                if (Character.isJavaIdentifierStart((char)b)) rep2 .append((char)b);
                else rep2 .append("."); }
            rep
                .append(rep0)
                .append(" :  ")
                .append(rep1)
                .append(":  ")
                .append(rep2).append(eol); }

        rep1 = new StringBuffer();
        rep2 = new StringBuffer();

        for (i=0;i<8;++i) lbytes[i]=0;
        byte [] tbytes = Integer.toHexString (row*16).getBytes();
        for (int t=0,l=lbytes.length-tbytes.length;
             t<tbytes.length;
             ++l,++t) lbytes[l] = tbytes[t];
       
        rep0 = new StringBuffer(new String(lbytes));

        for (col=0; col<rem; ++col) {
                byte b = data[i++];
                rep1 .append(toHexString(b)).append(i%2 == 0 ? " " : "");
                if (Character.isJavaIdentifierStart((char)b)) rep2 .append((char)b);
                else rep2 .append("."); }
        for (col=rem; col<16; ++col) rep1 .append("  ").append(col%2 == 0 ? " " : "");

        rep
            .append(rep0)
            .append(" :  ")
            .append(rep1)
            .append(":  ")
            .append(rep2).append(eol);
       
        return rep.toString(); }

    /**
     * Access the profile header
     * @return ICCProfileHeader
     */
    public ICCProfileHeader getHeader () {return header;}

   
    /**
     * Access the profile tag table
     * @return ICCTagTable
     */
    public ICCTagTable getTagTable () {return tags;}
   
    /**
     * Parse this ICCProfile into a RestrictedICCProfile
     * which is appropriate to the data in this profile.
     * Either a MonochromeInputRestrictedProfile or
     * MatrixBasedRestrictedProfile is returned
     * @return RestrictedICCProfile
     * @exception ICCProfileInvalidException no curve data
     */
    public  RestrictedICCProfile parse () throws ICCProfileInvalidException {
 
        // The next step is to determine which Restricted ICC type is used by this profile.
        // Unfortunately, the only way to do this is to look through the tag table for
        // the tags required by the two types.
 
        // First look for the gray TRC tag. If the profile is indeed an input profile, and this
        // tag exists, then the profile is a Monochrome Input profile

        ICCCurveType grayTag = (ICCCurveType) tags.get(new Integer(kdwGrayTRCTag));
        if (grayTag != null) {
            return RestrictedICCProfile.createInstance (grayTag); }
 
        // If it wasn't a Monochrome Input profile, look for the Red Colorant tag. If that
        // tag is found and the profile is indeed an input profile, then this profile is
        // a Three-Component Matrix-Based Input profile

        ICCCurveType rTRCTag = (ICCCurveType) tags.get(new Integer(kdwRedTRCTag));
       

        if (rTRCTag != null) {
            ICCCurveType gTRCTag = (ICCCurveType) tags.get(new Integer(kdwGreenTRCTag));
            ICCCurveType bTRCTag = (ICCCurveType) tags.get(new Integer(kdwBlueTRCTag));
            ICCXYZType rColorantTag = (ICCXYZType) tags.get(new Integer(kdwRedColorantTag));
            ICCXYZType gColorantTag = (ICCXYZType) tags.get(new Integer(kdwGreenColorantTag));
            ICCXYZType bColorantTag = (ICCXYZType) tags.get(new Integer(kdwBlueColorantTag));
            return RestrictedICCProfile.createInstance
                (rTRCTag, gTRCTag, bTRCTag, rColorantTag, gColorantTag, bColorantTag); }

        throw new ICCProfileInvalidException ("curve data not found in profile"); }

    /**
     * Output this ICCProfile to a RandomAccessFile
     *   @param os output file
     */
    public void write (RandomAccessFile os) throws IOException {
        getHeader().write (os);
        getTagTable().write (os); }

   
    /* end class ICCProfile */ }















TOP

Related Classes of ucar.jpeg.icc.ICCProfile$BoxType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.