AbstractBitmapIndexed.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
webplugin.aclib.image.ico |
![]() |
![]() |
TV-Browser |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* This Classes are slightly modified Versions of the
* AC.lib-ICO.
*
* The original can be found here:
*
* http://www.acproductions.de/commercial/aclibico/index.html
*
* The code is based on:
*
* winicontoppm.c - read a MS Windows .ico file and write portable pixmap(s)
*
* Copyright (C) 2000 by Lee Benfield - lee@recoil.org
*
* Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. This software is provided "as is" without express or implied warranty.
*
* Addendum for Java code by Christian Treber:
* The rules for the Java adaption are the same as stated above for the C version.
*
*/
package webplugin.aclib.image.ico;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.IOException;
import webplugin.aclib.codec.AbstractDecoder;
/**
* <p>
* Parent class for indexed bitmaps (1, 4, and 8 bits per pixel). The value of a
* pixel refers to an entry in the color palette. The bitmap has a mask which is
* a 1 BPP bitmap specifiying whether a pixel is transparent or opaque.
* </p>
* @author © Christian Treber, ct@ctreber.com
*/
public abstract class AbstractBitmapIndexed extends AbstractBitmap {
private static final int OPAQUE = 255;
/**
* The color palette. Refered to by the pixel values. The size is expected
* to be 2^BPP, but see getVerifiedColorCount() for a discussion of this.
*/
private Color[] _colorPalette;
/** The pixel values. The value refers to an entry in the color palette. */
protected int[] _pixels;
private BitmapMask _transparencyMask;
/**
* Create a bitmap with a color table and a mask.
* @param pDescriptor
* The descriptor.
*/
public AbstractBitmapIndexed(final BitmapDescriptor pDescriptor) {
super(pDescriptor);
_pixels = new int[getWidth() * getHeight()];
}
/**
* Needed to be replaced for indexed images because they contain a color
* palette and a mask which needs to be read as well.
* @param pDec
* The decoder.
* @throws IOException
*/
void read(final AbstractDecoder pDec) throws IOException {
readColorPalette(pDec);
readBitmap(pDec);
readMask(pDec);
}
/**
* @param pDec
* The decoder.
* @throws IOException
*/
private void readColorPalette(final AbstractDecoder pDec)
throws IOException {
final int lColorCount = getVerifiedColorCount();
_colorPalette = new Color[lColorCount];
for (int lColorNo = 0; lColorNo < lColorCount; lColorNo++) {
setColor(lColorNo, readColor(pDec));
}
}
private Color readColor(final AbstractDecoder pDec) throws IOException {
final int lBlue = pDec.readUInt1();
final int lGreen = pDec.readUInt1();
final int lRed = pDec.readUInt1();
// "Reserved"
pDec.readUInt1();
return new Color(lRed, lGreen, lBlue);
}
/**
* This functions is needed b/c all classes read the bitmap, but not always
* a color table and a mask.
* @param pDec
* The decoder.
* @throws IOException
*/
abstract void readBitmap(final AbstractDecoder pDec) throws IOException;
/**
* @param pDec
* The decoder.
* @throws IOException
*/
private void readMask(final AbstractDecoder pDec) throws IOException {
_transparencyMask = new BitmapMask(_descriptor);
_transparencyMask.read(pDec);
}
/**
* Thanks to eml@ill.com for pointing out that official color count might
* not be what it should: 2^BPP specifies the miminum size for the color
* palette!
* @return The verified color count.
*/
private int getVerifiedColorCount() {
int lColorCount = getColorCount();
final int lColorCount2 = 1 << _descriptor.getBPP();
if (lColorCount < lColorCount2) {
lColorCount = lColorCount2;
}
return lColorCount;
}
/**
* Return bytes per scan line rounded up to the next 4 byte boundary.
* @param pWidth
* The image width.
* @param pBPP
* Bytes per pixel.
* @return Bytes per scan line rounded up to the next 4 byte boundar.
*/
protected static int getBytesPerScanLine(final int pWidth, final int pBPP) {
final double lBytesPerPixels = (double) pBPP / 8;
int lBytesPerScanLine = (int) Math.ceil(pWidth * lBytesPerPixels);
if ((lBytesPerScanLine & 0x03) != 0) {
// Not on 4 byte boundary.
lBytesPerScanLine = (lBytesPerScanLine & ~0x03) + 4;
}
return lBytesPerScanLine;
}
/**
* @return BufferedImage (palette) created from the indexed bitmap.
*/
public BufferedImage createImageIndexed() {
final IndexColorModel lModel = createColorModel();
final BufferedImage lImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_BYTE_INDEXED, lModel);
lImage.getRaster()
.setSamples(0, 0, getWidth(), getHeight(), 0, _pixels);
return lImage;
}
/**
* @return Color model created from color palette in entry.
*/
private IndexColorModel createColorModel() {
final int lColorCount = getVerifiedColorCount();
final byte[] lRed = new byte[lColorCount];
final byte[] lGreen = new byte[lColorCount];
final byte[] lBlue = new byte[lColorCount];
final byte[] lAlpha = new byte[lColorCount];
for (int lColorNo = 0; lColorNo < lColorCount; lColorNo++) {
final Color lColor = getColor(lColorNo);
lRed[lColorNo] = (byte) lColor.getRed();
lGreen[lColorNo] = (byte) lColor.getGreen();
lBlue[lColorNo] = (byte) lColor.getBlue();
lAlpha[lColorNo] = (byte) OPAQUE;
}
final IndexColorModel lModel = new IndexColorModel(8, lColorCount,
lRed, lGreen, lBlue, lAlpha);
return lModel;
}
/**
* @return BufferedImage (ARGB) from the indexed bitmap.
*/
public BufferedImage createImageRGB() {
final BufferedImage lImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_ARGB);
// For each pixel, copy the color information.
for (int lYPos = 0; lYPos < getHeight(); lYPos++) {
for (int lXPos = 0; lXPos < getWidth(); lXPos++) {
int lRGB = getColor(lXPos, lYPos).getRGB();
if (_transparencyMask.isOpaque(lXPos, lYPos)) {
// Visible (sic), set alpha to opaque
lRGB |= 0xFF000000;
} else {
// Invisible, set alpha to transparent.
lRGB &= 0x00FFFFFF;
}
lImage.setRGB(lXPos, lYPos, lRGB);
}
}
return lImage;
}
/**
* Get the color for the specified point.
* @param pXPos
* The x position.
* @param pYPos
* The y position.
* @return Color of the selected point.
*/
public Color getColor(final int pXPos, final int pYPos) {
return getColor(getPaletteIndex(pXPos, pYPos));
}
/**
* Index into the color palette for the specified point.
* @param pXPos
* The x position.
* @param pYPos
* The y position.
* @return Palette index for pixel x, y
*/
public int getPaletteIndex(final int pXPos, final int pYPos) {
return _pixels[pYPos * getWidth() + pXPos];
}
/**
* Get the color for the specified color palette index.
* @param pIndex
* of the color requested.
* @return Requested color.
*/
public Color getColor(final int pIndex) {
if (pIndex >= getVerifiedColorCount()) {
throw new IllegalArgumentException("Color index out of range: is "
+ pIndex + ", max. " + getVerifiedColorCount());
}
return _colorPalette[pIndex];
}
/**
* @param pIndex
* Color index.
* @param pColor
* Color to set.
*/
private void setColor(final int pIndex, final Color pColor) {
_colorPalette[pIndex] = pColor;
}
}
The table below shows all metrics for AbstractBitmapIndexed.java.




