KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)SinglePixelPackedSampleModel.java 1.42 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 import java.util.Arrays JavaDoc;
21
22 /**
23  * This class represents pixel data packed such that the N samples which make
24  * up a single pixel are stored in a single data array element, and each data
25  * data array element holds samples for only one pixel.
26  * This class supports
27  * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
28  * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
29  * {@link DataBuffer#TYPE_INT TYPE_INT} data types.
30  * All data array elements reside
31  * in the first bank of a DataBuffer. Accessor methods are provided so
32  * that the image data can be manipulated directly. Scanline stride is the
33  * number of data array elements between a given sample and the corresponding
34  * sample in the same column of the next scanline. Bit masks are the masks
35  * required to extract the samples representing the bands of the pixel.
36  * Bit offsets are the offsets in bits into the data array
37  * element of the samples representing the bands of the pixel.
38  * <p>
39  * The following code illustrates extracting the bits of the sample
40  * representing band <code>b</code> for pixel <code>x,y</code>
41  * from DataBuffer <code>data</code>:
42  * <pre>
43  * int sample = data.getElem(y * scanlineStride + x);
44  * sample = (sample & bitMasks[b]) >>> bitOffsets[b];
45  * </pre>
46  */

47
48 public class SinglePixelPackedSampleModel extends SampleModel JavaDoc
49 {
50     /** Bit masks for all bands of the image data. */
51     private int bitMasks[];
52
53     /** Bit Offsets for all bands of the image data. */
54     private int bitOffsets[];
55
56     /** Bit sizes for all the bands of the image data. */
57     private int bitSizes[];
58
59     /** Maximum bit size. */
60     private int maxBitSize;
61
62     /** Line stride of the region of image data described by this
63      * SinglePixelPackedSampleModel.
64      */

65     private int scanlineStride;
66
67     private static native void initIDs();
68     static {
69         ColorModel.loadLibraries();
70         initIDs();
71     }
72
73     /**
74      * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
75      * Each sample is stored in a data array element in the position of
76      * its corresponding bit mask. Each bit mask must be contiguous and
77      * masks must not overlap.
78      * @param dataType The data type for storing samples.
79      * @param w The width (in pixels) of the region of the
80      * image data described.
81      * @param h The height (in pixels) of the region of the
82      * image data described.
83      * @param bitMasks The bit masks for all bands.
84      * @throws IllegalArgumentException if <code>dataType</code> is not
85      * either <code>DataBuffer.TYPE_BYTE</code>,
86      * <code>DataBuffer.TYPE_USHORT</code>, or
87      * <code>DataBuffer.TYPE_INT</code>
88      */

89     public SinglePixelPackedSampleModel(int dataType, int w, int h,
90                    int bitMasks[]) {
91         this(dataType, w, h, w, bitMasks);
92         if (dataType != DataBuffer.TYPE_BYTE &&
93             dataType != DataBuffer.TYPE_USHORT &&
94             dataType != DataBuffer.TYPE_INT) {
95             throw new IllegalArgumentException JavaDoc("Unsupported data type "+
96                                                dataType);
97         }
98     }
99
100     /**
101      * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
102      * and a scanline stride equal to scanlineStride data array elements.
103      * Each sample is stored in a data array element in the position of
104      * its corresponding bit mask. Each bit mask must be contiguous and
105      * masks must not overlap.
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 scanlineStride The line stride of the image data.
112      * @param bitMasks The bit masks for all bands.
113      * @throws IllegalArgumentException if <code>w</code> or
114      * <code>h</code> is not greater than 0
115      * @throws IllegalArgumentException if any mask in
116      * <code>bitMask</code> is not contiguous
117      * @throws IllegalArgumentException if <code>dataType</code> is not
118      * either <code>DataBuffer.TYPE_BYTE</code>,
119      * <code>DataBuffer.TYPE_USHORT</code>, or
120      * <code>DataBuffer.TYPE_INT</code>
121      */

122     public SinglePixelPackedSampleModel(int dataType, int w, int h,
123                                    int scanlineStride, int bitMasks[]) {
124         super(dataType, w, h, bitMasks.length);
125         if (dataType != DataBuffer.TYPE_BYTE &&
126             dataType != DataBuffer.TYPE_USHORT &&
127             dataType != DataBuffer.TYPE_INT) {
128             throw new IllegalArgumentException JavaDoc("Unsupported data type "+
129                                                dataType);
130         }
131         this.dataType = dataType;
132         this.bitMasks = (int[]) bitMasks.clone();
133         this.scanlineStride = scanlineStride;
134
135         this.bitOffsets = new int[numBands];
136         this.bitSizes = new int[numBands];
137
138         this.maxBitSize = 0;
139         for (int i=0; i<numBands; i++) {
140             int bitOffset = 0, bitSize = 0, mask;
141             mask = bitMasks[i];
142
143             if (mask != 0) {
144                 while ((mask & 1) == 0) {
145                     mask = mask >>> 1;
146                     bitOffset++;
147                 }
148                 while ((mask & 1) == 1) {
149                     mask = mask >>> 1;
150                     bitSize++;
151                 }
152                 if (mask != 0) {
153                     throw new IllegalArgumentException JavaDoc("Mask "+bitMasks[i]+
154                                                        " must be contiguous");
155                 }
156             }
157             bitOffsets[i] = bitOffset;
158             bitSizes[i] = bitSize;
159             if (bitSize > maxBitSize) {
160                 maxBitSize = bitSize;
161             }
162         }
163     }
164
165     /**
166      * Returns the number of data elements needed to transfer one pixel
167      * via the getDataElements and setDataElements methods.
168      * For a SinglePixelPackedSampleModel, this is one.
169      */

170     public int getNumDataElements() {
171     return 1;
172     }
173
174     /**
175      * Returns the size of the buffer (in data array elements)
176      * needed for a data buffer that matches this
177      * SinglePixelPackedSampleModel.
178      */

179     private long getBufferSize() {
180       long size = scanlineStride * (height-1) + width;
181       return size;
182     }
183
184     /**
185      * Creates a new SinglePixelPackedSampleModel with the specified
186      * width and height. The new SinglePixelPackedSampleModel will have the
187      * same storage data type and bit masks as this
188      * SinglePixelPackedSampleModel.
189      * @param w the width of the resulting <code>SampleModel</code>
190      * @param h the height of the resulting <code>SampleModel</code>
191      * @return a <code>SinglePixelPackedSampleModel</code> with the
192      * specified width and height.
193      * @throws IllegalArgumentException if <code>w</code> or
194      * <code>h</code> is not greater than 0
195      */

196     public SampleModel JavaDoc createCompatibleSampleModel(int w, int h) {
197       SampleModel JavaDoc sampleModel = new SinglePixelPackedSampleModel JavaDoc(dataType, w, h,
198                                   bitMasks);
199       return sampleModel;
200     }
201     
202     /**
203      * Creates a DataBuffer that corresponds to this
204      * SinglePixelPackedSampleModel. The DataBuffer's data type and size
205      * will be consistent with this SinglePixelPackedSampleModel. The
206      * DataBuffer will have a single bank.
207      */

208     public DataBuffer JavaDoc createDataBuffer() {
209     DataBuffer JavaDoc dataBuffer = null;
210
211     int size = (int)getBufferSize();
212     switch (dataType) {
213     case DataBuffer.TYPE_BYTE:
214         dataBuffer = new DataBufferByte JavaDoc(size);
215         break;
216     case DataBuffer.TYPE_USHORT:
217         dataBuffer = new DataBufferUShort JavaDoc(size);
218         break;
219     case DataBuffer.TYPE_INT:
220         dataBuffer = new DataBufferInt JavaDoc(size);
221         break;
222     }
223     return dataBuffer;
224     }
225
226     /** Returns the number of bits per sample for all bands. */
227     public int[] getSampleSize() {
228     int mask;
229     int sampleSize[] = new int [numBands];
230     for (int i=0; i<numBands; i++) {
231         sampleSize[i] = 0;
232         mask = bitMasks[i] >>> bitOffsets[i];
233         while ((mask & 1) != 0) {
234         sampleSize[i] ++;
235         mask = mask >>> 1;
236         }
237     }
238
239     return sampleSize;
240     }
241
242     /** Returns the number of bits per sample for the specified band. */
243     public int getSampleSize(int band) {
244     int sampleSize = 0;
245     int mask = bitMasks[band] >>> bitOffsets[band];
246     while ((mask & 1) != 0) {
247         sampleSize ++;
248         mask = mask >>> 1;
249     }
250
251     return sampleSize;
252     }
253
254     /** Returns the offset (in data array elements) of pixel (x,y).
255      * The data element containing pixel <code>x,y</code>
256      * can be retrieved from a DataBuffer <code>data</code> with a
257      * SinglePixelPackedSampleModel <code>sppsm</code> as:
258      * <pre>
259      * data.getElem(sppsm.getOffset(x, y));
260      * </pre>
261      * @param x,&nbsp;y the coordinates of the specified pixel
262      * @return the offset of the specified pixel.
263      */

264     public int getOffset(int x, int y) {
265     int offset = y * scanlineStride + x;
266     return offset;
267     }
268
269     /** Returns the bit offsets into the data array element representing
270      * a pixel for all bands.
271      * @return the bit offsets representing a pixel for all bands.
272      */

273     public int [] getBitOffsets() {
274       return (int[])bitOffsets.clone();
275     }
276
277     /** Returns the bit masks for all bands.
278      * @return the bit masks for all bands.
279      */

280     public int [] getBitMasks() {
281       return (int[])bitMasks.clone();
282     }
283
284     /** Returns the scanline stride of this SinglePixelPackedSampleModel.
285      * @return the scanline stride of this
286      * <code>SinglePixelPackedSampleModel</code>.
287      */

288     public int getScanlineStride() {
289       return scanlineStride;
290     }
291
292     /**
293      * This creates a new SinglePixelPackedSampleModel with a subset of the
294      * bands of this SinglePixelPackedSampleModel. The new
295      * SinglePixelPackedSampleModel can be used with any DataBuffer that the
296      * existing SinglePixelPackedSampleModel can be used with. The new
297      * SinglePixelPackedSampleModel/DataBuffer combination will represent
298      * an image with a subset of the bands of the original
299      * SinglePixelPackedSampleModel/DataBuffer combination.
300      * @exception RasterFormatException if the length of the bands argument is
301      * greater than the number of bands in
302      * the sample model.
303      */

304     public SampleModel JavaDoc createSubsetSampleModel(int bands[]) {
305     if (bands.length > numBands)
306         throw new RasterFormatException JavaDoc("There are only " +
307                         numBands +
308                         " bands");
309     int newBitMasks[] = new int[bands.length];
310     for (int i=0; i<bands.length; i++)
311         newBitMasks[i] = bitMasks[bands[i]];
312
313         return new SinglePixelPackedSampleModel JavaDoc(this.dataType, width, height,
314                        this.scanlineStride, newBitMasks);
315     }
316
317     /**
318      * Returns data for a single pixel in a primitive array of type
319      * TransferType. For a SinglePixelPackedSampleModel, the array will
320      * have one element, and the type will be the same as the storage
321      * data type. Generally, obj
322      * should be passed in as null, so that the Object will be created
323      * automatically and will be of the right primitive data type.
324      * <p>
325      * The following code illustrates transferring data for one pixel from
326      * DataBuffer <code>db1</code>, whose storage layout is described by
327      * SinglePixelPackedSampleModel <code>sppsm1</code>, to
328      * DataBuffer <code>db2</code>, whose storage layout is described by
329      * SinglePixelPackedSampleModel <code>sppsm2</code>.
330      * The transfer will generally be more efficient than using
331      * getPixel/setPixel.
332      * <pre>
333      * SinglePixelPackedSampleModel sppsm1, sppsm2;
334      * DataBufferInt db1, db2;
335      * sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
336      * db1), db2);
337      * </pre>
338      * Using getDataElements/setDataElements to transfer between two
339      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
340      * the same number of bands, corresponding bands have the same number of
341      * bits per sample, and the TransferTypes are the same.
342      * <p>
343      * If obj is non-null, it should be a primitive array of type TransferType.
344      * Otherwise, a ClassCastException is thrown. An
345      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
346      * not in bounds, or if obj is non-null and is not large enough to hold
347      * the pixel data.
348      * @param x The X coordinate of the pixel location.
349      * @param y The Y coordinate of the pixel location.
350      * @param obj If non-null, a primitive array in which to return
351      * the pixel data.
352      * @param data The DataBuffer containing the image data.
353      * @return the data for the specified pixel.
354      * @see #setDataElements(int, int, Object, DataBuffer)
355      */

356     public Object JavaDoc getDataElements(int x, int y, Object JavaDoc obj, DataBuffer JavaDoc data) {
357         // Bounds check for 'b' will be performed automatically
358
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
359             throw new ArrayIndexOutOfBoundsException JavaDoc
360                 ("Coordinate out of bounds!");
361         }
362
363     int type = getTransferType();
364
365     switch(type) {
366
367     case DataBuffer.TYPE_BYTE:
368
369         byte[] bdata;
370
371         if (obj == null)
372         bdata = new byte[1];
373         else
374         bdata = (byte[])obj;
375
376         bdata[0] = (byte)data.getElem(y * scanlineStride + x);
377
378         obj = (Object JavaDoc)bdata;
379         break;
380
381     case DataBuffer.TYPE_USHORT:
382
383         short[] sdata;
384
385         if (obj == null)
386         sdata = new short[1];
387         else
388         sdata = (short[])obj;
389
390         sdata[0] = (short)data.getElem(y * scanlineStride + x);
391
392         obj = (Object JavaDoc)sdata;
393         break;
394
395     case DataBuffer.TYPE_INT:
396
397         int[] idata;
398
399         if (obj == null)
400         idata = new int[1];
401         else
402         idata = (int[])obj;
403
404         idata[0] = data.getElem(y * scanlineStride + x);
405
406         obj = (Object JavaDoc)idata;
407         break;
408     }
409
410     return obj;
411     }
412
413     /**
414      * Returns all samples in for the specified pixel in an int array.
415      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
416      * not in bounds.
417      * @param x The X coordinate of the pixel location.
418      * @param y The Y coordinate of the pixel location.
419      * @param iArray If non-null, returns the samples in this array
420      * @param data The DataBuffer containing the image data.
421      * @return all samples for the specified pixel.
422      * @see #setPixel(int, int, int[], DataBuffer)
423      */

424     public int [] getPixel(int x, int y, int iArray[], DataBuffer JavaDoc data) {
425         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
426             throw new ArrayIndexOutOfBoundsException JavaDoc
427                 ("Coordinate out of bounds!");
428         }
429         int pixels[];
430     if (iArray == null) {
431         pixels = new int [numBands];
432         } else {
433             pixels = iArray;
434         }
435
436     int value = data.getElem(y * scanlineStride + x);
437     for (int i=0; i<numBands; i++) {
438         pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
439     }
440     return pixels;
441     }
442
443     /**
444      * Returns all samples for the specified rectangle of pixels in
445      * an int array, one sample per array element.
446      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
447      * not in bounds.
448      * @param x The X coordinate of the upper left pixel location.
449      * @param y The Y coordinate of the upper left pixel location.
450      * @param w The width of the pixel rectangle.
451      * @param h The height of the pixel rectangle.
452      * @param iArray If non-null, returns the samples in this array.
453      * @param data The DataBuffer containing the image data.
454      * @return all samples for the specified region of pixels.
455      * @see #setPixels(int, int, int, int, int[], DataBuffer)
456      */

457     public int[] getPixels(int x, int y, int w, int h,
458                            int iArray[], DataBuffer JavaDoc data) {
459         if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
460             throw new ArrayIndexOutOfBoundsException JavaDoc
461                 ("Coordinate out of bounds!");
462         }
463         int pixels[];
464         if (iArray != null) {
465            pixels = iArray;
466         } else {
467            pixels = new int [w*h*numBands];
468         }
469         int lineOffset = y*scanlineStride + x;
470         int dstOffset = 0;
471
472         for (int i = 0; i < h; i++) {
473            for (int j = 0; j < w; j++) {
474               int value = data.getElem(lineOffset+j);
475               for (int k=0; k < numBands; k++) {
476                   pixels[dstOffset++] =
477                      ((value & bitMasks[k]) >>> bitOffsets[k]);
478               }
479            }
480            lineOffset += scanlineStride;
481         }
482         return pixels;
483     }
484
485     /**
486      * Returns as int the sample in a specified band for the pixel
487      * located at (x,y).
488      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
489      * not in bounds.
490      * @param x The X coordinate of the pixel location.
491      * @param y The Y coordinate of the pixel location.
492      * @param b The band to return.
493      * @param data The DataBuffer containing the image data.
494      * @return the sample in a specified band for the specified
495      * pixel.
496      * @see #setSample(int, int, int, int, DataBuffer)
497      */

498     public int getSample(int x, int y, int b, DataBuffer JavaDoc data) {
499         // Bounds check for 'b' will be performed automatically
500
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
501             throw new ArrayIndexOutOfBoundsException JavaDoc
502                 ("Coordinate out of bounds!");
503         }
504     int sample = data.getElem(y * scanlineStride + x);
505     return ((sample & bitMasks[b]) >>> bitOffsets[b]);
506     }
507
508     /**
509      * Returns the samples for a specified band for the specified rectangle
510      * of pixels in an int array, one sample per array element.
511      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
512      * not in bounds.
513      * @param x The X coordinate of the upper left pixel location.
514      * @param y The Y coordinate of the upper left pixel location.
515      * @param w The width of the pixel rectangle.
516      * @param h The height of the pixel rectangle.
517      * @param b The band to return.
518      * @param iArray If non-null, returns the samples in this array.
519      * @param data The DataBuffer containing the image data.
520      * @return the samples for the specified band for the specified
521      * region of pixels.
522      * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
523      */

524     public int[] getSamples(int x, int y, int w, int h, int b,
525                int iArray[], DataBuffer JavaDoc data) {
526         // Bounds check for 'b' will be performed automatically
527
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
528             throw new ArrayIndexOutOfBoundsException JavaDoc
529                 ("Coordinate out of bounds!");
530         }
531         int samples[];
532         if (iArray != null) {
533            samples = iArray;
534         } else {
535            samples = new int [w*h];
536         }
537         int lineOffset = y*scanlineStride + x;
538         int dstOffset = 0;
539
540         for (int i = 0; i < h; i++) {
541            for (int j = 0; j < w; j++) {
542               int value = data.getElem(lineOffset+j);
543               samples[dstOffset++] =
544                  ((value & bitMasks[b]) >>> bitOffsets[b]);
545            }
546            lineOffset += scanlineStride;
547         }
548         return samples;
549     }
550
551     /**
552      * Sets the data for a single pixel in the specified DataBuffer from a
553      * primitive array of type TransferType. For a
554      * SinglePixelPackedSampleModel, only the first element of the array
555      * will hold valid data, and the type of the array must be the same as
556      * the storage data type of the SinglePixelPackedSampleModel.
557      * <p>
558      * The following code illustrates transferring data for one pixel from
559      * DataBuffer <code>db1</code>, whose storage layout is described by
560      * SinglePixelPackedSampleModel <code>sppsm1</code>,
561      * to DataBuffer <code>db2</code>, whose storage layout is described by
562      * SinglePixelPackedSampleModel <code>sppsm2</code>.
563      * The transfer will generally be more efficient than using
564      * getPixel/setPixel.
565      * <pre>
566      * SinglePixelPackedSampleModel sppsm1, sppsm2;
567      * DataBufferInt db1, db2;
568      * sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
569      * db1), db2);
570      * </pre>
571      * Using getDataElements/setDataElements to transfer between two
572      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
573      * the same number of bands, corresponding bands have the same number of
574      * bits per sample, and the TransferTypes are the same.
575      * <p>
576      * obj must be a primitive array of type TransferType. Otherwise,
577      * a ClassCastException is thrown. An
578      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
579      * not in bounds, or if obj is not large enough to hold the pixel data.
580      * @param x The X coordinate of the pixel location.
581      * @param y The Y coordinate of the pixel location.
582      * @param obj A primitive array containing pixel data.
583      * @param data The DataBuffer containing the image data.
584      * @see #getDataElements(int, int, Object, DataBuffer)
585      */

586     public void setDataElements(int x, int y, Object JavaDoc obj, DataBuffer JavaDoc data) {
587         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
588             throw new ArrayIndexOutOfBoundsException JavaDoc
589                 ("Coordinate out of bounds!");
590         }
591
592     int type = getTransferType();
593
594     switch(type) {
595
596     case DataBuffer.TYPE_BYTE:
597
598         byte[] barray = (byte[])obj;
599         data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
600         break;
601
602     case DataBuffer.TYPE_USHORT:
603
604         short[] sarray = (short[])obj;
605         data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
606         break;
607
608     case DataBuffer.TYPE_INT:
609
610         int[] iarray = (int[])obj;
611         data.setElem(y*scanlineStride+x, iarray[0]);
612         break;
613     }
614     }
615
616     /**
617      * Sets a pixel in the DataBuffer using an int array of samples for input.
618      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
619      * not in bounds.
620      * @param x The X coordinate of the pixel location.
621      * @param y The Y coordinate of the pixel location.
622      * @param iArray The input samples in an int array.
623      * @param data The DataBuffer containing the image data.
624      * @see #getPixel(int, int, int[], DataBuffer)
625      */

626     public void setPixel(int x, int y,
627              int iArray[],
628              DataBuffer JavaDoc data) {
629         if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
630             throw new ArrayIndexOutOfBoundsException JavaDoc
631                 ("Coordinate out of bounds!");
632         }
633         int lineOffset = y * scanlineStride + x;
634         int value = data.getElem(lineOffset);
635         for (int i=0; i < numBands; i++) {
636             value &= ~bitMasks[i];
637             value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
638         }
639         data.setElem(lineOffset, value);
640     }
641
642     /**
643      * Sets all samples for a rectangle of pixels from an int array containing
644      * one sample per array element.
645      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
646      * not in bounds.
647      * @param x The X coordinate of the upper left pixel location.
648      * @param y The Y coordinate of the upper left pixel location.
649      * @param w The width of the pixel rectangle.
650      * @param h The height of the pixel rectangle.
651      * @param iArray The input samples in an int array.
652      * @param data The DataBuffer containing the image data.
653      * @see #getPixels(int, int, int, int, int[], DataBuffer)
654      */

655     public void setPixels(int x, int y, int w, int h,
656                           int iArray[], DataBuffer JavaDoc data) {
657         if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
658             throw new ArrayIndexOutOfBoundsException JavaDoc
659                 ("Coordinate out of bounds!");
660         }
661
662         int lineOffset = y*scanlineStride + x;
663     int srcOffset = 0;
664
665         for (int i = 0; i < h; i++) {
666            for (int j = 0; j < w; j++) {
667                int value = data.getElem(lineOffset+j);
668                for (int k=0; k < numBands; k++) {
669                    value &= ~bitMasks[k];
670                    int srcValue = iArray[srcOffset++];
671                    value |= ((srcValue << bitOffsets[k])
672                              & bitMasks[k]);
673                }
674                data.setElem(lineOffset+j, value);
675            }
676            lineOffset += scanlineStride;
677         }
678     }
679
680     /**
681      * Sets a sample in the specified band for the pixel located at (x,y)
682      * in the DataBuffer using an int for input.
683      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
684      * not in bounds.
685      * @param x The X coordinate of the pixel location.
686      * @param y The Y coordinate of the pixel location.
687      * @param b The band to set.
688      * @param s The input sample as an int.
689      * @param data The DataBuffer containing the image data.
690      * @see #getSample(int, int, int, DataBuffer)
691      */

692     public void setSample(int x, int y, int b, int s,
693               DataBuffer JavaDoc data) {
694         // Bounds check for 'b' will be performed automatically
695
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
696             throw new ArrayIndexOutOfBoundsException JavaDoc
697                 ("Coordinate out of bounds!");
698         }
699         int value = data.getElem(y*scanlineStride + x);
700         value &= ~bitMasks[b];
701         value |= (s << bitOffsets[b]) & bitMasks[b];
702         data.setElem(y*scanlineStride + x,value);
703     }
704
705     /**
706      * Sets the samples in the specified band for the specified rectangle
707      * of pixels from an int array containing one sample per array element.
708      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
709      * not in bounds.
710      * @param x The X coordinate of the upper left pixel location.
711      * @param y The Y coordinate of the upper left pixel location.
712      * @param w The width of the pixel rectangle.
713      * @param h The height of the pixel rectangle.
714      * @param b The band to set.
715      * @param iArray The input samples in an int array.
716      * @param data The DataBuffer containing the image data.
717      * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
718      */

719     public void setSamples(int x, int y, int w, int h, int b,
720               int iArray[], DataBuffer JavaDoc data) {
721         // Bounds check for 'b' will be performed automatically
722
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
723             throw new ArrayIndexOutOfBoundsException JavaDoc
724                 ("Coordinate out of bounds!");
725         }
726         int lineOffset = y*scanlineStride + x;
727         int srcOffset = 0;
728
729         for (int i = 0; i < h; i++) {
730            for (int j = 0; j < w; j++) {
731               int value = data.getElem(lineOffset+j);
732               value &= ~bitMasks[b];
733               int sample = iArray[srcOffset++];
734               value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
735               data.setElem(lineOffset+j,value);
736            }
737            lineOffset += scanlineStride;
738         }
739     }
740
741     public boolean equals(Object JavaDoc o) {
742         if ((o == null) || !(o instanceof SinglePixelPackedSampleModel JavaDoc)) {
743             return false;
744         }
745
746         SinglePixelPackedSampleModel JavaDoc that = (SinglePixelPackedSampleModel JavaDoc)o;
747         return this.width == that.width &&
748             this.height == that.height &&
749             this.numBands == that.numBands &&
750             this.dataType == that.dataType &&
751             Arrays.equals(this.bitMasks, that.bitMasks) &&
752             Arrays.equals(this.bitOffsets, that.bitOffsets) &&
753             Arrays.equals(this.bitSizes, that.bitSizes) &&
754             this.maxBitSize == that.maxBitSize &&
755             this.scanlineStride == that.scanlineStride;
756     }
757
758     // If we implement equals() we must also implement hashCode
759
public int hashCode() {
760         int hash = 0;
761         hash = width;
762         hash <<= 8;
763         hash ^= height;
764         hash <<= 8;
765         hash ^= numBands;
766         hash <<= 8;
767         hash ^= dataType;
768         hash <<= 8;
769         for (int i = 0; i < bitMasks.length; i++) {
770             hash ^= bitMasks[i];
771             hash <<= 8;
772         }
773         for (int i = 0; i < bitOffsets.length; i++) {
774             hash ^= bitOffsets[i];
775             hash <<= 8;
776         }
777         for (int i = 0; i < bitSizes.length; i++) {
778             hash ^= bitSizes[i];
779             hash <<= 8;
780         }
781         hash ^= maxBitSize;
782         hash <<= 8;
783         hash ^= scanlineStride;
784         return hash;
785     }
786 }
787
Popular Tags