FileDocCategorySizeDatePackage
ColorScaler.javaAPI DocAndroid 1.5 API12884Wed May 06 22:41:54 BST 2009org.apache.harmony.awt.gl.color

ColorScaler

public class ColorScaler extends Object
This class provides functionality for scaling color data when ranges of the source and destination color values differs.

Fields Summary
private static final float
MAX_SHORT
private static final float
MAX_SIGNED_SHORT
private static final float
MAX_XYZ
private float[]
channelMinValues
private float[]
channelMulipliers
private float[]
invChannelMulipliers
int
nColorChannels
boolean
isTTypeIntegral
Constructors Summary
Methods Summary
public voidloadScalingData(java.awt.image.Raster r, java.awt.color.ICC_Profile pf)
Loads scaling data for raster. Note, if profile pf is null, for non-integral data types multipliers are not initialized.

param
r - raster
param
pf - profile which helps to determine the ranges of the color data


                                              
          
        boolean isSrcTTypeIntegral =
            r.getTransferType() != DataBuffer.TYPE_FLOAT &&
            r.getTransferType() != DataBuffer.TYPE_DOUBLE;
        if (isSrcTTypeIntegral)
            loadScalingData(r.getSampleModel());
        else if (pf != null)
            loadScalingData(pf);
    
public voidloadScalingData(java.awt.image.SampleModel sm)
Use this method only for integral transfer types. Extracts min/max values from the sample model

param
sm - sample model

        // Supposing integral transfer type
        isTTypeIntegral = true;

        nColorChannels = sm.getNumBands();

        channelMinValues = new float[nColorChannels];
        channelMulipliers = new float[nColorChannels];
        invChannelMulipliers = new float[nColorChannels];

        boolean isSignedShort =
            (sm.getTransferType() == DataBuffer.TYPE_SHORT);

        float maxVal;
        for (int i=0; i<nColorChannels; i++) {
            channelMinValues[i] = 0;
            if (isSignedShort) {
                channelMulipliers[i] = MAX_SHORT / MAX_SIGNED_SHORT;
                invChannelMulipliers[i] = MAX_SIGNED_SHORT / MAX_SHORT;
            } else {
                maxVal = ((1 << sm.getSampleSize(i)) - 1);
                channelMulipliers[i] = MAX_SHORT / maxVal;
                invChannelMulipliers[i] = maxVal / MAX_SHORT;
            }
        }
    
public voidloadScalingData(java.awt.color.ICC_Profile pf)
Use this method only for double of float transfer types. Extracts scaling data from the color space signature and other tags, stored in the profile

param
pf - ICC profile

        // Supposing double or float transfer type
        isTTypeIntegral = false;

        nColorChannels = pf.getNumComponents();

        // Get min/max values directly from the profile
        // Very much like fillMinMaxValues in ICC_ColorSpace
        float maxValues[] = new float[nColorChannels];
        float minValues[] = new float[nColorChannels];

        switch (pf.getColorSpaceType()) {
            case ColorSpace.TYPE_XYZ:
                minValues[0] = 0;
                minValues[1] = 0;
                minValues[2] = 0;
                maxValues[0] = MAX_XYZ;
                maxValues[1] = MAX_XYZ;
                maxValues[2] = MAX_XYZ;
                break;
            case ColorSpace.TYPE_Lab:
                minValues[0] = 0;
                minValues[1] = -128;
                minValues[2] = -128;
                maxValues[0] = 100;
                maxValues[1] = 127;
                maxValues[2] = 127;
                break;
            default:
                for (int i=0; i<nColorChannels; i++) {
                    minValues[i] = 0;
                    maxValues[i] = 1;
                }
        }

        channelMinValues = minValues;
        channelMulipliers = new float[nColorChannels];
        invChannelMulipliers = new float[nColorChannels];

        for (int i = 0; i < nColorChannels; i++) {
            channelMulipliers[i] =
                MAX_SHORT / (maxValues[i] - channelMinValues[i]);

            invChannelMulipliers[i] =
                (maxValues[i] - channelMinValues[i]) / MAX_SHORT;
        }
    
public voidloadScalingData(java.awt.color.ColorSpace cs)
Extracts scaling data from the color space

param
cs - color space

        nColorChannels = cs.getNumComponents();

        channelMinValues = new float[nColorChannels];
        channelMulipliers = new float[nColorChannels];
        invChannelMulipliers = new float[nColorChannels];

        for (int i = 0; i < nColorChannels; i++) {
            channelMinValues[i] = cs.getMinValue(i);

            channelMulipliers[i] =
                MAX_SHORT / (cs.getMaxValue(i) - channelMinValues[i]);

            invChannelMulipliers[i] =
                (cs.getMaxValue(i) - channelMinValues[i]) / MAX_SHORT;
        }
    
public short[]scale(java.awt.image.Raster r)
Scales the whole raster to short and returns the result in the array

param
r - source raster
return
scaled and normalized raster data

        int width = r.getWidth();
        int height = r.getHeight();
        short result[] = new short[width*height*nColorChannels];

        int pos = 0;
        if (isTTypeIntegral) {
            int sample;
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        sample = r.getSample(row, col, chan);
                        result[pos++] =
                            (short) (sample * channelMulipliers[chan] + 0.5f);
                    }
                }
            }
        } else {
            float sample;
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        sample = r.getSampleFloat(row, col, chan);
                        result[pos++] = (short) ((sample - channelMinValues[chan])
                            * channelMulipliers[chan] + 0.5f);
                    }
                }
            }
        }
        return result;
    
public voidscale(float[] pixelData, short[] chanData, int chanDataOffset)
Scales one pixel and puts obtained values to the chanData

param
pixelData - input pixel
param
chanData - output buffer
param
chanDataOffset - output buffer offset

        for (int chan = 0; chan < nColorChannels; chan++) {
            chanData[chanDataOffset + chan] =
                    (short) ((pixelData[chan] - channelMinValues[chan]) *
                        channelMulipliers[chan] + 0.5f);
        }
    
public float[][]scaleNormalize(java.awt.image.Raster r)
Scales and normalizes the whole raster and returns the result in the float array

param
r - source raster
return
scaled and normalized raster data

        int width = r.getWidth();
        int height = r.getHeight();
        float result[][] = new float[width*height][nColorChannels];
        float normMultipliers[] = new float[nColorChannels];

        int pos = 0;
        if (isTTypeIntegral) {
            // Change max value from MAX_SHORT to 1f
            for (int i=0; i<nColorChannels; i++) {
                normMultipliers[i] = channelMulipliers[i] / MAX_SHORT;
            }

            int sample;
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        sample = r.getSample(row, col, chan);
                        result[pos][chan] = (sample * normMultipliers[chan]);
                    }
                    pos++;
                }
            }
        } else { // Just get the samples...
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        result[pos][chan] = r.getSampleFloat(row, col, chan);
                    }
                    pos++;
                }
            }
        }
        return result;
    
public voidunscale(float[] pixelData, short[] chanData, int chanDataOffset)
Unscales one pixel and puts obtained values to the pixelData

param
pixelData - output pixel
param
chanData - input buffer
param
chanDataOffset - input buffer offset

        for (int chan = 0; chan < nColorChannels; chan++) {
            pixelData[chan] = (chanData[chanDataOffset + chan] & 0xFFFF)
                * invChannelMulipliers[chan] + channelMinValues[chan];
        }
    
public voidunscale(short[] data, java.awt.image.WritableRaster wr)
Unscales the whole data array and puts obtained values to the raster

param
data - input data
param
wr - destination raster

        int width = wr.getWidth();
        int height = wr.getHeight();

        int pos = 0;
        if (isTTypeIntegral) {
            int sample;
            for (int row=wr.getMinX(); row<width; row++) {
                for (int col=wr.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                         sample = (int) ((data[pos++] & 0xFFFF) *
                                invChannelMulipliers[chan] + 0.5f);
                         wr.setSample(row, col, chan, sample);
                    }
                }
            }
        } else {
            float sample;
            for (int row=wr.getMinX(); row<width; row++) {
                for (int col=wr.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                         sample = (data[pos++] & 0xFFFF) *
                            invChannelMulipliers[chan] + channelMinValues[chan];
                         wr.setSample(row, col, chan, sample);
                    }
                }
            }
        }
    
public voidunscaleNormalized(java.awt.image.WritableRaster r, float[][] data)
Unscale the whole float array and put the result in the raster

param
r - destination raster
param
data - input pixels

        int width = r.getWidth();
        int height = r.getHeight();
        float normMultipliers[] = new float[nColorChannels];

        int pos = 0;
        if (isTTypeIntegral) {
            // Change max value from MAX_SHORT to 1f
            for (int i=0; i<nColorChannels; i++) {
                normMultipliers[i] = invChannelMulipliers[i] * MAX_SHORT;
            }

            int sample;
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        sample = (int) (data[pos][chan] * normMultipliers[chan] + 0.5f);
                        r.setSample(row, col, chan, sample);
                    }
                    pos++;
                }
            }
        } else { // Just set the samples...
            for (int row=r.getMinX(); row<width; row++) {
                for (int col=r.getMinY(); col<height; col++) {
                    for (int chan = 0; chan < nColorChannels; chan++) {
                        r.setSample(row, col, chan, data[pos][chan]);
                    }
                    pos++;
                }
            }
        }