Methods Summary |
---|
protected void | buildPalette()
reduceList = new ColorNode[MAXLEVEL + 1];
for (int i = 0; i < reduceList.length; i++) {
reduceList[i] = null;
}
numNodes = 0;
maxNodes = 0;
root = null;
currSize = 0;
currLevel = MAXLEVEL;
/*
from the book
*/
int w = src.getWidth();
int h = src.getHeight();
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Color aColor = getSrcColor(w - x - 1, h - y - 1);
/*
* If transparency of given image is not opaque we assume all
* colors with alpha less than 1.0 as fully transparent.
*/
if (transparency != Transparency.OPAQUE &&
aColor.getAlpha() != 0xff)
{
transColor = insertNode(transColor, aColor, 0);
} else {
root = insertNode(root, aColor, 0);
}
if (currSize > requiredSize) {
reduceTree();
}
}
}
|
public static boolean | canCreatePalette(javax.imageio.ImageTypeSpecifier type)Returns true if PaletteBuilder is able to create
palette for given image type.
if (type == null) {
throw new IllegalArgumentException("type == null");
}
return true;
|
public static boolean | canCreatePalette(java.awt.image.RenderedImage image)Returns true if PaletteBuilder is able to create
palette for given rendered image.
if (image == null) {
throw new IllegalArgumentException("image == null");
}
ImageTypeSpecifier type = new ImageTypeSpecifier(image);
return canCreatePalette(type);
|
public static java.awt.image.IndexColorModel | createIndexColorModel(java.awt.image.RenderedImage img)Creates an palette representing colors from given image
img . If number of colors in the given image exceeds
maximum palette size closest colors would be merged.
PaletteBuilder pb = new PaletteBuilder(img);
pb.buildPalette();
return pb.getIndexColorModel();
|
public static java.awt.image.RenderedImage | createIndexedImage(java.awt.image.RenderedImage src)Creates an image representing given image
src using IndexColorModel .
Lossless conversion is not always possible (e.g. if number
of colors in the given image exceeds maximum palette size).
Result image then is an approximation constructed by octree
quantization method.
PaletteBuilder pb = new PaletteBuilder(src);
pb.buildPalette();
return pb.getIndexedImage();
|
protected int | findColorIndex(com.sun.imageio.plugins.common.PaletteBuilder$ColorNode aNode, java.awt.Color aColor)
if (transparency != Transparency.OPAQUE &&
aColor.getAlpha() != 0xff)
{
return 0; // default transparnt pixel
}
if (aNode.isLeaf) {
return aNode.paletteIndex;
} else {
int childIndex = getBranchIndex(aColor, aNode.level);
return findColorIndex(aNode.children[childIndex], aColor);
}
|
protected int | findPaletteEntry(com.sun.imageio.plugins.common.PaletteBuilder$ColorNode aNode, int index, byte[] red, byte[] green, byte[] blue)
if (aNode.isLeaf) {
red[index] = (byte)(aNode.red/aNode.colorCount);
green[index] = (byte)(aNode.green/aNode.colorCount);
blue[index] = (byte)(aNode.blue/aNode.colorCount);
aNode.paletteIndex = index;
palette[index] = aNode;
index++;
} else {
for (int i = 0; i < 8; i++) {
if (aNode.children[i] != null) {
index = findPaletteEntry(aNode.children[i], index,
red, green, blue);
}
}
}
return index;
|
protected com.sun.imageio.plugins.common.PaletteBuilder$ColorNode | freeTree(com.sun.imageio.plugins.common.PaletteBuilder$ColorNode aNode)
if (aNode == null) {
return null;
}
for (int i = 0; i < 8; i++) {
aNode.children[i] = freeTree(aNode.children[i]);
}
numNodes--;
return null;
|
protected int | getBranchIndex(java.awt.Color aColor, int aLevel)
if (aLevel > MAXLEVEL || aLevel < 0) {
throw new IllegalArgumentException("Invalid octree node depth: " +
aLevel);
}
int shift = MAXLEVEL - aLevel;
int red_index = 0x1 & ((0xff & aColor.getRed()) >> shift);
int green_index = 0x1 & ((0xff & aColor.getGreen()) >> shift);
int blue_index = 0x1 & ((0xff & aColor.getBlue()) >> shift);
int index = (red_index << 2) | (green_index << 1) | blue_index;
return index;
|
protected java.awt.image.IndexColorModel | getIndexColorModel()
int size = currSize;
if (transparency == Transparency.BITMASK) {
size ++; // we need place for transparent color;
}
byte[] red = new byte[size];
byte[] green = new byte[size];
byte[] blue = new byte[size];
int index = 0;
palette = new ColorNode[size];
if (transparency == Transparency.BITMASK) {
index ++;
}
int lastIndex = findPaletteEntry(root, index, red, green, blue);
IndexColorModel icm = null;
if (transparency == Transparency.BITMASK) {
icm = new IndexColorModel(8, size, red, green, blue, 0);
} else {
icm = new IndexColorModel(8, currSize, red, green, blue);
}
return icm;
|
protected java.awt.image.RenderedImage | getIndexedImage()
IndexColorModel icm = getIndexColorModel();
BufferedImage dst =
new BufferedImage(src.getWidth(), src.getHeight(),
BufferedImage.TYPE_BYTE_INDEXED, icm);
WritableRaster wr = dst.getRaster();
for (int y =0; y < dst.getHeight(); y++) {
for (int x = 0; x < dst.getWidth(); x++) {
Color aColor = getSrcColor(x,y);
wr.setSample(x, y, 0, findColorIndex(root, aColor));
}
}
return dst;
|
private java.awt.Color | getSrcColor(int x, int y)
int argb = srcColorModel.getRGB(srcRaster.getDataElements(x, y, null));
return new Color(argb, transparency != Transparency.OPAQUE);
|
protected com.sun.imageio.plugins.common.PaletteBuilder$ColorNode | insertNode(com.sun.imageio.plugins.common.PaletteBuilder$ColorNode aNode, java.awt.Color aColor, int aLevel)
if (aNode == null) {
aNode = new ColorNode();
numNodes++;
if (numNodes > maxNodes) {
maxNodes = numNodes;
}
aNode.level = aLevel;
aNode.isLeaf = (aLevel > MAXLEVEL);
if (aNode.isLeaf) {
currSize++;
}
}
aNode.colorCount++;
aNode.red += aColor.getRed();
aNode.green += aColor.getGreen();
aNode.blue += aColor.getBlue();
if (!aNode.isLeaf) {
int branchIndex = getBranchIndex(aColor, aLevel);
if (aNode.children[branchIndex] == null) {
aNode.childCount++;
if (aNode.childCount == 2) {
aNode.nextReducible = reduceList[aLevel];
reduceList[aLevel] = aNode;
}
}
aNode.children[branchIndex] =
insertNode(aNode.children[branchIndex], aColor, aLevel + 1);
}
return aNode;
|
protected void | reduceTree()
int level = reduceList.length - 1;
while (reduceList[level] == null && level >= 0) {
level--;
}
ColorNode thisNode = reduceList[level];
if (thisNode == null) {
// nothing to reduce
return;
}
// look for element with lower color count
ColorNode pList = thisNode;
int minColorCount = pList.colorCount;
int cnt = 1;
while (pList.nextReducible != null) {
if (minColorCount > pList.nextReducible.colorCount) {
thisNode = pList;
minColorCount = pList.colorCount;
}
pList = pList.nextReducible;
cnt++;
}
// save pointer to first reducible node
// NB: current color count for node could be changed in future
if (thisNode == reduceList[level]) {
reduceList[level] = thisNode.nextReducible;
} else {
pList = thisNode.nextReducible; // we need to process it
thisNode.nextReducible = pList.nextReducible;
thisNode = pList;
}
if (thisNode.isLeaf) {
return;
}
// reduce node
int leafChildCount = thisNode.getLeafChildCount();
thisNode.isLeaf = true;
currSize -= (leafChildCount - 1);
int aDepth = thisNode.level;
for (int i = 0; i < 8; i++) {
thisNode.children[i] = freeTree(thisNode.children[i]);
}
thisNode.childCount = 0;
|