OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [awt/] [image/] [BufferedImage.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* BufferedImage.java --
2
   Copyright (C) 2000, 2002, 2003, 2004, 2005  Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.awt.image;
40
 
41
import gnu.java.awt.ComponentDataBlitOp;
42
 
43
import java.awt.Graphics;
44
import java.awt.Graphics2D;
45
import java.awt.GraphicsEnvironment;
46
import java.awt.Image;
47
import java.awt.Point;
48
import java.awt.Rectangle;
49
import java.awt.Transparency;
50
import java.awt.color.ColorSpace;
51
import java.util.Hashtable;
52
import java.util.Vector;
53
 
54
/**
55
 * A buffered image always starts at coordinates (0, 0).
56
 *
57
 * The buffered image is not subdivided into multiple tiles. Instead,
58
 * the image consists of one large tile (0,0) with the width and
59
 * height of the image. This tile is always considered to be checked
60
 * out.
61
 *
62
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
63
 */
64
public class BufferedImage extends Image
65
  implements WritableRenderedImage, Transparency
66
{
67
  public static final int TYPE_CUSTOM         =  0,
68
                          TYPE_INT_RGB        =  1,
69
                          TYPE_INT_ARGB       =  2,
70
                          TYPE_INT_ARGB_PRE   =  3,
71
                          TYPE_INT_BGR        =  4,
72
                          TYPE_3BYTE_BGR      =  5,
73
                          TYPE_4BYTE_ABGR     =  6,
74
                          TYPE_4BYTE_ABGR_PRE =  7,
75
                          TYPE_USHORT_565_RGB =  8,
76
                          TYPE_USHORT_555_RGB =  9,
77
                          TYPE_BYTE_GRAY      = 10,
78
                          TYPE_USHORT_GRAY    = 11,
79
                          TYPE_BYTE_BINARY    = 12,
80
                          TYPE_BYTE_INDEXED   = 13;
81
 
82
  static final int[] bits3 = { 8, 8, 8 };
83
  static final int[] bits4 = { 8, 8, 8 };
84
  static final int[] bits1byte = { 8 };
85
  static final int[] bits1ushort = { 16 };
86
 
87
  static final int[] masks_int = { 0x00ff0000,
88
                                   0x0000ff00,
89
                                   0x000000ff,
90
                                   DataBuffer.TYPE_INT };
91
  static final int[] masks_565 = { 0xf800,
92
                                   0x07e0,
93
                                   0x001f,
94
                                   DataBuffer.TYPE_USHORT};
95
  static final int[] masks_555 = { 0x7c00,
96
                                   0x03e0,
97
                                   0x001f,
98
                                   DataBuffer.TYPE_USHORT};
99
 
100
  Vector observers;
101
 
102
  public BufferedImage(int w, int h, int type)
103
  {
104
    ColorModel cm = null;
105
 
106
    boolean alpha = false;
107
    boolean premultiplied = false;
108
    switch (type)
109
      {
110
      case TYPE_4BYTE_ABGR_PRE:
111
      case TYPE_INT_ARGB_PRE:
112
        premultiplied = true;
113
        // fall through
114
      case TYPE_INT_ARGB:
115
      case TYPE_4BYTE_ABGR:
116
        alpha = true;
117
      }
118
 
119
    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
120
    switch (type)
121
      {
122
      case TYPE_INT_RGB:
123
      case TYPE_INT_ARGB:
124
      case TYPE_INT_ARGB_PRE:
125
      case TYPE_USHORT_565_RGB:
126
      case TYPE_USHORT_555_RGB:
127
        int[] masks = null;
128
        switch (type)
129
          {
130
          case TYPE_INT_RGB:
131
          case TYPE_INT_ARGB:
132
          case TYPE_INT_ARGB_PRE:
133
            masks = masks_int;
134
            break;
135
          case TYPE_USHORT_565_RGB:
136
            masks = masks_565;
137
            break;
138
          case TYPE_USHORT_555_RGB:
139
            masks = masks_555;
140
            break;
141
          }
142
 
143
        cm = new DirectColorModel(cs,
144
                                  32, // 32 bits in an int
145
                                  masks[0], // r
146
                                  masks[1], // g
147
                                  masks[2], // b
148
                                  alpha ? 0xff000000 : 0,
149
                                  premultiplied,
150
                                  masks[3] // data type
151
                                  );
152
        break;
153
 
154
      case TYPE_INT_BGR:
155
        String msg =
156
          "FIXME: Programmer is confused. Why (and how) does a " +
157
          "TYPE_INT_BGR image use ComponentColorModel to store " +
158
          "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
159
          "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
160
        throw new UnsupportedOperationException(msg);
161
 
162
      case TYPE_3BYTE_BGR:
163
      case TYPE_4BYTE_ABGR:
164
      case TYPE_4BYTE_ABGR_PRE:
165
      case TYPE_BYTE_GRAY:
166
      case TYPE_USHORT_GRAY:
167
        int[] bits = null;
168
        int dataType = DataBuffer.TYPE_BYTE;
169
        switch (type) {
170
        case TYPE_3BYTE_BGR:
171
          bits = bits3;
172
          break;
173
        case TYPE_4BYTE_ABGR:
174
        case TYPE_4BYTE_ABGR_PRE:
175
          bits = bits4;
176
          break;
177
        case TYPE_BYTE_GRAY:
178
          bits = bits1byte;
179
          break;
180
        case TYPE_USHORT_GRAY:
181
          bits = bits1ushort;
182
          dataType = DataBuffer.TYPE_USHORT;
183
          break;
184
        }
185
        cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
186
                                     alpha ?
187
                                     Transparency.TRANSLUCENT:
188
                                     Transparency.OPAQUE,
189
                                     dataType);
190
        break;
191
      case TYPE_BYTE_BINARY:
192
        byte[] vals = { 0, (byte) 0xff };
193
        cm = new IndexColorModel(8, 2, vals, vals, vals);
194
        break;
195
      case TYPE_BYTE_INDEXED:
196
        String msg2 = "type not implemented yet";
197
        throw new UnsupportedOperationException(msg2);
198
        // FIXME: build color-cube and create color model
199
      }
200
 
201
    init(cm,
202
         cm.createCompatibleWritableRaster(w, h),
203
         premultiplied,
204
         null, // no properties
205
         type
206
         );
207
  }
208
 
209
  public BufferedImage(int w, int h, int type,
210
                       IndexColorModel indexcolormodel)
211
  {
212
    if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
213
      throw new IllegalArgumentException("type must be binary or indexed");
214
 
215
    init(indexcolormodel,
216
         indexcolormodel.createCompatibleWritableRaster(w, h),
217
         false, // not premultiplied (guess)
218
         null, // no properties
219
         type);
220
  }
221
 
222
  public BufferedImage(ColorModel colormodel,
223
                       WritableRaster writableraster,
224
                       boolean premultiplied,
225
                       Hashtable properties)
226
  {
227
    init(colormodel, writableraster, premultiplied, properties,
228
         TYPE_CUSTOM);
229
    // TODO: perhaps try to identify type?
230
  }
231
 
232
  WritableRaster raster;
233
  ColorModel colorModel;
234
  Hashtable properties;
235
  boolean isPremultiplied;
236
  int type;
237
 
238
  private void init(ColorModel cm,
239
                    WritableRaster writableraster,
240
                    boolean premultiplied,
241
                    Hashtable properties,
242
                    int type)
243
  {
244
    raster = writableraster;
245
    colorModel = cm;
246
    this.properties = properties;
247
    isPremultiplied = premultiplied;
248
    this.type = type;
249
  }
250
 
251
  //public void addTileObserver(TileObserver tileobserver) {}
252
 
253
  public void coerceData(boolean premultiplied)
254
  {
255
    colorModel = colorModel.coerceData(raster, premultiplied);
256
  }
257
 
258
  public WritableRaster copyData(WritableRaster dest)
259
  {
260
    if (dest == null)
261
      dest = raster.createCompatibleWritableRaster(getMinX(), getMinY(),
262
                                                   getWidth(),getHeight());
263
 
264
    int x = dest.getMinX();
265
    int y = dest.getMinY();
266
    int w = dest.getWidth();
267
    int h = dest.getHeight();
268
 
269
    // create a src child that has the right bounds...
270
    WritableRaster src =
271
      raster.createWritableChild(x, y, w, h, x, y,
272
                                 null  // same bands
273
                                 );
274
    if (src.getSampleModel () instanceof ComponentSampleModel
275
        && dest.getSampleModel () instanceof ComponentSampleModel)
276
      // Refer to ComponentDataBlitOp for optimized data blitting:
277
      ComponentDataBlitOp.INSTANCE.filter(src, dest);
278
    else
279
      {
280
        // slower path
281
        int samples[] = src.getPixels (x, y, w, h, (int [])null);
282
        dest.setPixels (x, y, w, h, samples);
283
      }
284
    return dest;
285
  }
286
 
287
  public Graphics2D createGraphics()
288
  {
289
    GraphicsEnvironment env;
290
    env = GraphicsEnvironment.getLocalGraphicsEnvironment ();
291
    return env.createGraphics (this);
292
  }
293
 
294
  public void flush() {
295
  }
296
 
297
  public WritableRaster getAlphaRaster()
298
  {
299
    return colorModel.getAlphaRaster(raster);
300
  }
301
 
302
  public ColorModel getColorModel()
303
  {
304
    return colorModel;
305
  }
306
 
307
  public Raster getData()
308
  {
309
    return copyData(null);
310
    /* TODO: this might be optimized by returning the same
311
       raster (not writable) as long as image data doesn't change. */
312
  }
313
 
314
  public Raster getData(Rectangle rectangle)
315
  {
316
    WritableRaster dest =
317
      raster.createCompatibleWritableRaster(rectangle);
318
    return copyData(dest);
319
  }
320
 
321
  public Graphics getGraphics()
322
  {
323
    return createGraphics();
324
  }
325
 
326
  public int getHeight()
327
  {
328
    return raster.getHeight();
329
  }
330
 
331
  public int getHeight(ImageObserver imageobserver)
332
  {
333
    return getHeight();
334
  }
335
 
336
  public int getMinTileX()
337
  {
338
    return 0;
339
  }
340
 
341
  public int getMinTileY()
342
  {
343
    return 0;
344
  }
345
 
346
  public int getMinX()
347
  {
348
    return 0;
349
  }
350
 
351
  public int getMinY()
352
  {
353
    return 0;
354
  }
355
 
356
  public int getNumXTiles()
357
  {
358
    return 1;
359
  }
360
 
361
  public int getNumYTiles()
362
  {
363
        return 1;
364
  }
365
 
366
  public Object getProperty(String string)
367
  {
368
    if (properties == null)
369
      return null;
370
    return properties.get(string);
371
  }
372
 
373
  public Object getProperty(String string, ImageObserver imageobserver)
374
  {
375
    return getProperty(string);
376
  }
377
 
378
 
379
  public String[] getPropertyNames()
380
  {
381
    // FIXME: implement
382
    return null;
383
  }
384
 
385
  public int getRGB(int x, int y)
386
  {
387
    Object rgbElem = raster.getDataElements(x, y,
388
                                            null // create as needed
389
                                            );
390
    return colorModel.getRGB(rgbElem);
391
  }
392
 
393
  public int[] getRGB(int startX, int startY, int w, int h,
394
                      int[] rgbArray,
395
                      int offset, int scanlineStride)
396
  {
397
    if (rgbArray == null)
398
    {
399
      /*
400
        000000000000000000
401
        00000[#######-----   [ = start
402
        -----########-----   ] = end
403
        -----#######]00000
404
        000000000000000000  */
405
      int size = (h-1)*scanlineStride + w;
406
      rgbArray = new int[size];
407
    }
408
 
409
    int endX = startX + w;
410
    int endY = startY + h;
411
 
412
    /* *TODO*:
413
       Opportunity for optimization by examining color models...
414
 
415
       Perhaps wrap the rgbArray up in a WritableRaster with packed
416
       sRGB color model and perform optimized rendering into the
417
       array. */
418
 
419
    Object rgbElem = null;
420
    for (int y=startY; y<endY; y++)
421
      {
422
        int xoffset = offset;
423
        for (int x=startX; x<endX; x++)
424
          {
425
            int rgb;
426
            rgbElem = raster.getDataElements(x, y, rgbElem);
427
            rgb = colorModel.getRGB(rgbElem);
428
            rgbArray[xoffset++] = rgb;
429
          }
430
        offset += scanlineStride;
431
      }
432
    return rgbArray;
433
  }
434
 
435
  public WritableRaster getRaster()
436
  {
437
    return raster;
438
  }
439
 
440
  public SampleModel getSampleModel()
441
  {
442
    return raster.getSampleModel();
443
  }
444
 
445
  public ImageProducer getSource()
446
  {
447
    return new ImageProducer() {
448
 
449
        Vector consumers = new Vector();
450
 
451
        public void addConsumer(ImageConsumer ic)
452
        {
453
          if(!consumers.contains(ic))
454
            consumers.add(ic);
455
        }
456
 
457
        public boolean isConsumer(ImageConsumer ic)
458
        {
459
          return consumers.contains(ic);
460
        }
461
 
462
        public void removeConsumer(ImageConsumer ic)
463
        {
464
          consumers.remove(ic);
465
        }
466
 
467
        public void startProduction(ImageConsumer ic)
468
        {
469
          int x = 0;
470
          int y = 0;
471
          int width = getWidth();
472
          int height = getHeight();
473
          int stride = width;
474
          int offset = 0;
475
          int[] pixels = getRGB(x, y,
476
                                width, height,
477
                                (int[])null, offset, stride);
478
          ColorModel model = getColorModel();
479
 
480
          consumers.add(ic);
481
 
482
          for(int i=0;i<consumers.size();i++)
483
            {
484
              ImageConsumer c = (ImageConsumer) consumers.elementAt(i);
485
              c.setHints(ImageConsumer.SINGLEPASS);
486
              c.setDimensions(getWidth(), getHeight());
487
              c.setPixels(x, y, width, height, model, pixels, offset, stride);
488
              c.imageComplete(ImageConsumer.STATICIMAGEDONE);
489
            }
490
        }
491
 
492
        public void requestTopDownLeftRightResend(ImageConsumer ic)
493
        {
494
          startProduction(ic);
495
        }
496
 
497
      };
498
  }
499
 
500
  public Vector getSources()
501
  {
502
    return null;
503
  }
504
 
505
  public BufferedImage getSubimage(int x, int y, int w, int h)
506
  {
507
    WritableRaster subRaster =
508
      getRaster().createWritableChild(x, y, w, h, 0, 0, null);
509
 
510
    return new BufferedImage(getColorModel(),
511
                             subRaster,
512
                             isPremultiplied,
513
                             properties);
514
  }
515
 
516
  public Raster getTile(int tileX, int tileY)
517
  {
518
    return getWritableTile(tileX, tileY);
519
  }
520
 
521
  public int getTileGridXOffset()
522
  {
523
    return 0; // according to javadocs
524
  }
525
 
526
  public int getTileGridYOffset()
527
  {
528
    return 0; // according to javadocs
529
  }
530
 
531
  public int getTileHeight()
532
  {
533
    return getHeight(); // image is one big tile
534
  }
535
 
536
  public int getTileWidth()
537
  {
538
    return getWidth(); // image is one big tile
539
  }
540
 
541
  public int getType()
542
  {
543
    return type;
544
  }
545
 
546
  public int getWidth()
547
  {
548
    return raster.getWidth();
549
  }
550
 
551
  public int getWidth(ImageObserver imageobserver)
552
  {
553
    return getWidth();
554
  }
555
 
556
  public WritableRaster getWritableTile(int tileX, int tileY)
557
  {
558
    isTileWritable(tileX, tileY);  // for exception
559
    return raster;
560
  }
561
 
562
  private static final Point[] tileIndices = { new Point() };
563
 
564
  public Point[] getWritableTileIndices()
565
  {
566
    return tileIndices;
567
  }
568
 
569
  public boolean hasTileWriters()
570
  {
571
    return true;
572
  }
573
 
574
  public boolean isAlphaPremultiplied()
575
  {
576
    return isPremultiplied;
577
  }
578
 
579
  public boolean isTileWritable(int tileX, int tileY)
580
  {
581
    if ((tileX != 0) || (tileY != 0))
582
      throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
583
    return true;
584
  }
585
 
586
  public void releaseWritableTile(int tileX, int tileY)
587
  {
588
    isTileWritable(tileX, tileY);  // for exception
589
  }
590
 
591
  //public void removeTileObserver(TileObserver tileobserver) {}
592
 
593
  public void setData(Raster src)
594
  {
595
    int x = src.getMinX();
596
    int y = src.getMinY();
597
    int w = src.getWidth();
598
    int h = src.getHeight();
599
 
600
    // create a dest child that has the right bounds...
601
    WritableRaster dest =
602
      raster.createWritableChild(x, y, w, h, x, y,
603
                                 null  // same bands
604
                                 );
605
 
606
    if (src.getSampleModel () instanceof ComponentSampleModel
607
        && dest.getSampleModel () instanceof ComponentSampleModel)
608
 
609
      // Refer to ComponentDataBlitOp for optimized data blitting:
610
      ComponentDataBlitOp.INSTANCE.filter(src, dest);
611
    else
612
      {
613
        // slower path
614
        int samples[] = src.getPixels (x, y, w, h, (int [])null);
615
        dest.setPixels (x, y, w, h, samples);
616
      }
617
  }
618
 
619
  public void setRGB(int x, int y, int argb)
620
  {
621
    Object rgbElem = colorModel.getDataElements(argb, null);
622
    raster.setDataElements(x, y, rgbElem);
623
  }
624
 
625
  public void setRGB(int startX, int startY, int w, int h,
626
                     int[] argbArray, int offset, int scanlineStride)
627
  {
628
    int endX = startX + w;
629
    int endY = startY + h;
630
 
631
    Object rgbElem = null;
632
    for (int y=startY; y<endY; y++)
633
      {
634
        int xoffset = offset;
635
        for (int x=startX; x<endX; x++)
636
          {
637
            int argb = argbArray[xoffset++];
638
            rgbElem = colorModel.getDataElements(argb, rgbElem);
639
            raster.setDataElements(x, y, rgbElem);
640
          }
641
        offset += scanlineStride;
642
      }
643
  }
644
 
645
  public String toString()
646
  {
647
    StringBuffer buf;
648
 
649
    buf = new StringBuffer(/* estimated length */ 120);
650
    buf.append("BufferedImage@");
651
    buf.append(Integer.toHexString(hashCode()));
652
    buf.append(": type=");
653
    buf.append(type);
654
    buf.append(' ');
655
    buf.append(colorModel);
656
    buf.append(' ');
657
    buf.append(raster);
658
 
659
    return buf.toString();
660
  }
661
 
662
 
663
  /**
664
   * Adds a tile observer. If the observer is already present, it receives
665
   * multiple notifications.
666
   *
667
   * @param to The TileObserver to add.
668
   */
669
  public void addTileObserver (TileObserver to)
670
  {
671
    if (observers == null)
672
      observers = new Vector ();
673
 
674
    observers.add (to);
675
  }
676
 
677
  /**
678
   * Removes a tile observer. If the observer was not registered,
679
   * nothing happens. If the observer was registered for multiple
680
   * notifications, it is now registered for one fewer notification.
681
   *
682
   * @param to The TileObserver to remove.
683
   */
684
  public void removeTileObserver (TileObserver to)
685
  {
686
    if (observers == null)
687
      return;
688
 
689
    observers.remove (to);
690
  }
691
 
692
  /**
693
   * Return the transparency type.
694
   *
695
   * @return One of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}.
696
   * @see Transparency#getTransparency()
697
   * @since 1.5
698
   */
699
  public int getTransparency()
700
  {
701
    return colorModel.getTransparency();
702
  }
703
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.