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

ColorConverter

public class ColorConverter extends Object
This class combines ColorScaler, ICC_Transform and NativeImageFormat functionality in the workflows for different types of input/output pixel data.

Fields Summary
private ColorScaler
scaler
Constructors Summary
Methods Summary
private NativeImageFormatcreateImageFormat(java.awt.image.BufferedImage bi)
Creates NativeImageFormat from buffered image.

param
bi - buffered image
return
created NativeImageFormat

        int nRows = bi.getHeight();
        int nCols = bi.getWidth();
        int nComps = bi.getColorModel().getNumColorComponents();
        short imgData[] = new short[nRows*nCols*nComps];
        return new NativeImageFormat(
                imgData, nComps, nRows, nCols);
    
private NativeImageFormatcreateImageFormat(ICC_Transform t, short[] arr, int nCols, boolean in)
Creates one-row NativeImageFormat, using either nCols if it is positive, or arr.length to determine the number of pixels

param
t - transform
param
arr - short array or null if nCols is positive
param
nCols - number of pixels in the array or 0 if array is not null
param
in - is it an input or output array
return
one-row NativeImageFormat

        int nComponents = in ? t.getNumInputChannels() : t.getNumOutputChannels();

        if (arr == null || arr.length < nCols*nComponents) {
            arr = new short[nCols*nComponents];
        }

        if (nCols == 0)
            nCols = arr.length / nComponents;

        return new NativeImageFormat(arr, nComponents, 1, nCols);
    
public voidloadScalingData(java.awt.color.ColorSpace cs)


        
        scaler.loadScalingData(cs);
    
public voidtranslateColor(ICC_Transform t, java.awt.image.BufferedImage src, java.awt.image.BufferedImage dst)
Translates pixels, stored in source buffered image and writes the data to the destination image.

param
t - ICC transform
param
src - source image
param
dst - destination image

      NativeImageFormat srcIF = NativeImageFormat.createNativeImageFormat(src);
      NativeImageFormat dstIF = NativeImageFormat.createNativeImageFormat(dst);

      if (srcIF != null && dstIF != null) {
          t.translateColors(srcIF, dstIF);
          return;
      }

        srcIF = createImageFormat(src);
        dstIF = createImageFormat(dst);

        short srcChanData[] = (short[]) srcIF.getChannelData();
        short dstChanData[] = (short[]) dstIF.getChannelData();

        ColorModel srcCM = src.getColorModel();
        int nColorChannels = srcCM.getNumColorComponents();
        scaler.loadScalingData(srcCM.getColorSpace()); // input scaling data
        ColorModel dstCM = dst.getColorModel();

        // Prepare array for alpha channel
        float alpha[] = null;
        boolean saveAlpha = srcCM.hasAlpha() && dstCM.hasAlpha();
        if (saveAlpha) {
            alpha = new float[src.getWidth()*src.getHeight()];
        }

        WritableRaster wr = src.getRaster();
        int srcDataPos = 0, alphaPos = 0;
        float normalizedVal[];
        for (int row=0, nRows = srcIF.getNumRows(); row<nRows; row++) {
            for (int col=0, nCols = srcIF.getNumCols(); col<nCols; col++) {
                normalizedVal = srcCM.getNormalizedComponents(
                    wr.getDataElements(col, row, null),
                    null, 0);
                // Save alpha channel
                if (saveAlpha) {
                    // We need nColorChannels'th element cause it's nChannels - 1
                    alpha[alphaPos++] = normalizedVal[nColorChannels];
                }
                scaler.scale(normalizedVal, srcChanData, srcDataPos);
                srcDataPos += nColorChannels;
            }
        }

        t.translateColors(srcIF, dstIF);

        nColorChannels = dstCM.getNumColorComponents();
        boolean fillAlpha = dstCM.hasAlpha();
        scaler.loadScalingData(dstCM.getColorSpace()); // output scaling data
        float dstPixel[] = new float[dstCM.getNumComponents()];
        int dstDataPos = 0;
        alphaPos = 0;
        wr = dst.getRaster();

        for (int row=0, nRows = dstIF.getNumRows(); row<nRows; row++) {
            for (int col=0, nCols = dstIF.getNumCols(); col<nCols; col++) {
                scaler.unscale(dstPixel, dstChanData, dstDataPos);
                dstDataPos += nColorChannels;
                if (fillAlpha) {
                    if (saveAlpha) {
                        dstPixel[nColorChannels] = alpha[alphaPos++];
                    } else {
                        dstPixel[nColorChannels] = 1f;
                    }
                }
                wr.setDataElements(col, row,
                        dstCM.getDataElements(dstPixel, 0 , null));
            }
        }
    
public float[][]translateColor(ICC_Transform t, float[][] buffer, java.awt.color.ColorSpace srcCS, java.awt.color.ColorSpace dstCS, int nPixels)
Translates pixels, stored in the float data buffer. Each pixel occupies separate array. Input pixels passed in the buffer are replaced by output pixels and then the buffer is returned

param
t - ICC transform
param
buffer - data buffer
param
srcCS - source color space
param
dstCS - destination color space
param
nPixels - number of pixels
return
translated pixels

        // Scale source data
        if (srcCS != null) { // if it is null use old scaling data
            scaler.loadScalingData(srcCS);
        }
        int nSrcChannels = t.getNumInputChannels();
        short srcShortData[] = new short[nPixels*nSrcChannels];
        for (int i=0, srcDataPos = 0; i<nPixels; i++) {
            scaler.scale(buffer[i], srcShortData, srcDataPos);
            srcDataPos += nSrcChannels;
        }

        // Apply transform
        short dstShortData[] = this.translateColor(t, srcShortData, null);

        int nDstChannels = t.getNumOutputChannels();
        int bufferSize = buffer[0].length;
        if (bufferSize < nDstChannels + 1) { // Re-allocate buffer if needed
            for (int i=0; i<nPixels; i++) {
                // One extra element reserved for alpha
                buffer[i] = new float[nDstChannels + 1];
            }
        }

        // Unscale destination data
        if (dstCS != null) { // if it is null use old scaling data
            scaler.loadScalingData(dstCS);
        }
        for (int i=0, dstDataPos = 0; i<nPixels; i++) {
            scaler.unscale(buffer[i], dstShortData, dstDataPos);
            dstDataPos += nDstChannels;
        }

        return buffer;
    
public voidtranslateColor(ICC_Transform t, java.awt.image.Raster src, java.awt.image.WritableRaster dst)
Translates pixels stored in a raster. All data types are supported

param
t - ICC transform
param
src - source pixels
param
dst - destination pixels

        try{
            NativeImageFormat srcFmt = NativeImageFormat.createNativeImageFormat(src);
            NativeImageFormat dstFmt = NativeImageFormat.createNativeImageFormat(dst);

          if (srcFmt != null && dstFmt != null) {
              t.translateColors(srcFmt, dstFmt);
              return;
          }
        } catch (IllegalArgumentException e) {
      }

        // Go ahead and rescale the source image
        scaler.loadScalingData(src, t.getSrc());
        short srcData[] = scaler.scale(src);

        short dstData[] = translateColor(t, srcData, null);

        scaler.loadScalingData(dst, t.getDst());
        scaler.unscale(dstData, dst);
   
public short[]translateColor(ICC_Transform t, short[] src, short[] dst)
Translates pixels stored in an array of shorts. Samples are stored one-by-one, i.e. array structure is like following: RGBRGBRGB... The number of pixels is (size of the array) / (number of components).

param
t - ICC transform
param
src - source pixels
param
dst - destination pixels
return
destination pixels, stored in the array, passed in dst

        NativeImageFormat srcFmt = createImageFormat(t, src, 0, true);
        NativeImageFormat dstFmt = createImageFormat(t, dst, srcFmt.getNumCols(), false);

        t.translateColors(srcFmt, dstFmt);

        return (short[]) dstFmt.getChannelData();