1 /* Copyright (C) 2000, 2002, 2003  Free Software Foundation
2 
3 This file is part of GNU Classpath.
4 
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9 
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING.  If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 USA.
19 
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library.  Thus, the terms and
22 conditions of the GNU General Public License cover the whole
23 combination.
24 
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module.  An independent module is a module which is not derived from
32 or based on this library.  If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so.  If you do not wish to do so, delete this
35 exception statement from your version. */
36 
37 
38 package java.awt.image;
39 
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 
43 /**
44  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
45  */
46 public class Raster
47 {
48   protected SampleModel sampleModel;
49   protected DataBuffer dataBuffer;
50   protected int minX;
51   protected int minY;
52   protected int width;
53   protected int height;
54   protected int sampleModelTranslateX;
55   protected int sampleModelTranslateY;
56   protected int numBands;
57   protected int numDataElements;
58   protected Raster parent;
59 
Raster(SampleModel sampleModel, Point origin)60   protected Raster(SampleModel sampleModel, Point origin)
61   {
62     this(sampleModel, sampleModel.createDataBuffer(), origin);
63   }
64 
Raster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin)65   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
66 		   Point origin)
67   {
68     this(sampleModel, dataBuffer,
69 	 new Rectangle(origin.x, origin.y,
70 		       sampleModel.getWidth(), sampleModel.getHeight()),
71 	 origin, null);
72   }
73 
Raster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion, Point sampleModelTranslate, Raster parent)74   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
75 		   Rectangle aRegion,
76 		   Point sampleModelTranslate, Raster parent)
77   {
78     this.sampleModel = sampleModel;
79     this.dataBuffer = dataBuffer;
80     this.minX = aRegion.x;
81     this.minY = aRegion.y;
82     this.width = aRegion.width;
83     this.height = aRegion.height;
84 
85     // If sampleModelTranslate is null, use (0,0).  Methods such as
86     // Raster.createRaster are specified to allow for a null argument.
87     if (sampleModelTranslate != null)
88     {
89       this.sampleModelTranslateX = sampleModelTranslate.x;
90       this.sampleModelTranslateY = sampleModelTranslate.y;
91     }
92 
93     this.numBands = sampleModel.getNumBands();
94     this.numDataElements = sampleModel.getNumDataElements();
95     this.parent = parent;
96   }
97 
createInterleavedRaster(int dataType, int w, int h, int bands, Point location)98   public static WritableRaster createInterleavedRaster(int dataType,
99 						       int w, int h,
100 						       int bands,
101 						       Point location)
102   {
103     int[] bandOffsets = new int[bands];
104     // TODO: Maybe not generate this every time.
105     for (int b=0; b<bands; b++) bandOffsets[b] = b;
106 
107     int scanlineStride = bands*w;
108     return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
109 				   bandOffsets, location);
110   }
111 
createInterleavedRaster(int dataType, int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets, Point location)112   public static WritableRaster createInterleavedRaster(int dataType,
113 						       int w, int h,
114 						       int scanlineStride,
115 						       int pixelStride,
116 						       int[] bandOffsets,
117 						       Point location)
118   {
119     SampleModel sm = new ComponentSampleModel(dataType,
120 					      w, h,
121 					      pixelStride,
122 					      scanlineStride,
123 					      bandOffsets);
124     return createWritableRaster(sm, location);
125   }
126 
createBandedRaster(int dataType, int w, int h, int bands, Point location)127   public static WritableRaster createBandedRaster(int dataType,
128 						  int w, int h, int bands,
129 						  Point location)
130   {
131     SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
132     return createWritableRaster(sm, location);
133   }
134 
createBandedRaster(int dataType, int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)135   public static WritableRaster createBandedRaster(int dataType,
136 						  int w, int h,
137 						  int scanlineStride,
138 						  int[] bankIndices,
139 						  int[] bandOffsets,
140 						  Point location)
141   {
142     SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
143 					   bankIndices, bandOffsets);
144     return createWritableRaster(sm, location);
145   }
146 
createPackedRaster(int dataType, int w, int h, int[] bandMasks, Point location)147   public static WritableRaster createPackedRaster(int dataType,
148 						  int w, int h,
149 						  int[] bandMasks,
150 						  Point location)
151   {
152     SampleModel sm = new SinglePixelPackedSampleModel(dataType,
153 						      w, h,
154 						      bandMasks);
155     return createWritableRaster(sm, location);
156   }
157 
createPackedRaster(int dataType, int w, int h, int bands, int bitsPerBand, Point location)158   public static WritableRaster createPackedRaster(int dataType,
159 						  int w, int h,
160 						  int bands, int bitsPerBand,
161 						  Point location)
162   {
163     if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
164       throw new IllegalArgumentException();
165 
166     SampleModel sm;
167 
168     if (bands == 1)
169 	sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
170     else
171       {
172 	int[] bandMasks = new int[bands];
173 	int mask = 0x1;
174 	for (int bits = bitsPerBand; --bits != 0;)
175 	  mask = (mask << 1) | 0x1;
176 	for (int i = 0; i < bands; i++)
177 	  {
178 	    bandMasks[i] = mask;
179 	    mask <<= bitsPerBand;
180 	  }
181 
182 	sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
183       }
184     return createWritableRaster(sm, location);
185   }
186 
187   public static WritableRaster
createInterleavedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets, Point location)188   createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
189 			  int scanlineStride, int pixelStride,
190 			  int[] bandOffsets, Point location)
191   {
192     SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
193 					      w, h,
194 					      scanlineStride,
195 					      pixelStride,
196 					      bandOffsets);
197     return createWritableRaster(sm, dataBuffer, location);
198   }
199 
200   public static
createBandedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)201   WritableRaster createBandedRaster(DataBuffer dataBuffer,
202 				    int w, int h,
203 				    int scanlineStride,
204 				    int[] bankIndices,
205 				    int[] bandOffsets,
206 				    Point location)
207   {
208     SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
209 					   w, h, scanlineStride,
210 					   bankIndices, bandOffsets);
211     return createWritableRaster(sm, dataBuffer, location);
212   }
213 
214   public static WritableRaster
createPackedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int[] bandMasks, Point location)215   createPackedRaster(DataBuffer dataBuffer,
216 		     int w, int h,
217 		     int scanlineStride,
218 		     int[] bandMasks,
219 		     Point location)
220  {
221     SampleModel sm =
222       new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
223 				       w, h,
224 				       scanlineStride,
225 				       bandMasks);
226     return createWritableRaster(sm, dataBuffer, location);
227   }
228 
229   public static WritableRaster
createPackedRaster(DataBuffer dataBuffer, int w, int h, int bitsPerPixel, Point location)230   createPackedRaster(DataBuffer dataBuffer,
231 		     int w, int h,
232 		     int bitsPerPixel,
233 		     Point location)
234   {
235     SampleModel sm =
236       new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
237 				       w, h,
238 				       bitsPerPixel);
239     return createWritableRaster(sm, dataBuffer, location);
240   }
241 
createRaster(SampleModel sm, DataBuffer db, Point location)242   public static Raster createRaster(SampleModel sm, DataBuffer db,
243 				    Point location)
244   {
245     return new Raster(sm, db, location);
246   }
247 
createWritableRaster(SampleModel sm, Point location)248   public static WritableRaster createWritableRaster(SampleModel sm,
249 						    Point location)
250   {
251     return new WritableRaster(sm, location);
252   }
253 
createWritableRaster(SampleModel sm, DataBuffer db, Point location)254   public static WritableRaster createWritableRaster(SampleModel sm,
255 						    DataBuffer db,
256 						    Point location)
257   {
258     return new WritableRaster(sm, db, location);
259   }
260 
getParent()261   public Raster getParent()
262   {
263     return parent;
264   }
265 
getSampleModelTranslateX()266   public final int getSampleModelTranslateX()
267   {
268     return sampleModelTranslateX;
269   }
270 
getSampleModelTranslateY()271   public final int getSampleModelTranslateY()
272   {
273     return sampleModelTranslateY;
274   }
275 
createCompatibleWritableRaster()276   public WritableRaster createCompatibleWritableRaster()
277   {
278     return new WritableRaster(getSampleModel(), new Point(minX, minY));
279   }
280 
createCompatibleWritableRaster(int w, int h)281   public WritableRaster createCompatibleWritableRaster(int w, int h)
282   {
283     return createCompatibleWritableRaster(minX, minY, w, h);
284   }
285 
createCompatibleWritableRaster(Rectangle rect)286   public WritableRaster createCompatibleWritableRaster(Rectangle rect)
287   {
288     return createCompatibleWritableRaster(rect.x, rect.y,
289 					  rect.width, rect.height);
290   }
291 
createCompatibleWritableRaster(int x, int y, int w, int h)292   public WritableRaster createCompatibleWritableRaster(int x, int y,
293 						       int w, int h)
294   {
295     SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
296     return new WritableRaster(sm, sm.createDataBuffer(),
297 			      new Point(x, y));
298   }
299 
createTranslatedChild(int childMinX, int childMinY)300   public Raster createTranslatedChild(int childMinX, int childMinY) {
301     int tcx = sampleModelTranslateX - minX + childMinX;
302     int tcy = sampleModelTranslateY - minY + childMinY;
303 
304     return new Raster(sampleModel, dataBuffer,
305 		      new Rectangle(childMinX, childMinY,
306 				    width, height),
307 		      new Point(tcx, tcy),
308 		      this);
309   }
310 
createChild(int parentX, int parentY, int width, int height, int childMinX, int childMinY, int[] bandList)311   public Raster createChild(int parentX, int parentY, int width,
312 			    int height, int childMinX, int childMinY,
313 			    int[] bandList)
314   {
315     /* FIXME: Throw RasterFormatException if child bounds extends
316        beyond the bounds of this raster. */
317 
318     SampleModel sm = (bandList == null) ?
319       sampleModel :
320       sampleModel.createSubsetSampleModel(bandList);
321 
322     /*
323         data origin
324        /
325       +-------------------------
326       |\. __ parent trans
327       | \`.
328       |  \ `.    parent origin
329       |   \  `. /
330       |   /\   +-------- - -
331       |trans\ /<\-- deltaTrans
332       |child +-+-\---- - -
333       |     /|`|  \__ parent [x, y]
334       |child | |`. \
335       |origin| :  `.\
336       |      |    / `\
337       |      :   /    +
338       | child [x, y]
339 
340       parent_xy - parent_trans = child_xy - child_trans
341 
342       child_trans = parent_trans + child_xy - parent_xy
343     */
344 
345     return new Raster(sm, dataBuffer,
346 		      new Rectangle(childMinX, childMinY,
347 				    width, height),
348 		      new Point(sampleModelTranslateX+childMinX-parentX,
349 				sampleModelTranslateY+childMinY-parentY),
350 		      this);
351   }
352 
getBounds()353   public Rectangle getBounds()
354   {
355     return new Rectangle(minX, minY, width, height);
356   }
357 
getMinX()358   public final int getMinX()
359   {
360     return minX;
361   }
362 
getMinY()363   public final int getMinY()
364   {
365     return minY;
366   }
367 
getWidth()368   public final int getWidth()
369   {
370     return width;
371   }
372 
getHeight()373   public final int getHeight()
374   {
375     return height;
376   }
377 
getNumBands()378   public final int getNumBands()
379   {
380     return numBands;
381   }
382 
getNumDataElements()383   public final int getNumDataElements()
384   {
385     return numDataElements;
386   }
387 
getTransferType()388   public final int getTransferType()
389   {
390     return sampleModel.getTransferType();
391   }
392 
getDataBuffer()393   public DataBuffer getDataBuffer()
394   {
395     return dataBuffer;
396   }
397 
getSampleModel()398   public SampleModel getSampleModel()
399   {
400     return sampleModel;
401   }
402 
getDataElements(int x, int y, Object outData)403   public Object getDataElements(int x, int y, Object outData)
404   {
405     return sampleModel.getDataElements(x-sampleModelTranslateX,
406 				       y-sampleModelTranslateY,
407 				       outData, dataBuffer);
408   }
409 
getDataElements(int x, int y, int w, int h, Object outData)410   public Object getDataElements(int x, int y, int w, int h,
411 				Object outData)
412   {
413     return sampleModel.getDataElements(x-sampleModelTranslateX,
414 				       y-sampleModelTranslateY,
415 				       w, h, outData, dataBuffer);
416   }
417 
getPixel(int x, int y, int[] iArray)418   public int[] getPixel(int x, int y, int[] iArray)
419   {
420     return sampleModel.getPixel(x-sampleModelTranslateX,
421 				y-sampleModelTranslateY,
422 				iArray, dataBuffer);
423   }
424 
getPixel(int x, int y, float[] fArray)425   public float[] getPixel(int x, int y, float[] fArray)
426   {
427     return sampleModel.getPixel(x-sampleModelTranslateX,
428 				y-sampleModelTranslateY,
429 				fArray, dataBuffer);
430   }
431 
getPixel(int x, int y, double[] dArray)432   public double[] getPixel(int x, int y, double[] dArray)
433   {
434     return sampleModel.getPixel(x-sampleModelTranslateX,
435 				y-sampleModelTranslateY,
436 				dArray, dataBuffer);
437   }
438 
getPixels(int x, int y, int w, int h, int[] iArray)439   public int[] getPixels(int x, int y, int w, int h, int[] iArray)
440   {
441     return sampleModel.getPixels(x-sampleModelTranslateX,
442 				 y-sampleModelTranslateY,
443 				 w, h, iArray, dataBuffer);
444   }
445 
getPixels(int x, int y, int w, int h, float[] fArray)446   public float[] getPixels(int x, int y, int w, int h,
447 			   float[] fArray)
448   {
449     return sampleModel.getPixels(x-sampleModelTranslateX,
450 				 y-sampleModelTranslateY,
451 				 w, h, fArray, dataBuffer);
452   }
453 
getPixels(int x, int y, int w, int h, double[] dArray)454   public double[] getPixels(int x, int y, int w, int h,
455 			    double[] dArray)
456   {
457     return sampleModel.getPixels(x-sampleModelTranslateX,
458 				 y-sampleModelTranslateY,
459 				 w, h, dArray, dataBuffer);
460   }
461 
getSample(int x, int y, int b)462   public int getSample(int x, int y, int b)
463   {
464     return sampleModel.getSample(x-sampleModelTranslateX,
465 				 y-sampleModelTranslateY,
466 				 b, dataBuffer);
467   }
468 
getSampleFloat(int x, int y, int b)469   public float getSampleFloat(int x, int y, int b)
470   {
471     return sampleModel.getSampleFloat(x-sampleModelTranslateX,
472 				      y-sampleModelTranslateY,
473 				      b, dataBuffer);
474   }
475 
getSampleDouble(int x, int y, int b)476   public double getSampleDouble(int x, int y, int b)
477   {
478     return sampleModel.getSampleDouble(x-sampleModelTranslateX,
479 				       y-sampleModelTranslateY,
480 				       b, dataBuffer);
481   }
482 
getSamples(int x, int y, int w, int h, int b, int[] iArray)483   public int[] getSamples(int x, int y, int w, int h, int b,
484 			  int[] iArray)
485   {
486     return sampleModel.getSamples(x-sampleModelTranslateX,
487 				  y-sampleModelTranslateY,
488 				  w, h, b, iArray, dataBuffer);
489   }
490 
getSamples(int x, int y, int w, int h, int b, float[] fArray)491   public float[] getSamples(int x, int y, int w, int h, int b,
492 			    float[] fArray)
493   {
494     return sampleModel.getSamples(x-sampleModelTranslateX,
495 				  y-sampleModelTranslateY,
496 				  w, h, b, fArray, dataBuffer);
497   }
498 
getSamples(int x, int y, int w, int h, int b, double[] dArray)499   public double[] getSamples(int x, int y, int w, int h, int b,
500 			     double[] dArray)
501   {
502     return sampleModel.getSamples(x-sampleModelTranslateX,
503 				  y-sampleModelTranslateY,
504 				  w, h, b, dArray, dataBuffer);
505   }
506 
507   /**
508    * Create a String representing the stat of this Raster.
509    * @return A String representing the stat of this Raster.
510    * @see java.lang.Object#toString()
511    */
toString()512   public String toString()
513   {
514     StringBuffer result = new StringBuffer();
515 
516     result.append(getClass().getName());
517     result.append("[(");
518     result.append(minX).append(",").append(minY).append("), ");
519     result.append(width).append(" x ").append(height).append(",");
520     result.append(sampleModel).append(",");
521     result.append(dataBuffer);
522     result.append("]");
523 
524     return result.toString();
525   }
526 
527   // Map from datatype to bits
getTypeBits(int dataType)528   private static int getTypeBits(int dataType)
529   {
530     switch (dataType)
531       {
532       case DataBuffer.TYPE_BYTE:
533 	return 8;
534       case DataBuffer.TYPE_USHORT:
535       case DataBuffer.TYPE_SHORT:
536 	return 16;
537       case DataBuffer.TYPE_INT:
538       case DataBuffer.TYPE_FLOAT:
539 	return 32;
540       case DataBuffer.TYPE_DOUBLE:
541 	return 64;
542       default:
543 	return 0;
544       }
545   }
546 }
547