KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > image > MultiPixelPackedSampleModel


1 /*
2  * @(#)MultiPixelPackedSampleModel.java 1.36 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /* ****************************************************************
9  ******************************************************************
10  ******************************************************************
11  *** COPYRIGHT (c) Eastman Kodak Company, 1997
12  *** As an unpublished work pursuant to Title 17 of the United
13  *** States Code. All rights reserved.
14  ******************************************************************
15  ******************************************************************
16  ******************************************************************/

17
18 package java.awt.image;
19
20 /**
21  * The <code>MultiPixelPackedSampleModel</code> class represents
22  * one-banded images and can pack multiple one-sample
23  * pixels into one data element. Pixels are not allowed to span data elements.
24  * The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
25  * or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
26  * and a power of 2 number of pixels must fit exactly in one data element.
27  * Pixel bit stride is equal to the number of bits per pixel. Scanline
28  * stride is in data elements and the last several data elements might be
29  * padded with unused pixels. Data bit offset is the offset in bits from
30  * the beginning of the {@link DataBuffer} to the first pixel and must be
31  * a multiple of pixel bit stride.
32  * <p>
33  * The following code illustrates extracting the bits for pixel
34  * <code>x,&nbsp;y</code> from <code>DataBuffer</code> <code>data</code>
35  * and storing the pixel data in data elements of type
36  * <code>dataType</code>:
37  * <pre>
38  * int dataElementSize = DataBuffer.getDataTypeSize(dataType);
39  * int bitnum = dataBitOffset + x*pixelBitStride;
40  * int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
41  * int shift = dataElementSize - (bitnum & (dataElementSize-1))
42  * - pixelBitStride;
43  * int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
44  * </pre>
45  */

46
47 public class MultiPixelPackedSampleModel extends SampleModel JavaDoc
48 {
49     /** The number of bits from one pixel to the next. */
50     int pixelBitStride;
51
52     /** Bitmask that extracts the rightmost pixel of a data element. */
53     int bitMask;
54
55     /**
56       * The number of pixels that fit in a data element. Also used
57       * as the number of bits per pixel.
58       */

59     int pixelsPerDataElement;
60
61     /** The size of a data element in bits. */
62     int dataElementSize;
63
64     /** The bit offset into the data array where the first pixel begins.
65      */

66     int dataBitOffset;
67
68     /** ScanlineStride of the data buffer described in data array elements. */
69     int scanlineStride;
70
71     /**
72      * Constructs a <code>MultiPixelPackedSampleModel</code> with the
73      * specified data type, width, height and number of bits per pixel.
74      * @param dataType the data type for storing samples
75      * @param w the width, in pixels, of the region of
76      * image data described
77      * @param h the height, in pixels, of the region of
78      * image data described
79      * @param numberOfBits the number of bits per pixel
80      * @throws IllegalArgumentException if <code>dataType</code> is not
81      * either <code>DataBuffer.TYPE_BYTE</code>,
82      * <code>DataBuffer.TYPE_USHORT</code>, or
83      * <code>DataBuffer.TYPE_INT</code>
84      */

85     public MultiPixelPackedSampleModel(int dataType,
86                                        int w,
87                                        int h,
88                                        int numberOfBits) {
89         this(dataType,w,h,
90              numberOfBits,
91             (w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
92                 DataBuffer.getDataTypeSize(dataType),
93              0);
94         if (dataType != DataBuffer.TYPE_BYTE &&
95             dataType != DataBuffer.TYPE_USHORT &&
96             dataType != DataBuffer.TYPE_INT) {
97             throw new IllegalArgumentException JavaDoc("Unsupported data type "+
98                                                dataType);
99         }
100     }
101
102     /**
103      * Constructs a <code>MultiPixelPackedSampleModel</code> with
104      * specified data type, width, height, number of bits per pixel,
105      * scanline stride and data bit offset.
106      * @param dataType the data type for storing samples
107      * @param w the width, in pixels, of the region of
108      * image data described
109      * @param h the height, in pixels, of the region of
110      * image data described
111      * @param numberOfBits the number of bits per pixel
112      * @param scanlineStride the line stride of the image data
113      * @param dataBitOffset the data bit offset for the region of image
114      * data described
115      * @exception RasterFormatException if the number of bits per pixel
116      * is not a power of 2 or if a power of 2 number of
117      * pixels do not fit in one data element.
118      * @throws IllegalArgumentException if <code>w</code> or
119      * <code>h</code> is not greater than 0
120      * @throws IllegalArgumentException if <code>dataType</code> is not
121      * either <code>DataBuffer.TYPE_BYTE</code>,
122      * <code>DataBuffer.TYPE_USHORT</code>, or
123      * <code>DataBuffer.TYPE_INT</code>
124      */

125     public MultiPixelPackedSampleModel(int dataType, int w, int h,
126                                        int numberOfBits,
127                                        int scanlineStride,
128                                        int dataBitOffset) {
129         super(dataType, w, h, 1);
130         if (dataType != DataBuffer.TYPE_BYTE &&
131             dataType != DataBuffer.TYPE_USHORT &&
132             dataType != DataBuffer.TYPE_INT) {
133             throw new IllegalArgumentException JavaDoc("Unsupported data type "+
134                                                dataType);
135         }
136         this.dataType = dataType;
137         this.pixelBitStride = numberOfBits;
138         this.scanlineStride = scanlineStride;
139         this.dataBitOffset = dataBitOffset;
140         this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
141         this.pixelsPerDataElement = dataElementSize/numberOfBits;
142         if (pixelsPerDataElement*numberOfBits != dataElementSize) {
143            throw new RasterFormatException JavaDoc("MultiPixelPackedSampleModel " +
144                                              "does not allow pixels to " +
145                                              "span data element boundaries");
146         }
147         this.bitMask = (1 << numberOfBits) - 1;
148     }
149
150
151     /**
152      * Creates a new <code>MultiPixelPackedSampleModel</code> with the
153      * specified width and height. The new
154      * <code>MultiPixelPackedSampleModel</code> has the
155      * same storage data type and number of bits per pixel as this
156      * <code>MultiPixelPackedSampleModel</code>.
157      * @param w the specified width
158      * @param h the specified height
159      * @return a {@link SampleModel} with the specified width and height
160      * and with the same storage data type and number of bits per pixel
161      * as this <code>MultiPixelPackedSampleModel</code>.
162      * @throws IllegalArgumentException if <code>w</code> or
163      * <code>h</code> is not greater than 0
164      */

165     public SampleModel JavaDoc createCompatibleSampleModel(int w, int h) {
166       SampleModel JavaDoc sampleModel =
167             new MultiPixelPackedSampleModel JavaDoc(dataType, w, h, pixelBitStride);
168       return sampleModel;
169     }
170     
171     /**
172      * Creates a <code>DataBuffer</code> that corresponds to this
173      * <code>MultiPixelPackedSampleModel</code>. The
174      * <code>DataBuffer</code> object's data type and size
175      * is consistent with this <code>MultiPixelPackedSampleModel</code>.
176      * The <code>DataBuffer</code> has a single bank.
177      * @return a <code>DataBuffer</code> with the same data type and
178      * size as this <code>MultiPixelPackedSampleModel</code>.
179      */

180     public DataBuffer JavaDoc createDataBuffer() {
181     DataBuffer JavaDoc dataBuffer = null;
182
183     int size = (int)scanlineStride*height;
184     switch (dataType) {
185     case DataBuffer.TYPE_BYTE:
186         dataBuffer = new DataBufferByte JavaDoc(size+(dataBitOffset+7)/8);
187         break;
188     case DataBuffer.TYPE_USHORT:
189         dataBuffer = new DataBufferUShort JavaDoc(size+(dataBitOffset+15)/16);
190         break;
191     case DataBuffer.TYPE_INT:
192         dataBuffer = new DataBufferInt JavaDoc(size+(dataBitOffset+31)/32);
193         break;
194     }
195     return dataBuffer;
196     }
197
198     /**
199      * Returns the number of data elements needed to transfer one pixel
200      * via the {@link #getDataElements} and {@link #setDataElements}
201      * methods. For a <code>MultiPixelPackedSampleModel</code>, this is
202      * one.
203      * @return the number of data elements.
204      */

205     public int getNumDataElements() {
206     return 1;
207     }
208     
209     /**
210      * Returns the number of bits per sample for all bands.
211      * @return the number of bits per sample.
212      */

213     public int[] getSampleSize() {
214         int sampleSize[] = {pixelBitStride};
215     return sampleSize;
216     }
217
218     /**
219      * Returns the number of bits per sample for the specified band.
220      * @param band the specified band
221      * @return the number of bits per sample for the specified band.
222      */

223     public int getSampleSize(int band) {
224     return pixelBitStride;
225     }
226
227     /**
228      * Returns the offset of pixel (x,&nbsp;y) in data array elements.
229      * @param x,&nbsp;y the specified pixel
230      * @return the offset of the specified pixel.
231      */

232     public int getOffset(int x, int y) {
233     int offset = y * scanlineStride;
234         offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
235     return offset;
236     }
237
238     /**
239      * Returns the offset, in bits, into the data element in which it is
240      * stored for the <code>x</code>th pixel of a scanline.
241      * This offset is the same for all scanlines.
242      * @param x the specified pixel
243      * @return the bit offset of the specified pixel.
244      */

245     public int getBitOffset(int x){
246        return (x*pixelBitStride+dataBitOffset)%dataElementSize;
247     }
248
249     /**
250      * Returns the scanline stride.
251      * @return the scanline stride of this
252      * <code>MultiPixelPackedSampleModel</code>.
253      */

254     public int getScanlineStride() {
255         return scanlineStride;
256     }
257
258     /**
259      * Returns the pixel bit stride in bits. This value is the same as
260      * the number of bits per pixel.
261      * @return the <code>pixelBitStride</code> of this
262      * <code>MultiPixelPackedSampleModel</code>.
263      */

264     public int getPixelBitStride() {
265         return pixelBitStride;
266     }
267
268     /**
269      * Returns the data bit offset in bits.
270      * @return the <code>dataBitOffset</code> of this
271      * <code>MultiPixelPackedSampleModel</code>.
272      */

273     public int getDataBitOffset() {
274         return dataBitOffset;
275     }
276
277     /**
278      * Returns the TransferType used to transfer pixels by way of the
279      * <code>getDataElements</code> and <code>setDataElements</code>
280      * methods. The TransferType might or might not be the same as the
281      * storage DataType. The TransferType is one of
282      * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
283      * or DataBuffer.TYPE_INT.
284      * @return the transfertype.
285      */

286     public int getTransferType() {
287     if (pixelBitStride > 16)
288         return DataBuffer.TYPE_INT;
289     else if (pixelBitStride > 8)
290         return DataBuffer.TYPE_USHORT;
291     else
292         return DataBuffer.TYPE_BYTE;
293     }
294
295     /**
296      * Creates a new <code>MultiPixelPackedSampleModel</code> with a
297      * subset of the bands of this
298      * <code>MultiPixelPackedSampleModel</code>. Since a
299      * <code>MultiPixelPackedSampleModel</code> only has one band, the
300      * bands argument must have a length of one and indicate the zeroth
301      * band.
302      * @param bands the specified bands
303      * @return a new <code>SampleModel</code> with a subset of bands of
304      * this <code>MultiPixelPackedSampleModel</code>.
305      * @exception RasterFormatException if the number of bands requested
306      * is not one.
307      * @throws IllegalArgumentException if <code>w</code> or
308      * <code>h</code> is not greater than 0
309      */

310     public SampleModel JavaDoc createSubsetSampleModel(int bands[]) {
311         if (bands != null) {
312        if (bands.length != 1)
313         throw new RasterFormatException JavaDoc("MultiPixelPackedSampleModel has "
314                         + "only one band.");
315         }
316         SampleModel JavaDoc sm = createCompatibleSampleModel(width, height);
317         return sm;
318     }
319
320     /**
321      * Returns as <code>int</code> the sample in a specified band for the
322      * pixel located at (x,&nbsp;y). An
323      * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
324      * coordinates are not in bounds.
325      * @param x,&nbsp;y the coordinates of the specified pixel
326      * @param b the band to return, which is assumed to be 0
327      * @param data the <code>DataBuffer</code> containing the image
328      * data
329      * @return the specified band containing the sample of the specified
330      * pixel.
331      * @exception ArrayIndexOutOfBoundException if the specified
332      * coordinates are not in bounds.
333      * @see #setSample(int, int, int, int, DataBuffer)
334      */

335     public int getSample(int x, int y, int b, DataBuffer JavaDoc data) {
336         // 'b' must be 0
337
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
338             (b != 0)) {
339             throw new ArrayIndexOutOfBoundsException JavaDoc
340                 ("Coordinate out of bounds!");
341         }
342         int bitnum = dataBitOffset + x*pixelBitStride;
343         int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
344         int shift = dataElementSize - (bitnum & (dataElementSize-1))
345                     - pixelBitStride;
346         return (element >> shift) & bitMask;
347     }
348
349     /**
350      * Sets a sample in the specified band for the pixel located at
351      * (x,&nbsp;y) in the <code>DataBuffer</code> using an
352      * <code>int</code> for input.
353      * An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
354      * coordinates are not in bounds.
355      * @param x,&nbsp;y the coordinates of the specified pixel
356      * @param b the band to return, which is assumed to be 0
357      * @param s the input sample as an <code>int</code>
358      * @param data the <code>DataBuffer</code> where image data is stored
359      * @exception ArrayIndexOutOfBoundsException if the coordinates are
360      * not in bounds.
361      * @see #getSample(int, int, int, DataBuffer)
362      */

363     public void setSample(int x, int y, int b, int s,
364               DataBuffer JavaDoc data) {
365         // 'b' must be 0
366
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
367             (b != 0)) {
368             throw new ArrayIndexOutOfBoundsException JavaDoc
369                 ("Coordinate out of bounds!");
370         }
371         int bitnum = dataBitOffset + x * pixelBitStride;
372         int index = y * scanlineStride + (bitnum / dataElementSize);
373         int shift = dataElementSize - (bitnum & (dataElementSize-1))
374                     - pixelBitStride;
375         int element = data.getElem(index);
376         element &= ~(bitMask << shift);
377         element |= (s & bitMask) << shift;
378         data.setElem(index,element);
379     }
380
381     /**
382      * Returns data for a single pixel in a primitive array of type
383      * TransferType. For a <code>MultiPixelPackedSampleModel</code>,
384      * the array has one element, and the type is the smallest of
385      * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
386      * that can hold a single pixel. Generally, <code>obj</code>
387      * should be passed in as <code>null</code>, so that the
388      * <code>Object</code> is created automatically and is the
389      * correct primitive data type.
390      * <p>
391      * The following code illustrates transferring data for one pixel from
392      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
393      * described by <code>MultiPixelPackedSampleModel</code>
394      * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
395      * whose storage layout is described by
396      * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
397      * The transfer is generally more efficient than using
398      * <code>getPixel</code> or <code>setPixel</code>.
399      * <pre>
400      * MultiPixelPackedSampleModel mppsm1, mppsm2;
401      * DataBufferInt db1, db2;
402      * mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
403      * db1), db2);
404      * </pre>
405      * Using <code>getDataElements</code> or <code>setDataElements</code>
406      * to transfer between two <code>DataBuffer/SampleModel</code> pairs
407      * is legitimate if the <code>SampleModels</code> have the same number
408      * of bands, corresponding bands have the same number of
409      * bits per sample, and the TransferTypes are the same.
410      * <p>
411      * If <code>obj</code> is not <code>null</code>, it should be a
412      * primitive array of type TransferType. Otherwise, a
413      * <code>ClassCastException</code> is thrown. An
414      * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
415      * coordinates are not in bounds, or if <code>obj</code> is not
416      * <code>null</code> and is not large enough to hold the pixel data.
417      * @param x,&nbsp;y coordinates of the pixel location.
418      * @param obj a primitive array in which to return the pixel data or
419      * <code>null</code>.
420      * @param data the <code>DataBuffer</code> containing the image data.
421      * @return an <code>Object</code> containing data for the specified
422      * pixel.
423      * @exception ClassCastException if <code>obj</code> is not a
424      * primitive array of type TransferType or is not <code>null</code>
425      * @exception ArrayIndexOutOfBoundsException if the coordinates are
426      * not in bounds, or if <code>obj</code> is not <code>null</code> or
427      * not large enough to hold the pixel data
428      * @see #setDataElements(int, int, Object, DataBuffer)
429      */

430     public Object JavaDoc getDataElements(int x, int y, Object JavaDoc obj, DataBuffer JavaDoc data) {
431         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
432             throw new ArrayIndexOutOfBoundsException JavaDoc
433                 ("Coordinate out of bounds!");
434         }
435
436     int type = getTransferType();
437     int bitnum = dataBitOffset + x*pixelBitStride;
438     int shift = dataElementSize - (bitnum & (dataElementSize-1))
439                     - pixelBitStride;
440     int element = 0;
441
442     switch(type) {
443
444     case DataBuffer.TYPE_BYTE:
445
446         byte[] bdata;
447
448         if (obj == null)
449         bdata = new byte[1];
450         else
451         bdata = (byte[])obj;
452
453         element = data.getElem(y*scanlineStride +
454                     bitnum/dataElementSize);
455         bdata[0] = (byte)((element >> shift) & bitMask);
456
457         obj = (Object JavaDoc)bdata;
458         break;
459
460     case DataBuffer.TYPE_USHORT:
461
462         short[] sdata;
463
464         if (obj == null)
465         sdata = new short[1];
466         else
467         sdata = (short[])obj;
468
469         element = data.getElem(y*scanlineStride +
470                    bitnum/dataElementSize);
471         sdata[0] = (short)((element >> shift) & bitMask);
472
473         obj = (Object JavaDoc)sdata;
474         break;
475
476     case DataBuffer.TYPE_INT:
477
478         int[] idata;
479
480         if (obj == null)
481         idata = new int[1];
482         else
483         idata = (int[])obj;
484
485         element = data.getElem(y*scanlineStride +
486                    bitnum/dataElementSize);
487         idata[0] = (element >> shift) & bitMask;
488
489         obj = (Object JavaDoc)idata;
490         break;
491     }
492
493     return obj;
494     }
495
496     /**
497      * Returns the specified single band pixel in the first element
498      * of an <code>int</code> array.
499      * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
500      * coordinates are not in bounds.
501      * @param x,&nbsp;y the coordinates of the pixel location
502      * @param iArray the array containing the pixel to be returned or
503      * <code>null</code>
504      * @param data the <code>DataBuffer</code> where image data is stored
505      * @return an array containing the specified pixel.
506      * @exception ArrayIndexOutOfBoundsException if the coordinates
507      * are not in bounds
508      * @see #setPixel(int, int, int[], DataBuffer)
509      */

510     public int[] getPixel(int x, int y, int iArray[], DataBuffer JavaDoc data) {
511         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
512             throw new ArrayIndexOutOfBoundsException JavaDoc
513                 ("Coordinate out of bounds!");
514         }
515         int pixels[];
516         if (iArray != null) {
517            pixels = iArray;
518         } else {
519            pixels = new int [numBands];
520         }
521         int bitnum = dataBitOffset + x*pixelBitStride;
522         int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
523         int shift = dataElementSize - (bitnum & (dataElementSize-1))
524                     - pixelBitStride;
525         pixels[0] = (element >> shift) & bitMask;
526         return pixels;
527     }
528
529     /**
530      * Sets the data for a single pixel in the specified
531      * <code>DataBuffer</code> from a primitive array of type
532      * TransferType. For a <code>MultiPixelPackedSampleModel</code>,
533      * only the first element of the array holds valid data,
534      * and the type must be the smallest of
535      * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
536      * that can hold a single pixel.
537      * <p>
538      * The following code illustrates transferring data for one pixel from
539      * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
540      * described by <code>MultiPixelPackedSampleModel</code>
541      * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
542      * whose storage layout is described by
543      * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
544      * The transfer is generally more efficient than using
545      * <code>getPixel</code> or <code>setPixel</code>.
546      * <pre>
547      * MultiPixelPackedSampleModel mppsm1, mppsm2;
548      * DataBufferInt db1, db2;
549      * mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
550      * db1), db2);
551      * </pre>
552      * Using <code>getDataElements</code> or <code>setDataElements</code> to
553      * transfer between two <code>DataBuffer/SampleModel</code> pairs is
554      * legitimate if the <code>SampleModel</code> objects have
555      * the same number of bands, corresponding bands have the same number of
556      * bits per sample, and the TransferTypes are the same.
557      * <p>
558      * <code>obj</code> must be a primitive array of type TransferType.
559      * Otherwise, a <code>ClassCastException</code> is thrown. An
560      * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
561      * coordinates are not in bounds, or if <code>obj</code> is not large
562      * enough to hold the pixel data.
563      * @param x,&nbsp;y the coordinates of the pixel location
564      * @param obj a primitive array containing pixel data
565      * @param data the <code>DataBuffer</code> containing the image data
566      * @see #getDataElements(int, int, Object, DataBuffer)
567      */

568     public void setDataElements(int x, int y, Object JavaDoc obj, DataBuffer JavaDoc data) {
569         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
570             throw new ArrayIndexOutOfBoundsException JavaDoc
571                 ("Coordinate out of bounds!");
572         }
573
574     int type = getTransferType();
575     int bitnum = dataBitOffset + x * pixelBitStride;
576     int index = y * scanlineStride + (bitnum / dataElementSize);
577     int shift = dataElementSize - (bitnum & (dataElementSize-1))
578                     - pixelBitStride;
579         int element = data.getElem(index);
580     element &= ~(bitMask << shift);
581
582     switch(type) {
583
584     case DataBuffer.TYPE_BYTE:
585
586         byte[] barray = (byte[])obj;
587         element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
588         data.setElem(index, element);
589         break;
590
591     case DataBuffer.TYPE_USHORT:
592
593         short[] sarray = (short[])obj;
594         element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
595         data.setElem(index, element);
596         break;
597
598     case DataBuffer.TYPE_INT:
599
600         int[] iarray = (int[])obj;
601         element |= (iarray[0] & bitMask) << shift;
602         data.setElem(index, element);
603         break;
604     }
605     }
606
607     /**
608      * Sets a pixel in the <code>DataBuffer</code> using an
609      * <code>int</code> array for input.
610      * <code>ArrayIndexOutOfBoundsException</code> is thrown if
611      * the coordinates are not in bounds.
612      * @param x,&nbsp;y the coordinates of the pixel location
613      * @param iArray the input pixel in an <code>int</code> array
614      * @param data the <code>DataBuffer</code> containing the image data
615      * @see #getPixel(int, int, int[], DataBuffer)
616      */

617     public void setPixel(int x, int y, int[] iArray, DataBuffer JavaDoc data) {
618         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
619             throw new ArrayIndexOutOfBoundsException JavaDoc
620                 ("Coordinate out of bounds!");
621         }
622         int bitnum = dataBitOffset + x * pixelBitStride;
623         int index = y * scanlineStride + (bitnum / dataElementSize);
624         int shift = dataElementSize - (bitnum & (dataElementSize-1))
625                     - pixelBitStride;
626         int element = data.getElem(index);
627         element &= ~(bitMask << shift);
628         element |= (iArray[0] & bitMask) << shift;
629         data.setElem(index,element);
630     }
631
632     public boolean equals(Object JavaDoc o) {
633         if ((o == null) || !(o instanceof MultiPixelPackedSampleModel JavaDoc)) {
634             return false;
635         }
636
637         MultiPixelPackedSampleModel JavaDoc that = (MultiPixelPackedSampleModel JavaDoc)o;
638         return this.width == that.width &&
639             this.height == that.height &&
640             this.numBands == that.numBands &&
641             this.dataType == that.dataType &&
642             this.pixelBitStride == that.pixelBitStride &&
643             this.bitMask == that.bitMask &&
644             this.pixelsPerDataElement == that.pixelsPerDataElement &&
645             this.dataElementSize == that.dataElementSize &&
646             this.dataBitOffset == that.dataBitOffset &&
647             this.scanlineStride == that.scanlineStride;
648     }
649
650     // If we implement equals() we must also implement hashCode
651
public int hashCode() {
652         int hash = 0;
653         hash = width;
654         hash <<= 8;
655         hash ^= height;
656         hash <<= 8;
657         hash ^= numBands;
658         hash <<= 8;
659         hash ^= dataType;
660         hash <<= 8;
661         hash ^= pixelBitStride;
662         hash <<= 8;
663         hash ^= bitMask;
664         hash <<= 8;
665         hash ^= pixelsPerDataElement;
666         hash <<= 8;
667         hash ^= dataElementSize;
668         hash <<= 8;
669         hash ^= dataBitOffset;
670         hash <<= 8;
671         hash ^= scanlineStride;
672         return hash;
673     }
674 }
675
Popular Tags