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 Igor V. Stolyarov 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @version $Revision$ 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage java.awt.image; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The RGBImageFilter class represents a filter which modifies pixels of an 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * image in the default RGB ColorModel. 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @since Android 1.0 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class RGBImageFilter extends ImageFilter { 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The original model is the ColorModel to be replaced by the new model when 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * substituteColorModel is called. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected ColorModel origmodel; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The new model is the ColorModel with which to replace the original model 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when substituteColorModel is called. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected ColorModel newmodel; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The canFilterIndexColorModel indicates if it is acceptable to apply the 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * color filtering of the filterRGB method to the color table entries of an 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * IndexColorModel object. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean canFilterIndexColorModel; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Instantiates a new RGBImageFilter. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RGBImageFilter() { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Filters an IndexColorModel object by calling filterRGB function for each 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * entry of IndexColorModel. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param icm 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the IndexColorModel to be filtered. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the IndexColorModel. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public IndexColorModel filterIndexColorModel(IndexColorModel icm) { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int transferType = icm.getTransferType(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bits = icm.getPixelSize(); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mapSize = icm.getMapSize(); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int colorMap[] = new int[mapSize]; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int filteredColorMap[] = new int[mapSize]; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project icm.getRGBs(colorMap); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int trans = -1; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasAlpha = false; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < mapSize; i++) { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int alpha = filteredColorMap[i] >>> 24; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alpha != 0xff) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!hasAlpha) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasAlpha = true; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alpha == 0 && trans < 0) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project trans = i; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new IndexColorModel(bits, mapSize, filteredColorMap, 0, hasAlpha, trans, 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project transferType); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Replaces the original color model and the new one. 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param oldcm 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the old ColorModel. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param newcm 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the new ColorModel. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void substituteColorModel(ColorModel oldcm, ColorModel newcm) { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project origmodel = oldcm; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newmodel = newcm; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorModel(ColorModel model) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (model instanceof IndexColorModel && canFilterIndexColorModel) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IndexColorModel icm = (IndexColorModel)model; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorModel filteredModel = filterIndexColorModel(icm); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project substituteColorModel(model, filteredModel); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumer.setColorModel(filteredModel); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumer.setColorModel(ColorModel.getRGBdefault()); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scansize) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (model == null || model == origmodel) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rgbPixels[] = new int[w]; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sx = x, idx = 0; sx < x + w; sx++, idx++) { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scansize) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (model == null || model == origmodel) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rgbPixels[] = new int[w]; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sy = y, pixelsOff = off; sy < y + h; sy++, pixelsOff += scansize) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sx = x, idx = 0; sx < x + w; sx++, idx++) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx] & 0xff); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Filters a region of pixels in the default RGB ColorModel by calling the 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * filterRGB method for them. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the X coordinate of region. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the Y coordinate of region. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param w 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the width of region. 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param h 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the height of region. 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pixels 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the pixels array. 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param off 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the offset of array. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param scansize 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the distance between rows of pixels in the array. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, int off, int scansize) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int sx = x, idx = 0; sx < x + w; sx++, idx++) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pixels[lineOff + idx] = filterRGB(sx, sy, pixels[lineOff + idx]); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, off, scansize); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Converts a single input pixel in the default RGB ColorModel to a single 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output pixel. 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the X pixel's coordinate. 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the Y pixel's coordinate. 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rgb 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a pixel in the default RGB color model. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a filtered pixel in the default RGB color model. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract int filterRGB(int x, int y, int rgb); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 196