19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this work for additional information regarding copyright ownership. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (the "License"); you may not use this file except in compliance with 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @author Oleg V. Khaschansky 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @version $Revision$ 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage org.apache.harmony.awt.gl.color; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.color.ColorSpace; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.BufferedImage; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.ColorModel; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.Raster; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.image.WritableRaster; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class combines ColorScaler, ICC_Transform and NativeImageFormat functionality 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the workflows for different types of input/output pixel data. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorConverter { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ColorScaler scaler = new ColorScaler(); 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void loadScalingData(ColorSpace cs) { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(cs); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates pixels, stored in source buffered image and writes the data 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the destination image. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t - ICC transform 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param src - source image 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dst - destination image 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void translateColor(ICC_Transform t, 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BufferedImage src, BufferedImage dst) { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat srcIF = NativeImageFormat.createNativeImageFormat(src); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat dstIF = NativeImageFormat.createNativeImageFormat(dst); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (srcIF != null && dstIF != null) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.translateColors(srcIF, dstIF); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project srcIF = createImageFormat(src); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstIF = createImageFormat(dst); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short srcChanData[] = (short[]) srcIF.getChannelData(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short dstChanData[] = (short[]) dstIF.getChannelData(); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorModel srcCM = src.getColorModel(); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nColorChannels = srcCM.getNumColorComponents(); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(srcCM.getColorSpace()); // input scaling data 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorModel dstCM = dst.getColorModel(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Prepare array for alpha channel 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float alpha[] = null; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean saveAlpha = srcCM.hasAlpha() && dstCM.hasAlpha(); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (saveAlpha) { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alpha = new float[src.getWidth()*src.getHeight()]; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WritableRaster wr = src.getRaster(); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int srcDataPos = 0, alphaPos = 0; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float normalizedVal[]; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int row=0, nRows = srcIF.getNumRows(); row<nRows; row++) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int col=0, nCols = srcIF.getNumCols(); col<nCols; col++) { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project normalizedVal = srcCM.getNormalizedComponents( 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wr.getDataElements(col, row, null), 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, 0); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Save alpha channel 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (saveAlpha) { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need nColorChannels'th element cause it's nChannels - 1 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alpha[alphaPos++] = normalizedVal[nColorChannels]; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.scale(normalizedVal, srcChanData, srcDataPos); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project srcDataPos += nColorChannels; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.translateColors(srcIF, dstIF); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nColorChannels = dstCM.getNumColorComponents(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean fillAlpha = dstCM.hasAlpha(); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(dstCM.getColorSpace()); // output scaling data 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dstPixel[] = new float[dstCM.getNumComponents()]; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dstDataPos = 0; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alphaPos = 0; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wr = dst.getRaster(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int row=0, nRows = dstIF.getNumRows(); row<nRows; row++) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int col=0, nCols = dstIF.getNumCols(); col<nCols; col++) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.unscale(dstPixel, dstChanData, dstDataPos); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstDataPos += nColorChannels; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fillAlpha) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (saveAlpha) { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstPixel[nColorChannels] = alpha[alphaPos++]; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstPixel[nColorChannels] = 1f; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wr.setDataElements(col, row, 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstCM.getDataElements(dstPixel, 0 , null)); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates pixels, stored in the float data buffer. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Each pixel occupies separate array. Input pixels passed in the buffer 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are replaced by output pixels and then the buffer is returned 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t - ICC transform 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param buffer - data buffer 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param srcCS - source color space 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dstCS - destination color space 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nPixels - number of pixels 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return translated pixels 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[][] translateColor(ICC_Transform t, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float buffer[][], 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorSpace srcCS, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorSpace dstCS, 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nPixels) { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Scale source data 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (srcCS != null) { // if it is null use old scaling data 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(srcCS); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nSrcChannels = t.getNumInputChannels(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short srcShortData[] = new short[nPixels*nSrcChannels]; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0, srcDataPos = 0; i<nPixels; i++) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.scale(buffer[i], srcShortData, srcDataPos); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project srcDataPos += nSrcChannels; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Apply transform 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short dstShortData[] = this.translateColor(t, srcShortData, null); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nDstChannels = t.getNumOutputChannels(); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bufferSize = buffer[0].length; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bufferSize < nDstChannels + 1) { // Re-allocate buffer if needed 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<nPixels; i++) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // One extra element reserved for alpha 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buffer[i] = new float[nDstChannels + 1]; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Unscale destination data 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dstCS != null) { // if it is null use old scaling data 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(dstCS); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0, dstDataPos = 0; i<nPixels; i++) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.unscale(buffer[i], dstShortData, dstDataPos); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dstDataPos += nDstChannels; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return buffer; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates pixels stored in a raster. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All data types are supported 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t - ICC transform 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param src - source pixels 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dst - destination pixels 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void translateColor(ICC_Transform t, Raster src, WritableRaster dst) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try{ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat srcFmt = NativeImageFormat.createNativeImageFormat(src); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat dstFmt = NativeImageFormat.createNativeImageFormat(dst); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (srcFmt != null && dstFmt != null) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.translateColors(srcFmt, dstFmt); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Go ahead and rescale the source image 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(src, t.getSrc()); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short srcData[] = scaler.scale(src); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short dstData[] = translateColor(t, srcData, null); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.loadScalingData(dst, t.getDst()); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaler.unscale(dstData, dst); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates pixels stored in an array of shorts. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Samples are stored one-by-one, i.e. array structure is like following: RGBRGBRGB... 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of pixels is (size of the array) / (number of components). 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t - ICC transform 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param src - source pixels 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param dst - destination pixels 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return destination pixels, stored in the array, passed in dst 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public short[] translateColor(ICC_Transform t, short src[], short dst[]) { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat srcFmt = createImageFormat(t, src, 0, true); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NativeImageFormat dstFmt = createImageFormat(t, dst, srcFmt.getNumCols(), false); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.translateColors(srcFmt, dstFmt); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (short[]) dstFmt.getChannelData(); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates NativeImageFormat from buffered image. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bi - buffered image 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return created NativeImageFormat 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private NativeImageFormat createImageFormat(BufferedImage bi) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nRows = bi.getHeight(); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nCols = bi.getWidth(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nComps = bi.getColorModel().getNumColorComponents(); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project short imgData[] = new short[nRows*nCols*nComps]; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new NativeImageFormat( 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imgData, nComps, nRows, nCols); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates one-row NativeImageFormat, using either nCols if it is positive, 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or arr.length to determine the number of pixels 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t - transform 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param arr - short array or null if nCols is positive 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nCols - number of pixels in the array or 0 if array is not null 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param in - is it an input or output array 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return one-row NativeImageFormat 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private NativeImageFormat createImageFormat( 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ICC_Transform t, short arr[], int nCols, boolean in 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nComponents = in ? t.getNumInputChannels() : t.getNumOutputChannels(); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (arr == null || arr.length < nCols*nComponents) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arr = new short[nCols*nComponents]; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nCols == 0) 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nCols = arr.length / nComponents; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new NativeImageFormat(arr, nComponents, 1, nCols); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 258