1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46:
47: public class ComponentColorModel extends ColorModel
48: {
49:
50: private static int sum(int[] values)
51: {
52: int sum = 0;
53: for (int i=0; i<values.length; i++)
54: sum += values[i];
55: return sum;
56: }
57:
58:
59:
60: private static int[] findBits(ColorSpace colorSpace, int transferType,
61: boolean hasAlpha)
62: {
63: int[] bits;
64: if (hasAlpha)
65: bits = new int[colorSpace.getNumComponents()+1];
66: else
67: bits = new int[colorSpace.getNumComponents()];
68:
69: Arrays.fill(bits, DataBuffer.getDataTypeSize(transferType));
70:
71: return bits;
72: }
73:
74: public ComponentColorModel(ColorSpace colorSpace, int[] bits,
75: boolean hasAlpha,
76: boolean isAlphaPremultiplied,
77: int transparency, int transferType)
78: {
79: super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
80: transparency, transferType);
81: }
82:
83:
100: public ComponentColorModel(ColorSpace colorSpace,
101: boolean hasAlpha,
102: boolean isAlphaPremultiplied,
103: int transparency, int transferType)
104: {
105: this(colorSpace, findBits(colorSpace, transferType, hasAlpha), hasAlpha,
106: isAlphaPremultiplied, transparency, transferType);
107: }
108:
109: public int getRed(int pixel)
110: {
111: if (getNumComponents()>1) throw new IllegalArgumentException();
112: return (int) getRGBFloat(pixel)[0];
113: }
114:
115: public int getGreen(int pixel)
116: {
117: if (getNumComponents()>1) throw new IllegalArgumentException();
118: return (int) getRGBFloat(pixel)[0];
119: }
120:
121: public int getBlue(int pixel)
122: {
123: if (getNumComponents()>1) throw new IllegalArgumentException();
124: return (int) getRGBFloat(pixel)[0];
125: }
126:
127: public int getAlpha(int pixel)
128: {
129: if (getNumComponents()>1) throw new IllegalArgumentException();
130: int shift = 8 - getComponentSize(getNumColorComponents());
131: if (shift >= 0) return pixel << shift;
132: return pixel >> (-shift);
133: }
134:
135: public int getRGB(int pixel)
136: {
137: float[] rgb = getRGBFloat(pixel);
138: int ret = getRGB(rgb);
139: if (hasAlpha()) ret |= getAlpha(pixel) << 24;
140: return ret;
141: }
142:
143:
144:
146:
147: private float[] getRGBFloat(int pixel)
148: {
149: float[] data = { pixel };
150: return cspace.toRGB(data);
151: }
152:
153: private float[] getRGBFloat(Object inData)
154: {
155: DataBuffer buffer =
156: Buffers.createBufferFromData(transferType, inData,
157: getNumComponents());
158: int colors = getNumColorComponents();
159: float[] data = new float[colors];
160:
161:
162: for (int i=0; i<colors; i++)
163: {
164: float maxValue = (1<<getComponentSize(i))-1;
165: data[i] = buffer.getElemFloat(i)/maxValue;
166: }
167: float[] rgb = cspace.toRGB(data);
168: return rgb;
169: }
170:
171: public int getRed(Object inData)
172: {
173: return (int) getRGBFloat(inData)[0]*255;
174: }
175:
176: public int getGreen(Object inData)
177: {
178: return (int) getRGBFloat(inData)[1]*255;
179: }
180:
181: public int getBlue(Object inData)
182: {
183: return (int) getRGBFloat(inData)[2]*255;
184: }
185:
186: public int getAlpha(Object inData)
187: {
188: DataBuffer buffer =
189: Buffers.createBufferFromData(transferType, inData,
190: getNumComponents());
191: int shift = 8 - getComponentSize(getNumColorComponents());
192: int alpha = buffer.getElem(getNumColorComponents());
193: if (shift >= 0) return alpha << shift;
194: return alpha >> (-shift);
195: }
196:
197: private int getRGB(float[] rgb)
198: {
199:
203:
204:
206: int ret =
207: (((int) (rgb[0]*255F)) << 16) |
208: (((int) (rgb[1]*255F)) << 8) |
209: (((int) (rgb[2]*255F)) << 0);
210: return ret;
211: }
212:
213:
217: public int getRGB(Object inData)
218: {
219: float[] rgb = getRGBFloat(inData);
220: int ret = getRGB(rgb);
221: if (hasAlpha()) ret |= getAlpha(inData) << 24;
222: return ret;
223: }
224:
225: public Object getDataElements(int rgb, Object pixel)
226: {
227:
228: float[] rgbFloats = {
229: ((rgb >> 16)&0xff)/255.0F,
230: ((rgb >> 8)&0xff)/255.0F,
231: ((rgb >> 0)&0xff)/255.0F
232: };
233:
234:
235: float[] data = cspace.fromRGB(rgbFloats);
236: DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
237: getNumComponents());
238: int numColors = getNumColorComponents();
239:
240: if (hasAlpha())
241: {
242: float alpha = ((rgb >> 24)&0xff)/255.0F;
243:
244:
246: if (isAlphaPremultiplied()) {
247: for (int i=0; i<numColors; i++)
248: data[i] *= alpha;
249: }
250:
251: alpha *= (1<<(bits[numColors]-1));
252:
253: buffer.setElemFloat(numColors, alpha);
254: }
255: for (int i=0; i<numColors; i++)
256: {
257:
258: float value = data[i]*(1<<(bits[i]-1));
259:
260: buffer.setElemFloat(i, value);
261: }
262: return Buffers.getData(buffer);
263: }
264:
265: public int[] getComponents(int pixel, int[] components, int offset)
266: {
267: if (getNumComponents()>1) throw new IllegalArgumentException();
268: if (components == null)
269: components = new int[getNumComponents() + offset];
270: components[offset] = pixel;
271: return components;
272: }
273:
274: public int[] getComponents(Object pixel, int[] components, int offset)
275: {
276: DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
277: getNumComponents());
278: int numComponents = getNumComponents();
279:
280: if (components == null)
281: components = new int[numComponents + offset];
282:
283: for (int i=0; i<numComponents; i++)
284: components[offset++] = buffer.getElem(i);
285:
286: return components;
287: }
288:
289: public int getDataElement(int[] components, int offset)
290: {
291: if (getNumComponents()>1) throw new IllegalArgumentException();
292: return components[offset];
293: }
294:
295: public Object getDataElements(int[] components, int offset, Object obj)
296: {
297: DataBuffer buffer = Buffers.createBuffer(transferType, obj,
298: getNumComponents());
299: int numComponents = getNumComponents();
300:
301: for (int i=0; i<numComponents; i++)
302: buffer.setElem(i, components[offset++]);
303:
304: return Buffers.getData(buffer);
305: }
306:
307: public ColorModel coerceData(WritableRaster raster,
308: boolean isAlphaPremultiplied) {
309: if (this.isAlphaPremultiplied == isAlphaPremultiplied || !hasAlpha())
310: return this;
311:
312:
315: coerceDataWorker(raster, isAlphaPremultiplied);
316:
317: return new ComponentColorModel(cspace, hasAlpha, isAlphaPremultiplied,
318: transparency, transferType);
319: }
320:
321: public boolean isCompatibleRaster(Raster raster)
322: {
323: return super.isCompatibleRaster(raster);
324:
325: }
326:
327: public WritableRaster createCompatibleWritableRaster(int w, int h)
328: {
329: SampleModel sm = createCompatibleSampleModel(w, h);
330: Point origin = new Point(0, 0);
331: return Raster.createWritableRaster(sm, origin);
332: }
333:
334:
335:
342: public SampleModel createCompatibleSampleModel(int w, int h)
343: {
344: int pixelStride, scanlineStride;
345: int[] bandOffsets;
346:
347: pixelStride = getNumComponents();
348: scanlineStride = pixelStride * w;
349:
350:
356: bandOffsets = new int[pixelStride];
357: for (int i = 0; i < pixelStride; i++)
358: bandOffsets[i] = i;
359:
360:
366: switch (transferType)
367: {
368: case DataBuffer.TYPE_BYTE:
369: case DataBuffer.TYPE_USHORT:
370: return new PixelInterleavedSampleModel(transferType, w, h,
371: pixelStride,
372: scanlineStride,
373: bandOffsets);
374:
375: default:
376: return new ComponentSampleModel(transferType, w, h,
377: pixelStride,
378: scanlineStride,
379: bandOffsets);
380: }
381: }
382:
383:
384: public boolean isCompatibleSampleModel(SampleModel sm)
385: {
386: return
387: (sm instanceof ComponentSampleModel) &&
388: super.isCompatibleSampleModel(sm);
389: }
390:
391: public WritableRaster getAlphaRaster(WritableRaster raster)
392: {
393: if (!hasAlpha()) return null;
394:
395: SampleModel sm = raster.getSampleModel();
396: int[] alphaBand = { sm.getNumBands() - 1 };
397: SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
398: DataBuffer buffer = raster.getDataBuffer();
399: Point origin = new Point(0, 0);
400: return Raster.createWritableRaster(alphaModel, buffer, origin);
401: }
402:
403: public boolean equals(Object obj)
404: {
405: if (!(obj instanceof ComponentColorModel)) return false;
406: return super.equals(obj);
407: }
408: }