KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > ext > awt > image > rendered > Any2LsRGBRed


1 /*
2
3    Copyright 2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.ext.awt.image.rendered;
19
20
21 import java.awt.Point JavaDoc;
22 import java.awt.Rectangle JavaDoc;
23 import java.awt.color.ColorSpace JavaDoc;
24 import java.awt.image.BandCombineOp JavaDoc;
25 import java.awt.image.BufferedImage JavaDoc;
26 import java.awt.image.ColorConvertOp JavaDoc;
27 import java.awt.image.ColorModel JavaDoc;
28 import java.awt.image.DataBuffer JavaDoc;
29 import java.awt.image.Raster JavaDoc;
30 import java.awt.image.SampleModel JavaDoc;
31 import java.awt.image.SinglePixelPackedSampleModel JavaDoc;
32 import java.awt.image.WritableRaster JavaDoc;
33
34 import org.apache.batik.ext.awt.image.GraphicsUtil;
35
36 /**
37  * This function will tranform an image from any colorspace into a
38  * luminance image. The alpha channel if any will be copied to the
39  * new image.
40  *
41  * @author <a HREF="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
42  * @version $Id: Any2LsRGBRed.java,v 1.6 2004/08/18 07:14:07 vhardy Exp $ */

43 public class Any2LsRGBRed extends AbstractRed {
44
45     boolean srcIssRGB = false;
46
47     /**
48      * Construct a luminace image from src.
49      *
50      * @param src The image to convert to a luminance image
51      */

52     public Any2LsRGBRed(CachableRed src) {
53         super(src,src.getBounds(),
54               fixColorModel(src),
55               fixSampleModel(src),
56               src.getTileGridXOffset(),
57               src.getTileGridYOffset(),
58               null);
59
60         ColorModel JavaDoc srcCM = src.getColorModel();
61         if (srcCM == null) return;
62         ColorSpace JavaDoc srcCS = srcCM.getColorSpace();
63         if (srcCS == ColorSpace.getInstance(ColorSpace.CS_sRGB))
64             srcIssRGB = true;
65     }
66
67     /**
68      * Gamma for linear to sRGB convertion
69      */

70     private static final double GAMMA = 2.4;
71     private static final double LFACT = 1.0/12.92;
72
73
74     public static final double sRGBToLsRGB(double value) {
75         if(value <= 0.003928)
76             return value*LFACT;
77         return Math.pow((value+0.055)/1.055, GAMMA);
78     }
79
80     /**
81      * Lookup tables for RGB lookups. The linearToSRGBLut is used
82      * when noise values are considered to be on a linearScale. The
83      * linearToLinear table is used when the values are considered to
84      * be on the sRGB scale to begin with.
85      */

86     private static final int sRGBToLsRGBLut[] = new int[256];
87     static {
88         final double scale = 1.0/255;
89
90         // System.out.print("S2L: ");
91
for(int i=0; i<256; i++){
92             double value = sRGBToLsRGB(i*scale);
93             sRGBToLsRGBLut[i] = (int)Math.round(value*255.0);
94             // System.out.print(sRGBToLsRGBLut[i] + ",");
95
}
96         // System.out.println("");
97
}
98
99     public WritableRaster JavaDoc copyData(WritableRaster JavaDoc wr) {
100         // Get my source.
101
CachableRed src = (CachableRed)getSources().get(0);
102         ColorModel JavaDoc srcCM = src.getColorModel();
103         SampleModel JavaDoc srcSM = src.getSampleModel();
104
105         // Fast case, SRGB source, INT Pack writable raster...
106
if (srcIssRGB &&
107             Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) {
108             src.copyData(wr);
109             if (srcCM.hasAlpha())
110                 GraphicsUtil.coerceData(wr, srcCM, false);
111             Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut);
112             return wr;
113         }
114
115         if (srcCM == null) {
116             // We don't really know much about this source, let's
117
// guess based on the number of bands...
118

119             float [][] matrix = null;
120             switch (srcSM.getNumBands()) {
121             case 1:
122                 matrix = new float[1][3];
123                 matrix[0][0] = 1; // Red
124
matrix[0][1] = 1; // Grn
125
matrix[0][2] = 1; // Blu
126
break;
127             case 2:
128                 matrix = new float[2][4];
129                 matrix[0][0] = 1; // Red
130
matrix[0][1] = 1; // Grn
131
matrix[0][2] = 1; // Blu
132
matrix[1][3] = 1; // Alpha
133
break;
134             case 3:
135                 matrix = new float[3][3];
136                 matrix[0][0] = 1; // Red
137
matrix[1][1] = 1; // Grn
138
matrix[2][2] = 1; // Blu
139
break;
140             default:
141                 matrix = new float[srcSM.getNumBands()][4];
142                 matrix[0][0] = 1; // Red
143
matrix[1][1] = 1; // Grn
144
matrix[2][2] = 1; // Blu
145
matrix[3][3] = 1; // Alpha
146
break;
147             }
148
149             Raster JavaDoc srcRas = src.getData(wr.getBounds());
150             BandCombineOp JavaDoc op = new BandCombineOp JavaDoc(matrix, null);
151             op.filter(srcRas, wr);
152         } else {
153             ColorModel JavaDoc dstCM = getColorModel();
154             BufferedImage JavaDoc dstBI;
155
156             if (!dstCM.hasAlpha()) {
157                 // No alpha ao we don't have to work around the bug
158
// in the color convert op.
159
dstBI = new BufferedImage JavaDoc
160                     (dstCM, wr.createWritableTranslatedChild(0,0),
161                      dstCM.isAlphaPremultiplied(), null);
162             } else {
163                 // All this nonsense is to work around the fact that
164
// the Color convert op doesn't properly copy the
165
// Alpha from src to dst.
166
SinglePixelPackedSampleModel JavaDoc dstSM;
167                 dstSM = (SinglePixelPackedSampleModel JavaDoc)wr.getSampleModel();
168                 int [] masks = dstSM.getBitMasks();
169                 SampleModel JavaDoc dstSMNoA = new SinglePixelPackedSampleModel JavaDoc
170                     (dstSM.getDataType(), dstSM.getWidth(), dstSM.getHeight(),
171                      dstSM.getScanlineStride(),
172                      new int[] {masks[0], masks[1], masks[2]});
173                 ColorModel JavaDoc dstCMNoA = GraphicsUtil.Linear_sRGB;
174
175                 WritableRaster JavaDoc dstWr;
176                 dstWr = Raster.createWritableRaster(dstSMNoA,
177                                                     wr.getDataBuffer(),
178                                                     new Point JavaDoc(0,0));
179                 dstWr = dstWr.createWritableChild
180                     (wr.getMinX()-wr.getSampleModelTranslateX(),
181                      wr.getMinY()-wr.getSampleModelTranslateY(),
182                      wr.getWidth(), wr.getHeight(),
183                      0, 0, null);
184                 
185                 dstBI = new BufferedImage JavaDoc(dstCMNoA, dstWr, false, null);
186             }
187
188             // Divide out alpha if we have it. We need to do this since
189
// the color convert may not be a linear operation which may
190
// lead to out of range values.
191
ColorModel JavaDoc srcBICM = srcCM;
192             WritableRaster JavaDoc srcWr;
193             if ((srcCM.hasAlpha() == true) &&
194                 (srcCM.isAlphaPremultiplied() != false)) {
195                 Rectangle JavaDoc wrR = wr.getBounds();
196                 SampleModel JavaDoc sm = srcCM.createCompatibleSampleModel
197                     (wrR.width, wrR.height);
198                 
199                 srcWr = Raster.createWritableRaster
200                     (sm, new Point JavaDoc(wrR.x, wrR.y));
201                 src.copyData(srcWr);
202                 srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false);
203             } else {
204                 Raster JavaDoc srcRas = src.getData(wr.getBounds());
205                 srcWr = GraphicsUtil.makeRasterWritable(srcRas);
206             }
207
208             BufferedImage JavaDoc srcBI;
209             srcBI = new BufferedImage JavaDoc(srcBICM,
210                                       srcWr.createWritableTranslatedChild(0,0),
211                                       false,
212                                       null);
213
214             /*
215              * System.out.println("src: " + srcBI.getWidth() + "x" +
216              * srcBI.getHeight());
217              * System.out.println("dst: " + dstBI.getWidth() + "x" +
218              * dstBI.getHeight());
219              */

220
221             ColorConvertOp JavaDoc op = new ColorConvertOp JavaDoc(null);
222             op.filter(srcBI, dstBI);
223
224             if (dstCM.hasAlpha())
225                 copyBand(srcWr, srcSM.getNumBands()-1,
226                          wr, getSampleModel().getNumBands()-1);
227         }
228         return wr;
229     }
230
231         /**
232          * This function 'fixes' the source's color model. Right now
233          * it just selects if it should have one or two bands based on
234          * if the source had an alpha channel.
235          */

236     protected static ColorModel JavaDoc fixColorModel(CachableRed src) {
237         ColorModel JavaDoc cm = src.getColorModel();
238         if (cm != null) {
239             if (cm.hasAlpha())
240                 return GraphicsUtil.Linear_sRGB_Unpre;
241
242             return GraphicsUtil.Linear_sRGB;
243         }
244         else {
245             // No ColorModel so try to make some intelligent
246
// decisions based just on the number of bands...
247
// 1 bands -> replicated into RGB
248
// 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult
249
// 3 bands -> sRGB (not-linear?)
250
// 4 bands -> sRGB premult (not-linear?)
251
SampleModel JavaDoc sm = src.getSampleModel();
252
253             switch (sm.getNumBands()) {
254             case 1:
255                 return GraphicsUtil.Linear_sRGB;
256             case 2:
257                 return GraphicsUtil.Linear_sRGB_Unpre;
258             case 3:
259                 return GraphicsUtil.Linear_sRGB;
260             }
261             return GraphicsUtil.Linear_sRGB_Unpre;
262         }
263     }
264
265     /**
266      * This function 'fixes' the source's sample model.
267      * Right now it just selects if it should have 3 or 4 bands
268      * based on if the source had an alpha channel.
269      */

270     protected static SampleModel JavaDoc fixSampleModel(CachableRed src) {
271         SampleModel JavaDoc sm = src.getSampleModel();
272         ColorModel JavaDoc cm = src.getColorModel();
273
274         boolean alpha = false;
275
276         if (cm != null)
277             alpha = cm.hasAlpha();
278         else {
279             switch (sm.getNumBands()) {
280             case 1: case 3:
281                 alpha = false;
282                 break;
283             default:
284                 alpha = true;
285                 break;
286             }
287         }
288         if (alpha)
289             return new SinglePixelPackedSampleModel JavaDoc
290                 (DataBuffer.TYPE_INT,
291                  sm.getWidth(),
292                  sm.getHeight(),
293                  new int [] {0xFF0000, 0xFF00, 0xFF, 0xFF000000});
294         else
295             return new SinglePixelPackedSampleModel JavaDoc
296                 (DataBuffer.TYPE_INT,
297                  sm.getWidth(),
298                  sm.getHeight(),
299                  new int [] {0xFF0000, 0xFF00, 0xFF});
300     }
301 }
302
Popular Tags