KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.awt.Graphics2D JavaDoc;
21 import java.awt.Point JavaDoc;
22 import java.awt.RenderingHints JavaDoc;
23 import java.awt.Transparency JavaDoc;
24 import java.awt.color.ColorSpace JavaDoc;
25 import java.awt.image.BandedSampleModel JavaDoc;
26 import java.awt.image.BufferedImage JavaDoc;
27 import java.awt.image.ColorConvertOp JavaDoc;
28 import java.awt.image.ColorModel JavaDoc;
29 import java.awt.image.ComponentColorModel JavaDoc;
30 import java.awt.image.DataBuffer JavaDoc;
31 import java.awt.image.DataBufferByte JavaDoc;
32 import java.awt.image.DirectColorModel JavaDoc;
33 import java.awt.image.Raster JavaDoc;
34 import java.awt.image.RenderedImage JavaDoc;
35 import java.awt.image.WritableRaster JavaDoc;
36
37 import org.apache.batik.ext.awt.color.ICCColorSpaceExt;
38
39
40 /**
41  * This implementation of rendered image forces a color profile
42  * on its source
43  *
44  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
45  * @version $Id: ProfileRed.java,v 1.8 2004/08/18 07:14:08 vhardy Exp $
46  */

47 public class ProfileRed extends AbstractRed {
48     private static final ColorSpace JavaDoc sRGBCS
49         = ColorSpace.getInstance(ColorSpace.CS_sRGB);
50     private static final ColorModel JavaDoc sRGBCM
51         = new DirectColorModel JavaDoc(sRGBCS,
52                                32,
53                                0x00ff0000,
54                                0x0000ff00,
55                                0x000000ff,
56                                0xff000000,
57                                false,
58                                DataBuffer.TYPE_INT);
59
60     private ICCColorSpaceExt colorSpace;
61
62     /**
63      * @param src Images on which the input ColorSpace should
64      * be forced
65      * @param colorSpace colorSpace that should be forced on the
66      * source
67      */

68     public ProfileRed(CachableRed src,
69                       ICCColorSpaceExt colorSpace){
70         this.colorSpace = colorSpace;
71
72         init(src, src.getBounds(),
73              sRGBCM, sRGBCM.createCompatibleSampleModel(src.getWidth(),
74                                                         src.getHeight()),
75              src.getTileGridXOffset(), src.getTileGridYOffset(), null);
76              
77     }
78
79     public CachableRed getSource() {
80         return (CachableRed)getSources().get(0);
81     }
82
83     /**
84      * This method will turn the input image in an sRGB image as follows.
85      * If there is no colorSpace defined, then the input image is
86      * simply converted to singlePixelPacked sRGB if needed.
87      * If there is a colorSpace defined, the the image data is 'interpreted'
88      * as being in that space, instead of that of the image's colorSpace.
89      *
90      * Here is how the input image is processed:
91      * a. It is converted to using a ComponentColorModel
92      * b. Its data is extracted, ignoring it's ColorSpace
93      * c. A new ComponentColorModel is built for the replacing colorSpace
94      * Note that if the number of components in the input image and
95      * the number of components in the replacing ColorSpace do not
96      * match, it is not possible to apply the conversion.
97      * d. A new BufferedImage is built, using the new
98      * ComponentColorModel and the data from the original image
99      * converted to the ComponentColorModel built in a. The alpha
100      * channel is excluded from that new BufferedImage.
101      * e. The BufferedImage created in d. is converted to sRGB using
102      * ColorConvertOp
103      * f. The alpha channel information is integrated back into the image.
104      *
105      * IMPORTANT NOTE: The code uses a BandedSampleModel in c.) and
106      * d.) and discard the alpha channel during the color conversions
107      * (it is restored in f.)), because of bugs in the interleaved
108      * model with alpha. The BandedSampleModel did not cause any bug
109      * as of JDK 1.3.
110      */

111     public WritableRaster JavaDoc copyData(WritableRaster JavaDoc argbWR){
112         try{
113             RenderedImage JavaDoc img = getSource();
114
115             /**
116              * Check that the number of color components match in the input
117              * image and in the replacing profile.
118              */

119             ColorModel JavaDoc imgCM = img.getColorModel();
120             ColorSpace JavaDoc imgCS = imgCM.getColorSpace();
121             int nImageComponents = imgCS.getNumComponents();
122             int nProfileComponents = colorSpace.getNumComponents();
123             if(nImageComponents != nProfileComponents){
124                 // Should we go in error???? Here we simply trace an error
125
// and return null
126
System.err.println("Input image and associated color profile have" +
127                                    " mismatching number of color components: conversion is not possible");
128                 return argbWR;
129             }
130
131             /**
132              * Get the data from the source for the requested region
133              */

134             int w = argbWR.getWidth();
135             int h = argbWR.getHeight();
136             int minX = argbWR.getMinX();
137             int minY = argbWR.getMinY();
138             WritableRaster JavaDoc srcWR =
139                 imgCM.createCompatibleWritableRaster(w, h);
140             srcWR = srcWR.createWritableTranslatedChild(minX, minY);
141             img.copyData(srcWR);
142
143             /**
144              * If the source data is not a ComponentColorModel using a
145              * BandedSampleModel, do the conversion now.
146              */

147             if(!(imgCM instanceof ComponentColorModel JavaDoc) ||
148                !(img.getSampleModel() instanceof BandedSampleModel JavaDoc) ||
149                (imgCM.hasAlpha() &&
150                 imgCM.isAlphaPremultiplied() == true)) {
151                 ComponentColorModel JavaDoc imgCompCM
152                     = new ComponentColorModel JavaDoc
153                         (imgCS, // Same ColorSpace as img
154
imgCM.getComponentSize(), // Number of bits/comp
155
imgCM.hasAlpha(), // Same alpha as img
156
false, // unpremult alpha (so we can remove it next).
157
imgCM.getTransparency(), // Same trans as img
158
DataBuffer.TYPE_BYTE); // 8 bit/component.
159

160                 WritableRaster JavaDoc wr = Raster.createBandedRaster
161                     (DataBuffer.TYPE_BYTE,
162                      argbWR.getWidth(), argbWR.getHeight(),
163                      imgCompCM.getNumComponents(),
164                      new Point JavaDoc(0, 0));
165
166                 BufferedImage JavaDoc imgComp = new BufferedImage JavaDoc
167                     (imgCompCM, wr, imgCompCM.isAlphaPremultiplied(), null);
168
169                 BufferedImage JavaDoc srcImg = new BufferedImage JavaDoc
170                     (imgCM, srcWR.createWritableTranslatedChild(0, 0),
171                      imgCM.isAlphaPremultiplied(), null);
172                 
173                 Graphics2D JavaDoc g = imgComp.createGraphics();
174                 g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
175                                    RenderingHints.VALUE_COLOR_RENDER_QUALITY);
176                 g.drawImage(srcImg, 0, 0, null);
177                 img = imgComp;
178                 imgCM = imgCompCM;
179                 srcWR = wr.createWritableTranslatedChild(minX, minY);
180             }
181
182             /**
183              * Now, the input image is using a component color
184              * model. We can therefore create an image with the new
185              * profile, using a ComponentColorModel as well, because
186              * we know the number of components match (this was
187              * checked at the begining of this routine). */

188             ComponentColorModel JavaDoc newCM = new ComponentColorModel JavaDoc
189                 (colorSpace, // **** New ColorSpace ****
190
imgCM.getComponentSize(), // Array of number of bits per components
191
false, // No alpa
192
false, // Not premultiplied
193
Transparency.OPAQUE, // No transparency
194
DataBuffer.TYPE_BYTE); // 8 Bits
195

196             // Build a raster with bands 0, 1 and 2 of img's raster
197
DataBufferByte JavaDoc data = (DataBufferByte JavaDoc)srcWR.getDataBuffer();
198             srcWR = Raster.createBandedRaster
199                 (data, argbWR.getWidth(), argbWR.getHeight(),
200                  argbWR.getWidth(), new int[]{0, 1, 2},
201                  new int[]{0, 0, 0}, new Point JavaDoc(0, 0));
202             BufferedImage JavaDoc newImg = new BufferedImage JavaDoc
203                 (newCM, srcWR, newCM.isAlphaPremultiplied(), null);
204
205             /**
206              * Now, convert the image to sRGB
207              */

208             ComponentColorModel JavaDoc sRGBCompCM = new ComponentColorModel JavaDoc
209                 (ColorSpace.getInstance(ColorSpace.CS_sRGB),
210                  new int[]{8, 8, 8},
211                  false,
212                  false,
213                  Transparency.OPAQUE,
214                  DataBuffer.TYPE_BYTE);
215
216             WritableRaster JavaDoc wr = Raster.createBandedRaster
217                 (DataBuffer.TYPE_BYTE, argbWR.getWidth(), argbWR.getHeight(),
218                  sRGBCompCM.getNumComponents(), new Point JavaDoc(0, 0));
219
220             BufferedImage JavaDoc sRGBImage = new BufferedImage JavaDoc
221                 (sRGBCompCM, wr, false, null);
222             ColorConvertOp JavaDoc colorConvertOp = new ColorConvertOp JavaDoc(null);
223             colorConvertOp.filter(newImg, sRGBImage);
224
225             /**
226              * Integrate alpha back into the image if there is any
227              */

228             if (imgCM.hasAlpha()){
229                 DataBufferByte JavaDoc rgbData = (DataBufferByte JavaDoc)wr.getDataBuffer();
230                 byte[][] imgBanks = data.getBankData();
231                 byte[][] rgbBanks = rgbData.getBankData();
232                 
233                 byte[][] argbBanks = {rgbBanks[0], rgbBanks[1],
234                                       rgbBanks[2], imgBanks[3]};
235                 DataBufferByte JavaDoc argbData = new DataBufferByte JavaDoc(argbBanks, imgBanks[0].length);
236                 srcWR = Raster.createBandedRaster
237                     (argbData, argbWR.getWidth(), argbWR.getHeight(),
238                      argbWR.getWidth(), new int[]{0, 1, 2, 3},
239                      new int[]{0, 0, 0, 0}, new Point JavaDoc(0, 0));
240                 sRGBCompCM = new ComponentColorModel JavaDoc
241                     (ColorSpace.getInstance(ColorSpace.CS_sRGB),
242                      new int[]{8, 8, 8, 8},
243                      true,
244                      false,
245                      Transparency.TRANSLUCENT,
246                      DataBuffer.TYPE_BYTE);
247                 sRGBImage = new BufferedImage JavaDoc(sRGBCompCM,
248                                               srcWR,
249                                               false,
250                                               null);
251                 
252             }
253
254             /*BufferedImage result = new BufferedImage(img.getWidth(),
255               img.getHeight(),
256               BufferedImage.TYPE_INT_ARGB);*/

257             BufferedImage JavaDoc result = new BufferedImage JavaDoc(sRGBCM,
258                                                      argbWR.createWritableTranslatedChild(0, 0),
259                                                      false,
260                                                      null);
261
262
263             ///////////////////////////////////////////////
264
// BUG IN ColorConvertOp: The following breaks:
265
// colorConvertOp.filter(sRGBImage, result);
266
//
267
// Using Graphics2D instead....
268
///////////////////////////////////////////////
269
Graphics2D JavaDoc g = result.createGraphics();
270             g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
271                                RenderingHints.VALUE_COLOR_RENDER_QUALITY);
272             g.drawImage(sRGBImage, 0, 0, null);
273             g.dispose();
274
275             return argbWR;
276         }catch(Exception JavaDoc e){
277             e.printStackTrace();
278             throw new Error JavaDoc();
279         }
280     }
281
282 }
283
Popular Tags