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.util.Arrays;
023:
024: import org.apache.harmony.awt.internal.nls.Messages;
025:
026: public class SinglePixelPackedSampleModel extends SampleModel {
027:
028: private int bitMasks[];
029:
030: private int bitOffsets[];
031:
032: private int bitSizes[];
033:
034: private int scanlineStride;
035:
036: private int maxBitSize;
037:
038: public SinglePixelPackedSampleModel(int dataType, int w, int h,
039: int bitMasks[]) {
040: this (dataType, w, h, w, bitMasks);
041: }
042:
043: public SinglePixelPackedSampleModel(int dataType, int w, int h,
044: int scanlineStride, int bitMasks[]) {
045:
046: super (dataType, w, h, bitMasks.length);
047:
048: if (dataType != DataBuffer.TYPE_BYTE
049: && dataType != DataBuffer.TYPE_USHORT
050: && dataType != DataBuffer.TYPE_INT) {
051: // awt.61=Unsupported data type: {0}
052: throw new IllegalArgumentException(Messages.getString(
053: "awt.61", //$NON-NLS-1$
054: dataType));
055: }
056:
057: this .scanlineStride = scanlineStride;
058: this .bitMasks = bitMasks.clone();
059: this .bitOffsets = new int[this .numBands];
060: this .bitSizes = new int[this .numBands];
061:
062: this .maxBitSize = 0;
063:
064: for (int i = 0; i < this .numBands; i++) {
065: int offset = 0;
066: int size = 0;
067: int mask = bitMasks[i];
068:
069: if (mask != 0) {
070: while ((mask & 1) == 0) {
071: mask >>>= 1;
072: offset++;
073: }
074:
075: while ((mask & 1) == 1) {
076: mask >>>= 1;
077: size++;
078: }
079:
080: if (mask != 0) {
081: // awt.62=Wrong mask : {0}
082: throw new IllegalArgumentException(Messages
083: .getString("awt.62", bitMasks[i])); //$NON-NLS-1$
084: }
085: }
086:
087: this .bitOffsets[i] = offset;
088: this .bitSizes[i] = size;
089:
090: if (this .maxBitSize < size) {
091: this .maxBitSize = size;
092: }
093:
094: }
095:
096: }
097:
098: @Override
099: public Object getDataElements(int x, int y, Object obj,
100: DataBuffer data) {
101: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
102: // awt.63=Coordinates are not in bounds
103: throw new ArrayIndexOutOfBoundsException(Messages
104: .getString("awt.63")); //$NON-NLS-1$
105: }
106: switch (getTransferType()) {
107: case DataBuffer.TYPE_BYTE:
108: byte bdata[];
109: if (obj == null) {
110: bdata = new byte[1];
111: } else {
112: bdata = (byte[]) obj;
113: }
114:
115: bdata[0] = (byte) data.getElem(y * scanlineStride + x);
116: obj = bdata;
117: break;
118: case DataBuffer.TYPE_USHORT:
119: short sdata[];
120: if (obj == null) {
121: sdata = new short[1];
122: } else {
123: sdata = (short[]) obj;
124: }
125:
126: sdata[0] = (short) data.getElem(y * scanlineStride + x);
127: obj = sdata;
128: break;
129: case DataBuffer.TYPE_INT:
130: int idata[];
131: if (obj == null) {
132: idata = new int[1];
133: } else {
134: idata = (int[]) obj;
135: }
136:
137: idata[0] = data.getElem(y * scanlineStride + x);
138: obj = idata;
139: break;
140: }
141: return obj;
142: }
143:
144: @Override
145: public void setDataElements(int x, int y, Object obj,
146: DataBuffer data) {
147: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
148: // awt.63=Coordinates are not in bounds
149: throw new ArrayIndexOutOfBoundsException(Messages
150: .getString("awt.63")); //$NON-NLS-1$
151: }
152: switch (getTransferType()) {
153: case DataBuffer.TYPE_BYTE:
154: data.setElem(y * scanlineStride + x,
155: ((byte[]) obj)[0] & 0xff);
156: break;
157: case DataBuffer.TYPE_USHORT:
158: data.setElem(y * scanlineStride + x,
159: ((short[]) obj)[0] & 0xffff);
160: break;
161: case DataBuffer.TYPE_INT:
162: data.setElem(y * scanlineStride + x, ((int[]) obj)[0]);
163: break;
164: }
165: }
166:
167: @Override
168: public boolean equals(Object o) {
169: if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
170: return false;
171: }
172:
173: SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel) o;
174: return this .width == model.width && this .height == model.height
175: && this .numBands == model.numBands
176: && this .dataType == model.dataType
177: && Arrays.equals(this .bitMasks, model.bitMasks)
178: && Arrays.equals(this .bitOffsets, model.bitOffsets)
179: && Arrays.equals(this .bitSizes, model.bitSizes)
180: && this .scanlineStride == model.scanlineStride;
181: }
182:
183: @Override
184: public SampleModel createSubsetSampleModel(int bands[]) {
185: if (bands.length > this .numBands) {
186: // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
187: throw new RasterFormatException(Messages
188: .getString("awt.64")); //$NON-NLS-1$
189: }
190:
191: int masks[] = new int[bands.length];
192: for (int i = 0; i < bands.length; i++) {
193: masks[i] = this .bitMasks[bands[i]];
194: }
195: return new SinglePixelPackedSampleModel(this .dataType,
196: this .width, this .height, this .scanlineStride, masks);
197: }
198:
199: @Override
200: public SampleModel createCompatibleSampleModel(int w, int h) {
201: return new SinglePixelPackedSampleModel(this .dataType, w, h,
202: this .bitMasks);
203: }
204:
205: @Override
206: public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
207: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
208: // awt.63=Coordinates are not in bounds
209: throw new ArrayIndexOutOfBoundsException(Messages
210: .getString("awt.63")); //$NON-NLS-1$
211: }
212: int pixel[];
213: if (iArray == null) {
214: pixel = new int[this .numBands];
215: } else {
216: pixel = iArray;
217: }
218:
219: for (int i = 0; i < this .numBands; i++) {
220: pixel[i] = getSample(x, y, i, data);
221: }
222:
223: return pixel;
224: }
225:
226: @Override
227: public void setPixel(int x, int y, int iArray[], DataBuffer data) {
228: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
229: // awt.63=Coordinates are not in bounds
230: throw new ArrayIndexOutOfBoundsException(Messages
231: .getString("awt.63")); //$NON-NLS-1$
232: }
233: for (int i = 0; i < this .numBands; i++) {
234: setSample(x, y, i, iArray[i], data);
235: }
236: }
237:
238: @Override
239: public int getSample(int x, int y, int b, DataBuffer data) {
240: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
241: // awt.63=Coordinates are not in bounds
242: throw new ArrayIndexOutOfBoundsException(Messages
243: .getString("awt.63")); //$NON-NLS-1$
244: }
245: int sample = data.getElem(y * scanlineStride + x);
246: return ((sample & this .bitMasks[b]) >>> this .bitOffsets[b]);
247: }
248:
249: @Override
250: public int[] getPixels(int x, int y, int w, int h, int iArray[],
251: DataBuffer data) {
252: if ((x < 0) || (y < 0) || ((long) x + (long) w > this .width)
253: || ((long) y + (long) h > this .height)) {
254: // awt.63=Coordinates are not in bounds
255: throw new ArrayIndexOutOfBoundsException(Messages
256: .getString("awt.63")); //$NON-NLS-1$
257: }
258:
259: int pixels[];
260:
261: if (iArray == null) {
262: pixels = new int[w * h * this .numBands];
263: } else {
264: pixels = iArray;
265: }
266:
267: int idx = 0;
268:
269: for (int i = y; i < y + h; i++) {
270: for (int j = x; j < x + w; j++) {
271: for (int n = 0; n < this .numBands; n++) {
272: pixels[idx++] = getSample(j, i, n, data);
273: }
274: }
275: }
276: return pixels;
277: }
278:
279: @Override
280: public void setPixels(int x, int y, int w, int h, int iArray[],
281: DataBuffer data) {
282: if ((x < 0) || (y < 0) || ((long) x + (long) w > this .width)
283: || ((long) y + (long) h > this .height)) {
284: // awt.63=Coordinates are not in bounds
285: throw new ArrayIndexOutOfBoundsException(Messages
286: .getString("awt.63")); //$NON-NLS-1$
287: }
288:
289: int idx = 0;
290:
291: for (int i = y; i < y + h; i++) {
292: for (int j = x; j < x + w; j++) {
293: for (int n = 0; n < this .numBands; n++) {
294: setSample(j, i, n, iArray[idx++], data);
295: }
296: }
297: }
298: }
299:
300: @Override
301: public void setSample(int x, int y, int b, int s, DataBuffer data) {
302: if (x < 0 || y < 0 || x >= this .width || y >= this .height) {
303: // awt.63=Coordinates are not in bounds
304: throw new ArrayIndexOutOfBoundsException(Messages
305: .getString("awt.63")); //$NON-NLS-1$
306: }
307: int tmp = data.getElem(y * scanlineStride + x);
308: tmp &= ~this .bitMasks[b];
309: tmp |= (s << this .bitOffsets[b]) & this .bitMasks[b];
310: data.setElem(y * scanlineStride + x, tmp);
311: }
312:
313: @Override
314: public int[] getSamples(int x, int y, int w, int h, int b,
315: int iArray[], DataBuffer data) {
316: if ((x < 0) || (y < 0) || ((long) x + (long) w > this .width)
317: || ((long) y + (long) h > this .height)) {
318: // awt.63=Coordinates are not in bounds
319: throw new ArrayIndexOutOfBoundsException(Messages
320: .getString("awt.63")); //$NON-NLS-1$
321: }
322:
323: int samples[];
324: int idx = 0;
325:
326: if (iArray == null) {
327: samples = new int[w * h];
328: } else {
329: samples = iArray;
330: }
331:
332: for (int i = y; i < y + h; i++) {
333: for (int j = x; j < x + w; j++) {
334: samples[idx++] = getSample(j, i, b, data);
335: }
336: }
337:
338: return samples;
339: }
340:
341: @Override
342: public void setSamples(int x, int y, int w, int h, int b,
343: int iArray[], DataBuffer data) {
344: if ((x < 0) || (y < 0) || ((long) x + (long) w > this .width)
345: || ((long) y + (long) h > this .height)) {
346: // awt.63=Coordinates are not in bounds
347: throw new ArrayIndexOutOfBoundsException(Messages
348: .getString("awt.63")); //$NON-NLS-1$
349: }
350:
351: int idx = 0;
352: for (int i = y; i < y + h; i++) {
353: for (int j = x; j < x + w; j++) {
354: setSample(x + j, y + i, b, iArray[idx++], data);
355: }
356: }
357: }
358:
359: @Override
360: public DataBuffer createDataBuffer() {
361: DataBuffer data = null;
362: int size = (this .height - 1) * scanlineStride + width;
363:
364: switch (this .dataType) {
365: case DataBuffer.TYPE_BYTE:
366: data = new DataBufferByte(size);
367: break;
368: case DataBuffer.TYPE_USHORT:
369: data = new DataBufferUShort(size);
370: break;
371: case DataBuffer.TYPE_INT:
372: data = new DataBufferInt(size);
373: break;
374: }
375: return data;
376: }
377:
378: public int getOffset(int x, int y) {
379: return (y * scanlineStride + x);
380: }
381:
382: @Override
383: public int getSampleSize(int band) {
384: return bitSizes[band];
385: }
386:
387: @Override
388: public int[] getSampleSize() {
389: return bitSizes.clone();
390: }
391:
392: public int[] getBitOffsets() {
393: return bitOffsets.clone();
394: }
395:
396: public int[] getBitMasks() {
397: return bitMasks.clone();
398: }
399:
400: @Override
401: public int hashCode() {
402: int hash = 0;
403: int tmp = 0;
404:
405: hash = width;
406: tmp = hash >>> 24;
407: hash <<= 8;
408: hash |= tmp;
409: hash ^= height;
410: tmp = hash >>> 24;
411: hash <<= 8;
412: hash |= tmp;
413: hash ^= numBands;
414: tmp = hash >>> 24;
415: hash <<= 8;
416: hash |= tmp;
417: hash ^= dataType;
418: tmp = hash >>> 24;
419: hash <<= 8;
420: hash |= tmp;
421: for (int element : bitMasks) {
422: hash ^= element;
423: tmp = hash >>> 24;
424: hash <<= 8;
425: hash |= tmp;
426: }
427: for (int element : bitOffsets) {
428: hash ^= element;
429: tmp = hash >>> 24;
430: hash <<= 8;
431: hash |= tmp;
432: }
433: for (int element : bitSizes) {
434: hash ^= element;
435: tmp = hash >>> 24;
436: hash <<= 8;
437: hash |= tmp;
438: }
439: hash ^= scanlineStride;
440: return hash;
441: }
442:
443: public int getScanlineStride() {
444: return this .scanlineStride;
445: }
446:
447: @Override
448: public int getNumDataElements() {
449: return 1;
450: }
451:
452: }
|