{
LOG.error("Something went wrong ... the pixelmap doesn't contain any data.");
return null;
}
// Get the ColorModel right
PDColorSpace colorspace = getColorSpace();
if (colorspace == null)
{
LOG.error("getColorSpace() returned NULL. Predictor = " + getPredictor());
return null;
}
ColorModel cm = null;
if (colorspace instanceof PDIndexed)
{
PDIndexed csIndexed = (PDIndexed)colorspace;
// the base color space uses 8 bit per component, as the indexed color values
// of an indexed color space are always in a range from 0 to 255
ColorModel baseColorModel = csIndexed.getBaseColorSpace().createColorModel(8);
// number of possible color values in the target color space
int numberOfColorValues = 1 << bpc;
// number of indexed color values
int highValue = csIndexed.getHighValue();
// choose the correct size, sometimes there are more indexed values than needed
// and sometimes there are fewer indexed value than possible
int size = Math.min(numberOfColorValues-1, highValue);
byte[] index = csIndexed.getLookupData();
boolean hasAlpha = baseColorModel.hasAlpha();
COSBase maskArray = getMask();
if( baseColorModel.getTransferType() != DataBuffer.TYPE_BYTE )
{
throw new IOException( "Not implemented" );
}
// the IndexColorModel uses RGB-based color values
// which leads to 3 color components and a optional alpha channel
int numberOfComponents = 3 + (hasAlpha ? 1 : 0);
int buffersize = (size+1) * numberOfComponents;
byte[] colorValues = new byte[buffersize];
byte[] inData = new byte[baseColorModel.getNumComponents()];
int bufferIndex = 0;
for( int i = 0; i <= size; i++ )
{
System.arraycopy(index, i * inData.length, inData, 0, inData.length);
// convert the indexed color values to RGB
colorValues[bufferIndex] = (byte)baseColorModel.getRed(inData);
colorValues[bufferIndex+1] = (byte)baseColorModel.getGreen(inData);
colorValues[bufferIndex+2] = (byte)baseColorModel.getBlue(inData);
if( hasAlpha )
{
colorValues[bufferIndex+3] = (byte)baseColorModel.getAlpha(inData);
}
bufferIndex += numberOfComponents;
}
if (maskArray != null && maskArray instanceof COSArray)
{
cm = new IndexColorModel(bpc, size+1, colorValues, 0, hasAlpha, ((COSArray)maskArray).getInt(0));
}
else
{
cm = new IndexColorModel(bpc, size+1, colorValues, 0, hasAlpha);
}
}
else if (colorspace instanceof PDSeparation)
{
PDSeparation csSeparation = (PDSeparation)colorspace;
int numberOfComponents = csSeparation.getAlternateColorSpace().getNumberOfComponents();
PDFunction tintTransformFunc = csSeparation.getTintTransform();
COSArray decode = getDecode();
// we have to invert the tint-values,
// if the Decode array exists and consists of (1,0)
boolean invert = decode != null && decode.getInt(0) == 1;
// TODO add interpolation for other decode values then 1,0
int maxValue = (int)Math.pow(2,bpc) - 1;
// destination array
byte[] mappedData = new byte[width*height*numberOfComponents];
int rowLength = width*numberOfComponents;
float[] input = new float[1];
for ( int i = 0; i < height; i++ )
{
int rowOffset = i * rowLength;
for (int j = 0; j < width; j++)
{
// scale tint values to a range of 0...1
int value = (array[ i * width + j ] + 256) % 256;
if (invert)
{
input[0] = 1-(value / maxValue);
}
else
{
input[0] = value / maxValue;
}
float[] mappedColor = tintTransformFunc.eval(input);
int columnOffset = j * numberOfComponents;
for ( int k = 0; k < numberOfComponents; k++ )
{
// redo scaling for every single color value
float mappedValue = mappedColor[k];
mappedData[ rowOffset + columnOffset + k] = (byte)(mappedValue * maxValue);
}
}
}
array = mappedData;
cm = colorspace.createColorModel( bpc );
}
else if (bpc == 1)
{
byte[] map = null;
if (colorspace instanceof PDDeviceGray)
{
COSArray decode = getDecode();
// we have to invert the b/w-values,
// if the Decode array exists and consists of (1,0)
if (decode != null && decode.getInt(0) == 1)
{
map = new byte[] {(byte)0xff};
}
else
{
map = new byte[] {(byte)0x00, (byte)0xff};
}
}
else if (colorspace instanceof PDICCBased)
{
if ( ((PDICCBased)colorspace).getNumberOfComponents() == 1)
{
map = new byte[] {(byte)0xff};
}
else
{
map = new byte[] {(byte)0x00, (byte)0xff};
}
}
else
{
map = new byte[] {(byte)0x00, (byte)0xff};
}
cm = new IndexColorModel(bpc, map.length, map, map, map, Transparency.OPAQUE);
}
else
{
if (colorspace instanceof PDICCBased)
{
if (((PDICCBased)colorspace).getNumberOfComponents() == 1)
{
byte[] map = new byte[] {(byte)0xff};
cm = new IndexColorModel(bpc, 1, map, map, map, Transparency.OPAQUE);
}
else
{
cm = colorspace.createColorModel( bpc );
}
}
else
{
cm = colorspace.createColorModel( bpc );
}
}
LOG.debug("ColorModel: " + cm.toString());
WritableRaster raster = cm.createCompatibleWritableRaster( width, height );