/// **************************************************************************
///
/// $Id: PaletteBox.java,v 1.1 2002/07/25 14:50:47 grosbois Exp $
///
/// Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650
/// $Date $
/// ***************************************************************************
///
using System;
using ColorSpaceException = CSJ2K.Color.ColorSpaceException;
using ICCProfile = CSJ2K.Icc.ICCProfile;
using ParameterList = CSJ2K.j2k.util.ParameterList;
using RandomAccessIO = CSJ2K.j2k.io.RandomAccessIO;
namespace CSJ2K.Color.Boxes
{
/// This class models the palette box contained in a JP2
/// image.
///
///
/// 1.0
///
/// Bruce A. Kern
///
public sealed class PaletteBox:JP2Box
{
/// Return the number of palette entries.
public int NumEntries
{
get
{
return nentries;
}
}
/// Return the number of palette columns.
public int NumColumns
{
get
{
return ncolumns;
}
}
private int nentries;
private int ncolumns;
private short[] bitdepth;
private int[][] entries;
/// Construct a PaletteBox from an input image.
/// RandomAccessIO jp2 image
///
/// offset to the start of the box in the image
///
/// ColorSpaceException
///
public PaletteBox(RandomAccessIO in_Renamed, int boxStart):base(in_Renamed, boxStart)
{
readBox();
}
/// Analyze the box content.
internal void readBox()
{
byte[] bfr = new byte[4];
int i, j, b, m;
//int entry;
// Read the number of palette entries and columns per entry.
in_Renamed.seek((int) dataStart);
in_Renamed.readFully(bfr, 0, 3);
nentries = ICCProfile.getShort(bfr, 0) & 0x0000ffff;
ncolumns = bfr[2] & 0x0000ffff;
// Read the bitdepths for each column
bitdepth = new short[ncolumns];
bfr = new byte[ncolumns];
in_Renamed.readFully(bfr, 0, ncolumns);
for (i = 0; i < ncolumns; ++i)
{
bitdepth[i] = (short) (bfr[i] & 0x00fff);
}
entries = new int[nentries * ncolumns][];
bfr = new byte[2];
for (i = 0; i < nentries; ++i)
{
entries[i] = new int[ncolumns];
for (j = 0; j < ncolumns; ++j)
{
int bd = getBitDepth(j);
bool signed = isSigned(j);
switch (getEntrySize(j))
{
case 1: // 8 bit entries
in_Renamed.readFully(bfr, 0, 1);
b = bfr[0];
break;
case 2: // 16 bits
in_Renamed.readFully(bfr, 0, 2);
b = ICCProfile.getShort(bfr, 0);
break;
default:
throw new ColorSpaceException("palettes greater than 16 bits deep not supported");
}
if (signed)
{
// Do sign extension if high bit is set.
if ((b & (1 << (bd - 1))) == 0)
{
// high bit not set.
m = (1 << bd) - 1;
entries[i][j] = m & b;
}
else
{
// high bit set.
// CONVERSION PROBLEM?
m = unchecked((int)(0xffffffff << bd));
entries[i][j] = m | b;
}
}
else
{
// Clear all high bits.
m = (1 << bd) - 1;
entries[i][j] = m & b;
}
}
}
}
/// Are entries signed predicate.
public bool isSigned(int column)
{
return (bitdepth[column] & 0x80) == 1;
}
/// Are entries unsigned predicate.
public bool isUnSigned(int column)
{
return !isSigned(column);
}
/// Return the bitdepth of palette entries.
public short getBitDepth(int column)
{
return (short) ((bitdepth[column] & 0x7f) + 1);
}
/// Return an entry for a given index and column.
public int getEntry(int column, int entry)
{
return entries[entry][column];
}
/// Return a suitable String representation of the class instance.
public override System.String ToString()
{
System.Text.StringBuilder rep = new System.Text.StringBuilder("[PaletteBox ").Append("nentries= ").Append(System.Convert.ToString(nentries)).Append(", ncolumns= ").Append(System.Convert.ToString(ncolumns)).Append(", bitdepth per column= (");
for (int i = 0; i < ncolumns; ++i)
rep.Append(getBitDepth(i)).Append(isSigned(i)?"S":"U").Append(i < ncolumns - 1?", ":"");
return rep.Append(")]").ToString();
}
private int getEntrySize(int column)
{
int bd = getBitDepth(column);
return bd / 8 + (bd % 8) == 0?0:1;
}
/* end class PaletteBox */
static PaletteBox()
{
{
type = 0x70636c72;
}
}
}
}