KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)BufferedImage.java 1.101 04/07/16
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.image;
9
10 import java.awt.Transparency JavaDoc;
11 import java.awt.color.ColorSpace JavaDoc;
12 import java.awt.Graphics2D JavaDoc;
13 import java.awt.GraphicsConfiguration JavaDoc;
14 import java.awt.GraphicsEnvironment JavaDoc;
15 import java.awt.ImageCapabilities JavaDoc;
16 import java.awt.geom.Rectangle2D JavaDoc;
17 import java.awt.geom.Point2D JavaDoc;
18 import java.awt.Point JavaDoc;
19 import java.awt.Rectangle JavaDoc;
20 import java.util.Hashtable JavaDoc;
21 import java.util.Vector JavaDoc;
22
23 import sun.awt.image.BytePackedRaster;
24 import sun.awt.image.ShortComponentRaster;
25 import sun.awt.image.ByteComponentRaster;
26 import sun.awt.image.IntegerComponentRaster;
27 import sun.awt.image.OffScreenImageSource;
28
29 /**
30  *
31  * The <code>BufferedImage</code> subclass describes an {@link
32  * java.awt.Image Image} with an accessible buffer of image data.
33  * A <code>BufferedImage</code> is comprised of a {@link ColorModel} and a
34  * {@link Raster} of image data.
35  * The number and types of bands in the {@link SampleModel} of the
36  * <code>Raster</code> must match the number and types required by the
37  * <code>ColorModel</code> to represent its color and alpha components.
38  * All <code>BufferedImage</code> objects have an upper left corner
39  * coordinate of (0,&nbsp;0). Any <code>Raster</code> used to construct a
40  * <code>BufferedImage</code> must therefore have minX=0 and minY=0.
41  *
42  * <p>
43  * This class relies on the data fetching and setting methods
44  * of <code>Raster</code>,
45  * and on the color characterization methods of <code>ColorModel</code>.
46  *
47  * @see ColorModel
48  * @see Raster
49  * @see WritableRaster
50  * @version 10 Feb 1997
51  */

52
53 public class BufferedImage extends java.awt.Image JavaDoc
54                            implements WritableRenderedImage JavaDoc, Transparency JavaDoc
55 {
56     int imageType = TYPE_CUSTOM;
57     ColorModel JavaDoc colorModel;
58     WritableRaster JavaDoc raster;
59     OffScreenImageSource osis;
60     Hashtable JavaDoc properties;
61
62     boolean isAlphaPremultiplied;// If true, alpha has been premultiplied in
63
// color channels
64

65     sun.awt.image.SurfaceManager surfaceManager;
66
67     /**
68      * Image Type Constants
69      */

70
71     /**
72      * Image type is not recognized so it must be a customized
73      * image. This type is only used as a return value for the getType()
74      * method.
75      */

76     public static final int TYPE_CUSTOM = 0;
77
78     /**
79      * Represents an image with 8-bit RGB color components packed into
80      * integer pixels. The image has a {@link DirectColorModel} without
81      * alpha.
82      * When data with non-opaque alpha is stored
83      * in an image of this type,
84      * the color data must be adjusted to a non-premultiplied form
85      * and the alpha discarded,
86      * as described in the
87      * {@link java.awt.AlphaComposite} documentation.
88      */

89     public static final int TYPE_INT_RGB = 1;
90
91     /**
92      * Represents an image with 8-bit RGBA color components packed into
93      * integer pixels. The image has a <code>DirectColorModel</code>
94      * with alpha. The color data in this image is considered not to be
95      * premultiplied with alpha. When this type is used as the
96      * <code>imageType</code> argument to a <code>BufferedImage</code>
97      * constructor, the created image is consistent with images
98      * created in the JDK1.1 and earlier releases.
99      */

100     public static final int TYPE_INT_ARGB = 2;
101
102     /**
103      * Represents an image with 8-bit RGBA color components packed into
104      * integer pixels. The image has a <code>DirectColorModel</code>
105      * with alpha. The color data in this image is considered to be
106      * premultiplied with alpha.
107      */

108     public static final int TYPE_INT_ARGB_PRE = 3;
109
110     /**
111      * Represents an image with 8-bit RGB color components, corresponding
112      * to a Windows- or Solaris- style BGR color model, with the colors
113      * Blue, Green, and Red packed into integer pixels. There is no alpha.
114      * The image has a {@link DirectColorModel}.
115      * When data with non-opaque alpha is stored
116      * in an image of this type,
117      * the color data must be adjusted to a non-premultiplied form
118      * and the alpha discarded,
119      * as described in the
120      * {@link java.awt.AlphaComposite} documentation.
121      */

122     public static final int TYPE_INT_BGR = 4;
123
124     /**
125      * Represents an image with 8-bit RGB color components, corresponding
126      * to a Windows-style BGR color model) with the colors Blue, Green,
127      * and Red stored in 3 bytes. There is no alpha. The image has a
128      * <code>ComponentColorModel</code>.
129      * When data with non-opaque alpha is stored
130      * in an image of this type,
131      * the color data must be adjusted to a non-premultiplied form
132      * and the alpha discarded,
133      * as described in the
134      * {@link java.awt.AlphaComposite} documentation.
135      */

136     public static final int TYPE_3BYTE_BGR = 5;
137
138     /**
139      * Represents an image with 8-bit RGBA color components with the colors
140      * Blue, Green, and Red stored in 3 bytes and 1 byte of alpha. The
141      * image has a <code>ComponentColorModel</code> with alpha. The
142      * color data in this image is considered not to be premultiplied with
143      * alpha. The byte data is interleaved in a single
144      * byte array in the order A, B, G, R
145      * from lower to higher byte addresses within each pixel.
146      */

147     public static final int TYPE_4BYTE_ABGR = 6;
148
149     /**
150      * Represents an image with 8-bit RGBA color components with the colors
151      * Blue, Green, and Red stored in 3 bytes and 1 byte of alpha. The
152      * image has a <code>ComponentColorModel</code> with alpha. The color
153      * data in this image is considered to be premultiplied with alpha.
154      * The byte data is interleaved in a single byte array in the order
155      * A, B, G, R from lower to higher byte addresses within each pixel.
156      */

157     public static final int TYPE_4BYTE_ABGR_PRE = 7;
158
159     /**
160      * Represents an image with 5-6-5 RGB color components (5-bits red,
161      * 6-bits green, 5-bits blue) with no alpha. This image has
162      * a <code>DirectColorModel</code>.
163      * When data with non-opaque alpha is stored
164      * in an image of this type,
165      * the color data must be adjusted to a non-premultiplied form
166      * and the alpha discarded,
167      * as described in the
168      * {@link java.awt.AlphaComposite} documentation.
169      */

170     public static final int TYPE_USHORT_565_RGB = 8;
171     
172     /**
173      * Represents an image with 5-5-5 RGB color components (5-bits red,
174      * 5-bits green, 5-bits blue) with no alpha. This image has
175      * a <code>DirectColorModel</code>.
176      * When data with non-opaque alpha is stored
177      * in an image of this type,
178      * the color data must be adjusted to a non-premultiplied form
179      * and the alpha discarded,
180      * as described in the
181      * {@link java.awt.AlphaComposite} documentation.
182      */

183     public static final int TYPE_USHORT_555_RGB = 9;
184
185     /**
186      * Represents a unsigned byte grayscale image, non-indexed. This
187      * image has a <code>ComponentColorModel</code> with a CS_GRAY
188      * {@link ColorSpace}.
189      * When data with non-opaque alpha is stored
190      * in an image of this type,
191      * the color data must be adjusted to a non-premultiplied form
192      * and the alpha discarded,
193      * as described in the
194      * {@link java.awt.AlphaComposite} documentation.
195      */

196     public static final int TYPE_BYTE_GRAY = 10;
197     
198     /**
199      * Represents an unsigned short grayscale image, non-indexed). This
200      * image has a <code>ComponentColorModel</code> with a CS_GRAY
201      * <code>ColorSpace</code>.
202      * When data with non-opaque alpha is stored
203      * in an image of this type,
204      * the color data must be adjusted to a non-premultiplied form
205      * and the alpha discarded,
206      * as described in the
207      * {@link java.awt.AlphaComposite} documentation.
208      */

209     public static final int TYPE_USHORT_GRAY = 11;
210     
211     /**
212      * Represents an opaque byte-packed 1, 2, or 4 bit image. The
213      * image has an {@link IndexColorModel} without alpha. When this
214      * type is used as the <code>imageType</code> argument to the
215      * <code>BufferedImage</code> constructor that takes an
216      * <code>imageType</code> argument but no <code>ColorModel</code>
217      * argument, a 1-bit image is created with an
218      * <code>IndexColorModel</code> with two colors in the default
219      * sRGB <code>ColorSpace</code>: {0,&nbsp;0,&nbsp;0} and
220      * {255,&nbsp;255,&nbsp;255}.
221      *
222      * <p> Images with 2 or 4 bits per pixel may be constructed via
223      * the <code>BufferedImage</code> constructor that takes a
224      * <code>ColorModel</code> argument by supplying a
225      * <code>ColorModel</code> with an appropriate map size.
226      *
227      * <p> Images with 8 bits per pixel should use the image types
228      * <code>TYPE_BYTE_INDEXED</code> or <code>TYPE_BYTE_GRAY</code>
229      * depending on their <code>ColorModel</code>.
230
231      * <p> When color data is stored in an image of this type,
232      * the closest color in the colormap is determined
233      * by the <code>IndexColorModel</code> and the resulting index is stored.
234      * Approximation and loss of alpha or color components
235      * can result, depending on the colors in the
236      * <code>IndexColorModel</code> colormap.
237      */

238     public static final int TYPE_BYTE_BINARY = 12;
239
240     /**
241      * Represents an indexed byte image. When this type is used as the
242      * <code>imageType</code> argument to the <code>BufferedImage</code>
243      * constructor that takes an <code>imageType</code> argument
244      * but no <code>ColorModel</code> argument, an
245      * <code>IndexColorModel</code> is created with
246      * a 256-color 6/6/6 color cube palette with the rest of the colors
247      * from 216-255 populated by grayscale values in the
248      * default sRGB ColorSpace.
249      *
250      * <p> When color data is stored in an image of this type,
251      * the closest color in the colormap is determined
252      * by the <code>IndexColorModel</code> and the resulting index is stored.
253      * Approximation and loss of alpha or color components
254      * can result, depending on the colors in the
255      * <code>IndexColorModel</code> colormap.
256      */

257     public static final int TYPE_BYTE_INDEXED = 13;
258     
259     private static final int DCM_RED_MASK = 0x00ff0000;
260     private static final int DCM_GREEN_MASK = 0x0000ff00;
261     private static final int DCM_BLUE_MASK = 0x000000ff;
262     private static final int DCM_ALPHA_MASK = 0xff000000;
263     private static final int DCM_565_RED_MASK = 0xf800;
264     private static final int DCM_565_GRN_MASK = 0x07E0;
265     private static final int DCM_565_BLU_MASK = 0x001F;
266     private static final int DCM_555_RED_MASK = 0x7C00;
267     private static final int DCM_555_GRN_MASK = 0x03E0;
268     private static final int DCM_555_BLU_MASK = 0x001F;
269     private static final int DCM_BGR_RED_MASK = 0x0000ff;
270     private static final int DCM_BGR_GRN_MASK = 0x00ff00;
271     private static final int DCM_BGR_BLU_MASK = 0xff0000;
272
273     
274     static private native void initIDs();
275     static {
276         ColorModel.loadLibraries();
277         initIDs();
278     }
279
280     /**
281      * Constructs a <code>BufferedImage</code> of one of the predefined
282      * image types. The <code>ColorSpace</code> for the image is the
283      * default sRGB space.
284      * @param width width of the created image
285      * @param height height of the created image
286      * @param imageType type of the created image
287      * @see ColorSpace
288      * @see #TYPE_INT_RGB
289      * @see #TYPE_INT_ARGB
290      * @see #TYPE_INT_ARGB_PRE
291      * @see #TYPE_INT_BGR
292      * @see #TYPE_3BYTE_BGR
293      * @see #TYPE_4BYTE_ABGR
294      * @see #TYPE_4BYTE_ABGR_PRE
295      * @see #TYPE_BYTE_GRAY
296      * @see #TYPE_USHORT_GRAY
297      * @see #TYPE_BYTE_BINARY
298      * @see #TYPE_BYTE_INDEXED
299      * @see #TYPE_USHORT_565_RGB
300      * @see #TYPE_USHORT_555_RGB
301      */

302     public BufferedImage(int width,
303                          int height,
304                          int imageType) {
305         switch (imageType) {
306         case TYPE_INT_RGB:
307             {
308                 colorModel = new DirectColorModel JavaDoc(24,
309                                                   0x00ff0000, // Red
310
0x0000ff00, // Green
311
0x000000ff, // Blue
312
0x0 // Alpha
313
);
314                   raster = colorModel.createCompatibleWritableRaster(width,
315                                                                       height);
316             }
317         break;
318             
319         case TYPE_INT_ARGB:
320             {
321                 colorModel = ColorModel.getRGBdefault();
322                 
323                 raster = colorModel.createCompatibleWritableRaster(width,
324                                                                    height);
325             }
326         break;
327
328         case TYPE_INT_ARGB_PRE:
329             {
330                 colorModel = new
331                     DirectColorModel JavaDoc(
332                                      ColorSpace.getInstance(ColorSpace.CS_sRGB),
333                                      32,
334                                      0x00ff0000,// Red
335
0x0000ff00,// Green
336
0x000000ff,// Blue
337
0xff000000,// Alpha
338
true, // Alpha Premultiplied
339
DataBuffer.TYPE_INT
340                                      );
341
342                   raster = colorModel.createCompatibleWritableRaster(width,
343                                                                       height);
344             }
345         break;
346
347         case TYPE_INT_BGR:
348             {
349                 colorModel = new DirectColorModel JavaDoc(24,
350                                                   0x000000ff, // Red
351
0x0000ff00, // Green
352
0x00ff0000 // Blue
353
);
354                   raster = colorModel.createCompatibleWritableRaster(width,
355                                                                       height);
356             }
357         break;
358
359         case TYPE_3BYTE_BGR:
360             {
361                 ColorSpace JavaDoc cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
362                 int[] nBits = {8, 8, 8};
363                 int[] bOffs = {2, 1, 0};
364                 colorModel = new ComponentColorModel JavaDoc(cs, nBits, false, false,
365                                                      Transparency.OPAQUE,
366                                                      DataBuffer.TYPE_BYTE);
367                 raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
368                                                         width, height,
369                                                         width*3, 3,
370                                                         bOffs, null);
371             }
372         break;
373             
374         case TYPE_4BYTE_ABGR:
375             {
376                 ColorSpace JavaDoc cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
377                 int[] nBits = {8, 8, 8, 8};
378                 int[] bOffs = {3, 2, 1, 0};
379                 colorModel = new ComponentColorModel JavaDoc(cs, nBits, true, false,
380                                                      Transparency.TRANSLUCENT,
381                                                      DataBuffer.TYPE_BYTE);
382                 raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
383                                                         width, height,
384                                                         width*4, 4,
385                                                         bOffs, null);
386             }
387         break;
388
389         case TYPE_4BYTE_ABGR_PRE:
390             {
391                 ColorSpace JavaDoc cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
392                 int[] nBits = {8, 8, 8, 8};
393                 int[] bOffs = {3, 2, 1, 0};
394                 colorModel = new ComponentColorModel JavaDoc(cs, nBits, true, true,
395                                                      Transparency.TRANSLUCENT,
396                                                      DataBuffer.TYPE_BYTE);
397                 raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
398                                                         width, height,
399                                                         width*4, 4,
400                                                         bOffs, null);
401             }
402         break;
403
404         case TYPE_BYTE_GRAY:
405             {
406                 ColorSpace JavaDoc cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
407                 int[] nBits = {8};
408                 colorModel = new ComponentColorModel JavaDoc(cs, nBits, false, true,
409                                                      Transparency.OPAQUE,
410                                                      DataBuffer.TYPE_BYTE);
411                 raster = colorModel.createCompatibleWritableRaster(width,
412                                                                    height);
413             }
414         break;
415                 
416         case TYPE_USHORT_GRAY:
417             {
418                 ColorSpace JavaDoc cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
419                 int[] nBits = {16};
420                 colorModel = new ComponentColorModel JavaDoc(cs, nBits, false, true,
421                                                      Transparency.OPAQUE,
422                                                      DataBuffer.TYPE_USHORT);
423                 raster = colorModel.createCompatibleWritableRaster(width,
424                                                                    height);
425             }
426         break;
427                 
428         case TYPE_BYTE_BINARY:
429             {
430                 byte[] arr = {(byte)0, (byte)0xff};
431                 
432                 colorModel = new IndexColorModel JavaDoc(1, 2, arr, arr, arr);
433                 raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE,
434                                                    width, height, 1, 1, null);
435             }
436         break;
437         
438         case TYPE_BYTE_INDEXED:
439             {
440                 // Create a 6x6x6 color cube
441
int[] cmap = new int[256];
442                 int i=0;
443                 for (int r=0; r < 256; r += 51) {
444                     for (int g=0; g < 256; g += 51) {
445                         for (int b=0; b < 256; b += 51) {
446                             cmap[i++] = (r<<16)|(g<<8)|b;
447                         }
448                     }
449                 }
450                 // And populate the rest of the cmap with gray values
451
int grayIncr = 256/(256-i);
452                 
453                 // The gray ramp will be between 18 and 252
454
int gray = grayIncr*3;
455                 for (; i < 256; i++) {
456                     cmap[i] = (gray<<16)|(gray<<8)|gray;
457                     gray += grayIncr;
458                 }
459
460                 colorModel = new IndexColorModel JavaDoc(8, 256, cmap, 0, false, -1,
461                                                  DataBuffer.TYPE_BYTE);
462                 raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
463                                                       width, height, 1, null);
464             }
465         break;
466
467         case TYPE_USHORT_565_RGB:
468             {
469                 colorModel = new DirectColorModel JavaDoc(16,
470                                                   DCM_565_RED_MASK,
471                                                   DCM_565_GRN_MASK,
472                                                   DCM_565_BLU_MASK
473                                                   );
474                 raster = colorModel.createCompatibleWritableRaster(width,
475                                                                    height);
476             }
477             break;
478
479         case TYPE_USHORT_555_RGB:
480             {
481                 colorModel = new DirectColorModel JavaDoc(15,
482                                                   DCM_555_RED_MASK,
483                                                   DCM_555_GRN_MASK,
484                                                   DCM_555_BLU_MASK
485                                                   );
486                 raster = colorModel.createCompatibleWritableRaster(width,
487                                                                    height);
488             }
489             break;
490
491         default:
492             throw new IllegalArgumentException JavaDoc ("Unknown image type " +
493                                                 imageType);
494         }
495
496         this.imageType = imageType;
497     }
498
499     /**
500      * Constructs a <code>BufferedImage</code> of one of the predefined
501      * image types:
502      * TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED.
503      *
504      * <p> If the image type is TYPE_BYTE_BINARY, the number of
505      * entries in the color model is used to determine whether the
506      * image should have 1, 2, or 4 bits per pixel. If the color model
507      * has 1 or 2 entries, the image will have 1 bit per pixel. If it
508      * has 3 or 4 entries, the image with have 2 bits per pixel. If
509      * it has between 5 and 16 entries, the image will have 4 bits per
510      * pixel. Otherwise, an IllegalArgumentException will be thrown.
511      *
512      * @param width width of the created image
513      * @param height height of the created image
514      * @param imageType type of the created image
515      * @param cm <code>IndexColorModel</code> of the created image
516      * @throws IllegalArgumentException if the imageType is not
517      * TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED or if the imageType is
518      * TYPE_BYTE_BINARY and the color map has more than 16 entries.
519      * @see #TYPE_BYTE_BINARY
520      * @see #TYPE_BYTE_INDEXED
521      */

522     public BufferedImage (int width,
523                           int height,
524                           int imageType,
525                           IndexColorModel JavaDoc cm) {
526         if (cm.hasAlpha() && cm.isAlphaPremultiplied()) {
527             throw new IllegalArgumentException JavaDoc("This image types do not have "+
528                                                "premultiplied alpha.");
529         }
530
531         switch(imageType) {
532         case TYPE_BYTE_BINARY:
533             int bits; // Will be set below
534
int mapSize = cm.getMapSize();
535             if (mapSize <= 2) {
536                 bits = 1;
537             } else if (mapSize <= 4) {
538                 bits = 2;
539             } else if (mapSize <= 16) {
540                 bits = 4;
541             } else {
542                 throw new IllegalArgumentException JavaDoc
543                     ("Color map for TYPE_BYTE_BINARY " +
544                      "must have no more than 16 entries");
545             }
546             raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE,
547                                                 width, height, 1, bits, null);
548             break;
549             
550         case TYPE_BYTE_INDEXED:
551             raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
552                                                     width, height, 1, null);
553             break;
554         default:
555             throw new IllegalArgumentException JavaDoc("Invalid image type (" +
556                                                imageType+"). Image type must"+
557                                                " be either TYPE_BYTE_BINARY or "+
558                                                " TYPE_BYTE_INDEXED");
559         }
560
561         if (!cm.isCompatibleRaster(raster)) {
562             throw new IllegalArgumentException JavaDoc("Incompatible image type and IndexColorModel");
563         }
564
565         colorModel = cm;
566         this.imageType = imageType;
567     }
568
569     /**
570      * Constructs a new <code>BufferedImage</code> with a specified
571      * <code>ColorModel</code> and <code>Raster</code>. If the number and
572      * types of bands in the <code>SampleModel</code> of the
573      * <code>Raster</code> do not match the number and types required by
574      * the <code>ColorModel</code> to represent its color and alpha
575      * components, a {@link RasterFormatException} is thrown. This
576      * method can multiply or divide the color <code>Raster</code> data by
577      * alpha to match the <code>alphaPremultiplied</code> state
578      * in the <code>ColorModel</code>. Properties for this
579      * <code>BufferedImage</code> can be established by passing
580      * in a {@link Hashtable} of <code>String</code>/<code>Object</code>
581      * pairs.
582      * @param cm <code>ColorModel</code> for the new image
583      * @param raster <code>Raster</code> for the image data
584      * @param isRasterPremultiplied if <code>true</code>, the data in
585      * the raster has been premultiplied with alpha.
586      * @param properties <code>Hashtable</code> of
587      * <code>String</code>/<code>Object</code> pairs.
588      * @exception <code>RasterFormatException</code> if the number and
589      * types of bands in the <code>SampleModel</code> of the
590      * <code>Raster</code> do not match the number and types required by
591      * the <code>ColorModel</code> to represent its color and alpha
592      * components.
593      * @exception <code>IllegalArgumentException</code> if
594      * <code>raster</code> is incompatible with <code>cm</code>
595      * @see ColorModel
596      * @see Raster
597      * @see WritableRaster
598      */

599
600
601 /*
602  *
603  * FOR NOW THE CODE WHICH DEFINES THE RASTER TYPE IS DUPLICATED BY DVF
604  * SEE THE METHOD DEFINERASTERTYPE @ RASTEROUTPUTMANAGER
605  *
606  */

607     public BufferedImage (ColorModel JavaDoc cm,
608                           WritableRaster JavaDoc raster,
609                           boolean isRasterPremultiplied,
610                           Hashtable JavaDoc<?,?> properties) {
611
612         if (!cm.isCompatibleRaster(raster)) {
613             throw new
614                 IllegalArgumentException JavaDoc("Raster "+raster+
615                                          " is incompatible with ColorModel "+
616                                          cm);
617         }
618
619     if ((raster.minX != 0) || (raster.minY != 0)) {
620             throw new
621                 IllegalArgumentException JavaDoc("Raster "+raster+
622                                          " has minX or minY not equal to zero: "
623                                          + raster.minX + " " + raster.minY);
624     }
625
626         colorModel = cm;
627         this.raster = raster;
628         this.properties = properties;
629         int numBands = raster.getNumBands();
630         boolean isAlphaPre = cm.isAlphaPremultiplied();
631         ColorSpace JavaDoc cs;
632         
633         // Force the raster data alpha state to match the premultiplied
634
// state in the color model
635
coerceData(isRasterPremultiplied);
636
637         SampleModel JavaDoc sm = raster.getSampleModel();
638         cs = cm.getColorSpace();
639         int csType = cs.getType();
640         if (csType != ColorSpace.TYPE_RGB) {
641             if (csType == ColorSpace.TYPE_GRAY
642                 && cm instanceof ComponentColorModel JavaDoc) {
643                 // Check if this might be a child raster (fix for bug 4240596)
644
if (sm instanceof ComponentSampleModel JavaDoc &&
645                     ((ComponentSampleModel JavaDoc)sm).getPixelStride() != numBands) {
646                     imageType = TYPE_CUSTOM;
647                 } else if (raster instanceof ByteComponentRaster &&
648                        raster.getNumBands() == 1 &&
649                        cm.getComponentSize(0) == 8 &&
650                        ((ByteComponentRaster)raster).getPixelStride() == 1) {
651                     imageType = TYPE_BYTE_GRAY;
652                 } else if (raster instanceof ShortComponentRaster &&
653                        raster.getNumBands() == 1 &&
654                        cm.getComponentSize(0) == 16 &&
655                        ((ShortComponentRaster)raster).getPixelStride() == 1) {
656                     imageType = TYPE_USHORT_GRAY;
657                 }
658             } else {
659                 imageType = TYPE_CUSTOM;
660             }
661             return;
662         }
663
664         if ((raster instanceof IntegerComponentRaster) &&
665             (numBands == 3 || numBands == 4)) {
666             IntegerComponentRaster iraster =
667                 (IntegerComponentRaster) raster;
668             // Check if the raster params and the color model
669
// are correct
670
int pixSize = cm.getPixelSize();
671             if (iraster.getPixelStride() == 1 &&
672                 cm instanceof DirectColorModel JavaDoc &&
673                 (pixSize == 32 || pixSize == 24))
674             {
675                 // Now check on the DirectColorModel params
676
DirectColorModel JavaDoc dcm = (DirectColorModel JavaDoc) cm;
677                 int rmask = dcm.getRedMask();
678                 int gmask = dcm.getGreenMask();
679                 int bmask = dcm.getBlueMask();
680                 if (rmask == DCM_RED_MASK && gmask == DCM_GREEN_MASK &&
681                     bmask == DCM_BLUE_MASK)
682                 {
683                     if (dcm.getAlphaMask() == DCM_ALPHA_MASK) {
684                         imageType = (isAlphaPre
685                                      ? TYPE_INT_ARGB_PRE
686                                      : TYPE_INT_ARGB);
687                     }
688                     else {
689                         // No Alpha
690
if (!dcm.hasAlpha()) {
691                             imageType = TYPE_INT_RGB;
692                         }
693                     }
694                 } // if (dcm.getRedMask() == DCM_RED_MASK &&
695
else if (rmask == DCM_BGR_RED_MASK && gmask == DCM_BGR_GRN_MASK
696                          && bmask == DCM_BGR_BLU_MASK) {
697                     if (!dcm.hasAlpha()) {
698                         imageType = TYPE_INT_BGR;
699                     }
700                 } // if (rmask == DCM_BGR_RED_MASK &&
701
} // if (iraster.getPixelStride() == 1
702
} // ((raster instanceof IntegerComponentRaster) &&
703
else if ((cm instanceof IndexColorModel JavaDoc) && (numBands == 1) &&
704                  (!cm.hasAlpha() || !isAlphaPre))
705         {
706             IndexColorModel JavaDoc icm = (IndexColorModel JavaDoc) cm;
707             int pixSize = icm.getPixelSize();
708
709             if (raster instanceof BytePackedRaster) {
710                 imageType = TYPE_BYTE_BINARY;
711             } // if (raster instanceof BytePackedRaster)
712
else if (raster instanceof ByteComponentRaster) {
713                 ByteComponentRaster braster = (ByteComponentRaster) raster;
714                 if (braster.getPixelStride() == 1 && pixSize <= 8) {
715                     imageType = TYPE_BYTE_INDEXED;
716                 }
717             }
718         } // else if (cm instanceof IndexColorModel) && (numBands == 1))
719
else if ((raster instanceof ShortComponentRaster)
720                  && (cm