001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Igor V. Stolyarov
019: * @version $Revision$
020: */package java.awt.image;
021:
022: import java.awt.Transparency;
023: import java.awt.color.ColorSpace;
024: import java.util.Arrays;
025:
026: import org.apache.harmony.awt.internal.nls.Messages;
027:
028: public abstract class PackedColorModel extends ColorModel {
029:
030: int componentMasks[];
031:
032: int offsets[];
033:
034: float scales[];
035:
036: public PackedColorModel(ColorSpace space, int bits,
037: int colorMaskArray[], int alphaMask,
038: boolean isAlphaPremultiplied, int trans, int transferType) {
039:
040: super (bits, createBits(colorMaskArray, alphaMask), space,
041: (alphaMask == 0 ? false : true), isAlphaPremultiplied,
042: trans, validateTransferType(transferType));
043:
044: if (pixel_bits < 1 || pixel_bits > 32) {
045: // awt.236=The bits is less than 1 or greater than 32
046: throw new IllegalArgumentException(Messages
047: .getString("awt.236")); //$NON-NLS-1$
048: }
049:
050: componentMasks = new int[numComponents];
051: for (int i = 0; i < numColorComponents; i++) {
052: componentMasks[i] = colorMaskArray[i];
053: }
054:
055: if (hasAlpha) {
056: componentMasks[numColorComponents] = alphaMask;
057: if (this .bits[numColorComponents] == 1) {
058: transparency = Transparency.BITMASK;
059: }
060: }
061:
062: parseComponents();
063: }
064:
065: public PackedColorModel(ColorSpace space, int bits, int rmask,
066: int gmask, int bmask, int amask,
067: boolean isAlphaPremultiplied, int trans, int transferType) {
068:
069: super (bits, createBits(rmask, gmask, bmask, amask), space,
070: (amask == 0 ? false : true), isAlphaPremultiplied,
071: trans, validateTransferType(transferType));
072:
073: if (pixel_bits < 1 || pixel_bits > 32) {
074: // awt.236=The bits is less than 1 or greater than 32
075: throw new IllegalArgumentException(Messages
076: .getString("awt.236")); //$NON-NLS-1$
077: }
078:
079: if (cs.getType() != ColorSpace.TYPE_RGB) {
080: // awt.239=The space is not a TYPE_RGB space
081: throw new IllegalArgumentException(Messages
082: .getString("awt.239")); //$NON-NLS-1$
083: }
084:
085: for (int i = 0; i < numColorComponents; i++) {
086: if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
087: // awt.23A=The min/max normalized component values are not 0.0/1.0
088: throw new IllegalArgumentException(Messages
089: .getString("awt.23A")); //$NON-NLS-1$
090: }
091: }
092: componentMasks = new int[numComponents];
093: componentMasks[0] = rmask;
094: componentMasks[1] = gmask;
095: componentMasks[2] = bmask;
096:
097: if (hasAlpha) {
098: componentMasks[3] = amask;
099: if (this .bits[3] == 1) {
100: transparency = Transparency.BITMASK;
101: }
102: }
103:
104: parseComponents();
105: }
106:
107: @Override
108: public WritableRaster getAlphaRaster(WritableRaster raster) {
109: if (!hasAlpha) {
110: return null;
111: }
112:
113: int x = raster.getMinX();
114: int y = raster.getMinY();
115: int w = raster.getWidth();
116: int h = raster.getHeight();
117: int band[] = new int[1];
118: band[0] = raster.getNumBands() - 1;
119: return raster.createWritableChild(x, y, w, h, x, y, band);
120: }
121:
122: @Override
123: public boolean equals(Object obj) {
124: if (obj == null) {
125: return false;
126: }
127: if (!(obj instanceof PackedColorModel)) {
128: return false;
129: }
130: PackedColorModel cm = (PackedColorModel) obj;
131:
132: return (pixel_bits == cm.getPixelSize()
133: && transferType == cm.getTransferType()
134: && cs.getType() == cm.getColorSpace().getType()
135: && hasAlpha == cm.hasAlpha()
136: && isAlphaPremultiplied == cm.isAlphaPremultiplied()
137: && transparency == cm.getTransparency()
138: && numColorComponents == cm.getNumColorComponents()
139: && numComponents == cm.getNumComponents()
140: && Arrays.equals(bits, cm.getComponentSize()) && Arrays
141: .equals(componentMasks, cm.getMasks()));
142: }
143:
144: @Override
145: public boolean isCompatibleSampleModel(SampleModel sm) {
146: if (sm == null) {
147: return false;
148: }
149: if (!(sm instanceof SinglePixelPackedSampleModel)) {
150: return false;
151: }
152: SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel) sm;
153:
154: return ((esm.getNumBands() == numComponents)
155: && (esm.getTransferType() == transferType) && Arrays
156: .equals(esm.getBitMasks(), componentMasks));
157: }
158:
159: @Override
160: public SampleModel createCompatibleSampleModel(int w, int h) {
161: return new SinglePixelPackedSampleModel(transferType, w, h,
162: componentMasks);
163: }
164:
165: public final int getMask(int index) {
166: return componentMasks[index];
167: }
168:
169: public final int[] getMasks() {
170: return (componentMasks.clone());
171: }
172:
173: private static int[] createBits(int colorMaskArray[], int alphaMask) {
174: int bits[];
175: int numComp;
176: if (alphaMask == 0) {
177: numComp = colorMaskArray.length;
178: } else {
179: numComp = colorMaskArray.length + 1;
180: }
181:
182: bits = new int[numComp];
183: int i = 0;
184: for (; i < colorMaskArray.length; i++) {
185: bits[i] = countCompBits(colorMaskArray[i]);
186: if (bits[i] < 0) {
187: // awt.23B=The mask of the {0} component is not contiguous
188: throw new IllegalArgumentException(Messages.getString(
189: "awt.23B", i)); //$NON-NLS-1$
190: }
191: }
192:
193: if (i < numComp) {
194: bits[i] = countCompBits(alphaMask);
195:
196: if (bits[i] < 0) {
197: // awt.23C=The mask of the alpha component is not contiguous
198: throw new IllegalArgumentException(Messages
199: .getString("awt.23C")); //$NON-NLS-1$
200: }
201: }
202:
203: return bits;
204: }
205:
206: private static int[] createBits(int rmask, int gmask, int bmask,
207: int amask) {
208:
209: int numComp;
210: if (amask == 0) {
211: numComp = 3;
212: } else {
213: numComp = 4;
214: }
215: int bits[] = new int[numComp];
216:
217: bits[0] = countCompBits(rmask);
218: if (bits[0] < 0) {
219: // awt.23D=The mask of the red component is not contiguous
220: throw new IllegalArgumentException(Messages
221: .getString("awt.23D")); //$NON-NLS-1$
222: }
223:
224: bits[1] = countCompBits(gmask);
225: if (bits[1] < 0) {
226: // awt.23E=The mask of the green component is not contiguous
227: throw new IllegalArgumentException(Messages
228: .getString("awt.23E")); //$NON-NLS-1$
229: }
230:
231: bits[2] = countCompBits(bmask);
232: if (bits[2] < 0) {
233: // awt.23F=The mask of the blue component is not contiguous
234: throw new IllegalArgumentException(Messages
235: .getString("awt.23F")); //$NON-NLS-1$
236: }
237:
238: if (amask != 0) {
239: bits[3] = countCompBits(amask);
240: if (bits[3] < 0) {
241: // awt.23C=The mask of the alpha component is not contiguous
242: throw new IllegalArgumentException(Messages
243: .getString("awt.23C")); //$NON-NLS-1$
244: }
245: }
246:
247: return bits;
248: }
249:
250: private static int countCompBits(int compMask) {
251: int bits = 0;
252: if (compMask != 0) {
253: // Deleting final zeros
254: while ((compMask & 1) == 0) {
255: compMask >>>= 1;
256: }
257: // Counting component bits
258: while ((compMask & 1) == 1) {
259: compMask >>>= 1;
260: bits++;
261: }
262: }
263:
264: if (compMask != 0) {
265: return -1;
266: }
267:
268: return bits;
269: }
270:
271: private static int validateTransferType(int transferType) {
272: if (transferType != DataBuffer.TYPE_BYTE
273: && transferType != DataBuffer.TYPE_USHORT
274: && transferType != DataBuffer.TYPE_INT) {
275: // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
276: // DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
277: throw new IllegalArgumentException(Messages
278: .getString("awt.240")); //$NON-NLS-1$
279: }
280: return transferType;
281: }
282:
283: private void parseComponents() {
284: offsets = new int[numComponents];
285: scales = new float[numComponents];
286: for (int i = 0; i < numComponents; i++) {
287: int off = 0;
288: int mask = componentMasks[i];
289: while ((mask & 1) == 0) {
290: mask >>>= 1;
291: off++;
292: }
293: offsets[i] = off;
294: if (bits[i] == 0) {
295: scales[i] = 256.0f; // May be any value different from zero,
296: // because will dividing by zero
297: } else {
298: scales[i] = 255.0f / maxValues[i];
299: }
300: }
301:
302: }
303:
304: }
|