/// **************************************************************************
///
/// $Id: ColorSpace.java,v 1.2 2002/07/25 16:31:11 grosbois Exp $
///
/// Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650
/// $Date $
/// ***************************************************************************
///
using System;
using FileFormatBoxes = CSJ2K.j2k.fileformat.FileFormatBoxes;
using ParameterList = CSJ2K.j2k.util.ParameterList;
using HeaderDecoder = CSJ2K.j2k.codestream.reader.HeaderDecoder;
using RandomAccessIO = CSJ2K.j2k.io.RandomAccessIO;
using ICCProfile = CSJ2K.Icc.ICCProfile;
using PaletteBox = CSJ2K.Color.Boxes.PaletteBox;
using ComponentMappingBox = CSJ2K.Color.Boxes.ComponentMappingBox;
using ColorSpecificationBox = CSJ2K.Color.Boxes.ColorSpecificationBox;
using ChannelDefinitionBox = CSJ2K.Color.Boxes.ChannelDefinitionBox;
using ImageHeaderBox = CSJ2K.Color.Boxes.ImageHeaderBox;
using JP2Box = CSJ2K.Color.Boxes.JP2Box;
namespace CSJ2K.Color
{
/// This class analyzes the image to provide colorspace
/// information for the decoding chain. It does this by
/// examining the box structure of the JP2 image.
/// It also provides access to the parameter list information,
/// which is stored as a public final field.
///
///
///
///
/// 1.0
///
/// Bruce A. Kern
///
public class ColorSpace
{
/// Retrieve the ICC profile from the images as
/// a byte array.
///
/// the ICC Profile as a byte [].
///
virtual public byte[] ICCProfile
{
get
{
return csbox.ICCProfile;
}
}
/// Return the colorspace method (Profiled, enumerated, or palettized).
virtual public MethodEnum Method
{
get
{
return csbox.Method;
}
}
/// Return number of channels in the palette.
virtual public PaletteBox PaletteBox
{
get
{
return pbox;
}
}
/// Return number of channels in the palette.
virtual public int PaletteChannels
{
get
{
return pbox == null?0:pbox.NumColumns;
}
}
/// Is palettized predicate.
virtual public bool Palettized
{
get
{
return pbox != null;
}
}
//UPGRADE_NOTE: Final was removed from the declaration of 'eol '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public static readonly System.String eol = System.Environment.NewLine;
// Renamed for convenience:
internal const int GRAY = 0;
internal const int RED = 1;
internal const int GREEN = 2;
internal const int BLUE = 3;
/// Parameter Specs
public ParameterList pl;
/// Parameter Specs
public HeaderDecoder hd;
/* Image box structure as pertains to colorspacees. */
private PaletteBox pbox = null;
private ComponentMappingBox cmbox = null;
private ColorSpecificationBox csbox = null;
private ChannelDefinitionBox cdbox = null;
private ImageHeaderBox ihbox = null;
/// Input image
private RandomAccessIO in_Renamed = null;
/// Indent a String that contains newlines.
public static System.String indent(System.String ident, System.Text.StringBuilder instr)
{
return indent(ident, instr.ToString());
}
/// Indent a String that contains newlines.
public static System.String indent(System.String ident, System.String instr)
{
System.Text.StringBuilder tgt = new System.Text.StringBuilder(instr);
char eolChar = eol[0];
int i = tgt.Length;
while (--i > 0)
{
if (tgt[i] == eolChar)
tgt.Insert(i + 1, ident);
}
return ident + tgt.ToString();
}
/// public constructor which takes in the image, parameterlist and the
/// image header decoder as args.
///
/// input RandomAccess image file.
///
/// provides information about the image header.
///
/// provides parameters from the default and commandline lists.
///
/// ColorSpaceException
///
public ColorSpace(RandomAccessIO in_Renamed, HeaderDecoder hd, ParameterList pl)
{
this.pl = pl;
this.in_Renamed = in_Renamed;
this.hd = hd;
getBoxes();
}
/// Retrieve the various boxes from the JP2 file.
/// IOException
///
protected internal void getBoxes()
{
//byte[] data;
int type;
long len = 0;
int boxStart = 0;
byte[] boxHeader = new byte[16];
int i = 0;
// Search the toplevel boxes for the header box
while (true)
{
in_Renamed.seek(boxStart);
in_Renamed.readFully(boxHeader, 0, 16);
// CONVERSION PROBLEM?
len = (long)CSJ2K.Icc.ICCProfile.getInt(boxHeader, 0);
if (len == 1)
len = CSJ2K.Icc.ICCProfile.getLong(boxHeader, 8); // Extended
// length
type = CSJ2K.Icc.ICCProfile.getInt(boxHeader, 4);
// Verify the contents of the file so far.
if (i == 0 && type != CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_SIGNATURE_BOX)
{
throw new ColorSpaceException("first box in image not " + "signature");
}
else if (i == 1 && type != CSJ2K.j2k.fileformat.FileFormatBoxes.FILE_TYPE_BOX)
{
throw new ColorSpaceException("second box in image not file");
}
else if (type == CSJ2K.j2k.fileformat.FileFormatBoxes.CONTIGUOUS_CODESTREAM_BOX)
{
throw new ColorSpaceException("header box not found in image");
}
else if (type == CSJ2K.j2k.fileformat.FileFormatBoxes.JP2_HEADER_BOX)
{
break;
}
// Progress to the next box.
++i;
boxStart = (int) (boxStart + len);
}
// boxStart indexes the start of the JP2_HEADER_BOX,
// make headerBoxEnd index the end of the box.
long headerBoxEnd = boxStart + len;
if (len == 1)
boxStart += 8; // Extended length header
for (boxStart += 8; boxStart < headerBoxEnd; boxStart = (int) (boxStart + len))
{
in_Renamed.seek(boxStart);
in_Renamed.readFully(boxHeader, 0, 16);
len = (long)CSJ2K.Icc.ICCProfile.getInt(boxHeader, 0);
if (len == 1)
throw new ColorSpaceException("Extended length boxes " + "not supported");
type = (int)CSJ2K.Icc.ICCProfile.getInt(boxHeader, 4);
switch (type)
{
case CSJ2K.j2k.fileformat.FileFormatBoxes.IMAGE_HEADER_BOX:
ihbox = new ImageHeaderBox(in_Renamed, boxStart);
break;
case CSJ2K.j2k.fileformat.FileFormatBoxes.COLOUR_SPECIFICATION_BOX:
csbox = new ColorSpecificationBox(in_Renamed, boxStart);
break;
case CSJ2K.j2k.fileformat.FileFormatBoxes.CHANNEL_DEFINITION_BOX:
cdbox = new ChannelDefinitionBox(in_Renamed, boxStart);
break;
case CSJ2K.j2k.fileformat.FileFormatBoxes.COMPONENT_MAPPING_BOX:
cmbox = new ComponentMappingBox(in_Renamed, boxStart);
break;
case CSJ2K.j2k.fileformat.FileFormatBoxes.PALETTE_BOX:
pbox = new PaletteBox(in_Renamed, boxStart);
break;
default:
break;
}
}
if (ihbox == null)
throw new ColorSpaceException("image header box not found");
if ((pbox == null && cmbox != null) || (pbox != null && cmbox == null))
throw new ColorSpaceException("palette box and component " + "mapping box inconsistency");
}
/// Return the channel definition of the input component.
public virtual int getChannelDefinition(int c)
{
if (cdbox == null)
return c;
else
return cdbox.getCn(c + 1);
}
/// Return the colorspace (sYCC, sRGB, sGreyScale).
public virtual CSEnum getColorSpace()
{
return csbox.ColorSpace;
}
/// Return bitdepth of the palette entries.
public virtual int getPaletteChannelBits(int c)
{
return pbox == null ? 0 : (int)pbox.getBitDepth(c);
}
/// Return a palettized sample
/// requested
///
/// of entry
///
/// palettized sample
///
public virtual int getPalettizedSample(int channel, int index)
{
return pbox == null?0:pbox.getEntry(channel, index);
}
/// Signed output predicate.
public virtual bool isOutputSigned(int channel)
{
return (pbox != null)?pbox.isSigned(channel):hd.isOriginalSigned(channel);
}
/// Return a suitable String representation of the class instance.
public override System.String ToString()
{
System.Text.StringBuilder rep = new System.Text.StringBuilder("[ColorSpace is ").Append(csbox.MethodString).Append(Palettized?" and palettized ":" ").Append(Method == MethodEnum.ENUMERATED?csbox.ColorSpaceString:"");
if (ihbox != null)
{
rep.Append(eol).Append(indent(" ", ihbox.ToString()));
}
if (cdbox != null)
{
rep.Append(eol).Append(indent(" ", cdbox.ToString()));
}
if (csbox != null)
{
rep.Append(eol).Append(indent(" ", csbox.ToString()));
}
if (pbox != null)
{
rep.Append(eol).Append(indent(" ", pbox.ToString()));
}
if (cmbox != null)
{
rep.Append(eol).Append(indent(" ", cmbox.ToString()));
}
return rep.Append("]").ToString();
}
/// Are profiling diagnostics turned on
/// yes or no
///
public virtual bool debugging()
{
return pl.Get("colorspace_debug") != null && pl.Get("colorspace_debug").ToUpper().Equals("on".ToUpper());
}
public enum MethodEnum
{
ICC_PROFILED,
ENUMERATED
}
public enum CSEnum
{
sRGB,
GreyScale,
sYCC,
esRGB,
Illegal,
Unknown
}
/* Enumeration Class */
/*
/// method enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'ICC_PROFILED '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const MethodEnum ICC_PROFILED = new MethodEnum("profiled");
/// method enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'ENUMERATED '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const MethodEnum ENUMERATED = new MethodEnum("enumerated");
/// colorspace enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'sRGB '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const CSEnum sRGB = new CSEnum("sRGB");
/// colorspace enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'GreyScale '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const CSEnum GreyScale = new CSEnum("GreyScale");
/// colorspace enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'sYCC '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const CSEnum sYCC = new CSEnum("sYCC");
/// colorspace enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'Illegal '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const CSEnum Illegal = new CSEnum("Illegal");
/// colorspace enumeration
//UPGRADE_NOTE: Final was removed from the declaration of 'Unknown '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public const CSEnum Unknown = new CSEnum("Unknown");
/// Typesafe enumeration class
/// 1.0
///
/// Bruce A Kern
///
public class Enumeration
{
//UPGRADE_NOTE: Final was removed from the declaration of 'value '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public System.String value_Renamed;
public Enumeration(System.String value_Renamed)
{
this.value_Renamed = value_Renamed;
}
public override System.String ToString()
{
return value_Renamed;
}
}
/// Method enumeration class
/// 1.0
///
/// Bruce A Kern
///
public class MethodEnum:Enumeration
{
public MethodEnum(System.String value_Renamed):base(value_Renamed)
{
}
}
/// Colorspace enumeration class
/// 1.0
///
/// Bruce A Kern
///
public class CSEnum:Enumeration
{
public CSEnum(System.String value_Renamed):base(value_Renamed)
{
}
}
*/
/* end class ColorSpace */
}
}