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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [peer/] [gtk/] [GdkPixbufDecoder.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* GdkPixbufDecoder.java -- Image data decoding object
2
   Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
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 gnu.java.awt.peer.gtk;
40
 
41
import gnu.classpath.Configuration;
42
 
43
import java.awt.image.BufferedImage;
44
import java.awt.image.ColorModel;
45
import java.awt.image.DirectColorModel;
46
import java.awt.image.ImageConsumer;
47
import java.awt.image.ImageProducer;
48
import java.awt.image.Raster;
49
import java.awt.image.RenderedImage;
50
import java.io.DataOutput;
51
import java.io.IOException;
52
import java.io.InputStream;
53
import java.net.URL;
54
import java.util.ArrayList;
55
import java.util.Hashtable;
56
import java.util.Iterator;
57
import java.util.Locale;
58
import java.util.Vector;
59
 
60
import javax.imageio.IIOImage;
61
import javax.imageio.ImageReadParam;
62
import javax.imageio.ImageReader;
63
import javax.imageio.ImageTypeSpecifier;
64
import javax.imageio.ImageWriteParam;
65
import javax.imageio.ImageWriter;
66
import javax.imageio.metadata.IIOMetadata;
67
import javax.imageio.spi.IIORegistry;
68
import javax.imageio.spi.ImageReaderSpi;
69
import javax.imageio.spi.ImageWriterSpi;
70
import javax.imageio.stream.ImageInputStream;
71
import javax.imageio.stream.ImageOutputStream;
72
 
73
public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
74
{
75
  static
76
  {
77
    if (Configuration.INIT_LOAD_LIBRARY)
78
      {
79
        System.loadLibrary("gtkpeer");
80
      }
81
    initStaticState ();
82
  }
83
 
84
  static native void initStaticState();
85
  private final int native_state = GtkGenericPeer.getUniqueInteger ();
86
 
87
  // initState() has been called, but pumpDone() has not yet been called.
88
  private boolean needsClose = false;
89
 
90
  // the current set of ImageConsumers for this decoder
91
  Vector curr;
92
 
93
  // interface to GdkPixbuf
94
  native void initState ();
95
  native void pumpBytes (byte[] bytes, int len) throws IOException;
96
  native void pumpDone () throws IOException;
97
  native void finish (boolean needsClose);
98
  static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink);
99
 
100
  // gdk-pixbuf provids data in RGBA format
101
  static final ColorModel cm = new DirectColorModel (32, 0xff000000,
102
                                                     0x00ff0000,
103
                                                     0x0000ff00,
104
                                                     0x000000ff);
105
  public GdkPixbufDecoder (InputStream in)
106
  {
107
    super (in);
108
  }
109
 
110
  public GdkPixbufDecoder (String filename)
111
  {
112
    super (filename);
113
  }
114
 
115
  public GdkPixbufDecoder (URL url)
116
  {
117
    super (url);
118
  }
119
 
120
  public GdkPixbufDecoder (byte[] imagedata, int imageoffset, int imagelength)
121
  {
122
    super (imagedata, imageoffset, imagelength);
123
  }
124
 
125
  // called back by native side: area_prepared_cb
126
  void areaPrepared (int width, int height)
127
  {
128
 
129
    if (curr == null)
130
      return;
131
 
132
    for (int i = 0; i < curr.size (); i++)
133
      {
134
        ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
135
        ic.setDimensions (width, height);
136
        ic.setColorModel (cm);
137
        ic.setHints (ImageConsumer.RANDOMPIXELORDER);
138
      }
139
  }
140
 
141
  // called back by native side: area_updated_cb
142
  void areaUpdated (int x, int y, int width, int height,
143
                    int pixels[], int scansize)
144
  {
145
    if (curr == null)
146
      return;
147
 
148
    for (int i = 0; i < curr.size (); i++)
149
      {
150
        ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
151
        ic.setPixels (x, y, width, height, cm, pixels, 0, scansize);
152
      }
153
  }
154
 
155
  // called from an async image loader of one sort or another, this method
156
  // repeatedly reads bytes from the input stream and passes them through a
157
  // GdkPixbufLoader using the native method pumpBytes. pumpBytes in turn
158
  // decodes the image data and calls back areaPrepared and areaUpdated on
159
  // this object, feeding back decoded pixel blocks, which we pass to each
160
  // of the ImageConsumers in the provided Vector.
161
 
162
  public void produce (Vector v, InputStream is) throws IOException
163
  {
164
    curr = v;
165
 
166
    byte bytes[] = new byte[4096];
167
    int len = 0;
168
    initState();
169
    needsClose = true;
170
    while ((len = is.read (bytes)) != -1)
171
      pumpBytes (bytes, len);
172
    pumpDone();
173
    needsClose = false;
174
 
175
    for (int i = 0; i < curr.size (); i++)
176
      {
177
        ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
178
        ic.imageComplete (ImageConsumer.STATICIMAGEDONE);
179
      }
180
 
181
    curr = null;
182
  }
183
 
184
  public void finalize()
185
  {
186
    finish(needsClose);
187
  }
188
 
189
 
190
  public static class ImageFormatSpec
191
  {
192
    public String name;
193
    public boolean writable = false;
194
    public ArrayList mimeTypes = new ArrayList();
195
    public ArrayList extensions = new ArrayList();
196
 
197
    public ImageFormatSpec(String name, boolean writable)
198
    {
199
      this.name = name;
200
      this.writable = writable;
201
    }
202
 
203
    public synchronized void addMimeType(String m)
204
    {
205
      mimeTypes.add(m);
206
    }
207
 
208
    public synchronized void addExtension(String e)
209
    {
210
      extensions.add(e);
211
    }
212
  }
213
 
214
  static ArrayList imageFormatSpecs;
215
 
216
  public static ImageFormatSpec registerFormat(String name, boolean writable)
217
  {
218
    ImageFormatSpec ifs = new ImageFormatSpec(name, writable);
219
    synchronized(GdkPixbufDecoder.class)
220
      {
221
        if (imageFormatSpecs == null)
222
          imageFormatSpecs = new ArrayList();
223
        imageFormatSpecs.add(ifs);
224
      }
225
    return ifs;
226
  }
227
 
228
  static String[] getFormatNames(boolean writable)
229
  {
230
    ArrayList names = new ArrayList();
231
    synchronized (imageFormatSpecs)
232
      {
233
        Iterator i = imageFormatSpecs.iterator();
234
        while (i.hasNext())
235
          {
236
            ImageFormatSpec ifs = (ImageFormatSpec) i.next();
237
            if (writable && !ifs.writable)
238
              continue;
239
            names.add(ifs.name);
240
 
241
            /*
242
             * In order to make the filtering code work, we need to register
243
             * this type under every "format name" likely to be used as a synonym.
244
             * This generally means "all the extensions people might use".
245
             */
246
 
247
            Iterator j = ifs.extensions.iterator();
248
            while (j.hasNext())
249
              names.add((String) j.next());
250
          }
251
      }
252
    Object[] objs = names.toArray();
253
    String[] strings = new String[objs.length];
254
    for (int i = 0; i < objs.length; ++i)
255
      strings[i] = (String) objs[i];
256
    return strings;
257
  }
258
 
259
  static String[] getFormatExtensions(boolean writable)
260
  {
261
    ArrayList extensions = new ArrayList();
262
    synchronized (imageFormatSpecs)
263
      {
264
        Iterator i = imageFormatSpecs.iterator();
265
        while (i.hasNext())
266
          {
267
            ImageFormatSpec ifs = (ImageFormatSpec) i.next();
268
            if (writable && !ifs.writable)
269
              continue;
270
            Iterator j = ifs.extensions.iterator();
271
            while (j.hasNext())
272
              extensions.add((String) j.next());
273
          }
274
      }
275
    Object[] objs = extensions.toArray();
276
    String[] strings = new String[objs.length];
277
    for (int i = 0; i < objs.length; ++i)
278
      strings[i] = (String) objs[i];
279
    return strings;
280
  }
281
 
282
  static String[] getFormatMimeTypes(boolean writable)
283
  {
284
    ArrayList mimeTypes = new ArrayList();
285
    synchronized (imageFormatSpecs)
286
      {
287
        Iterator i = imageFormatSpecs.iterator();
288
        while (i.hasNext())
289
          {
290
            ImageFormatSpec ifs = (ImageFormatSpec) i.next();
291
            if (writable && !ifs.writable)
292
              continue;
293
            Iterator j = ifs.mimeTypes.iterator();
294
            while (j.hasNext())
295
              mimeTypes.add((String) j.next());
296
          }
297
      }
298
    Object[] objs = mimeTypes.toArray();
299
    String[] strings = new String[objs.length];
300
    for (int i = 0; i < objs.length; ++i)
301
      strings[i] = (String) objs[i];
302
    return strings;
303
  }
304
 
305
 
306
  static String findFormatName(Object ext, boolean needWritable)
307
  {
308
    if (ext == null)
309
      return null;
310
 
311
    if (!(ext instanceof String))
312
      throw new IllegalArgumentException("extension is not a string");
313
 
314
    String str = (String) ext;
315
 
316
    Iterator i = imageFormatSpecs.iterator();
317
    while (i.hasNext())
318
      {
319
        ImageFormatSpec ifs = (ImageFormatSpec) i.next();
320
 
321
        if (needWritable && !ifs.writable)
322
          continue;
323
 
324
        if (ifs.name.equals(str))
325
          return str;
326
 
327
        Iterator j = ifs.extensions.iterator();
328
        while (j.hasNext())
329
          {
330
            String extension = (String)j.next();
331
            if (extension.equals(str))
332
              return ifs.name;
333
          }
334
 
335
        j = ifs.mimeTypes.iterator();
336
        while (j.hasNext())
337
          {
338
            String mimeType = (String)j.next();
339
            if (mimeType.equals(str))
340
              return ifs.name;
341
          }
342
      }
343
    throw new IllegalArgumentException("unknown extension '" + str + "'");
344
  }
345
 
346
  private static GdkPixbufReaderSpi readerSpi;
347
  private static GdkPixbufWriterSpi writerSpi;
348
 
349
  public static synchronized GdkPixbufReaderSpi getReaderSpi()
350
  {
351
    if (readerSpi == null)
352
      readerSpi = new GdkPixbufReaderSpi();
353
    return readerSpi;
354
  }
355
 
356
  public static synchronized GdkPixbufWriterSpi getWriterSpi()
357
  {
358
    if (writerSpi == null)
359
      writerSpi = new GdkPixbufWriterSpi();
360
    return writerSpi;
361
  }
362
 
363
  public static void registerSpis(IIORegistry reg)
364
  {
365
    reg.registerServiceProvider(getReaderSpi(), ImageReaderSpi.class);
366
    reg.registerServiceProvider(getWriterSpi(), ImageWriterSpi.class);
367
  }
368
 
369
  public static class GdkPixbufWriterSpi extends ImageWriterSpi
370
  {
371
    public GdkPixbufWriterSpi()
372
    {
373
      super("GdkPixbuf", "2.x",
374
            GdkPixbufDecoder.getFormatNames(true),
375
            GdkPixbufDecoder.getFormatExtensions(true),
376
            GdkPixbufDecoder.getFormatMimeTypes(true),
377
            "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriter",
378
            new Class[] { ImageOutputStream.class },
379
            new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReaderSpi" },
380
            false, null, null, null, null,
381
            false, null, null, null, null);
382
    }
383
 
384
    public boolean canEncodeImage(ImageTypeSpecifier ts)
385
    {
386
      return true;
387
    }
388
 
389
    public ImageWriter createWriterInstance(Object ext)
390
    {
391
      return new GdkPixbufWriter(this, ext);
392
    }
393
 
394
    public String getDescription(java.util.Locale loc)
395
    {
396
      return "GdkPixbuf Writer SPI";
397
    }
398
 
399
  }
400
 
401
  public static class GdkPixbufReaderSpi extends ImageReaderSpi
402
  {
403
    public GdkPixbufReaderSpi()
404
    {
405
      super("GdkPixbuf", "2.x",
406
            GdkPixbufDecoder.getFormatNames(false),
407
            GdkPixbufDecoder.getFormatExtensions(false),
408
            GdkPixbufDecoder.getFormatMimeTypes(false),
409
            "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReader",
410
            new Class[] { ImageInputStream.class },
411
            new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriterSpi" },
412
            false, null, null, null, null,
413
            false, null, null, null, null);
414
    }
415
 
416
    public boolean canDecodeInput(Object obj)
417
    {
418
      return true;
419
    }
420
 
421
    public ImageReader createReaderInstance(Object ext)
422
    {
423
      return new GdkPixbufReader(this, ext);
424
    }
425
 
426
    public String getDescription(Locale loc)
427
    {
428
      return "GdkPixbuf Reader SPI";
429
    }
430
  }
431
 
432
  private static class GdkPixbufWriter
433
    extends ImageWriter
434
  {
435
    String ext;
436
    public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext)
437
    {
438
      super(ownerSpi);
439
      this.ext = findFormatName(ext, true);
440
    }
441
 
442
    public IIOMetadata convertImageMetadata (IIOMetadata inData,
443
                                             ImageTypeSpecifier imageType,
444
                                             ImageWriteParam param)
445
    {
446
      return null;
447
    }
448
 
449
    public IIOMetadata convertStreamMetadata (IIOMetadata inData,
450
                                              ImageWriteParam param)
451
    {
452
      return null;
453
    }
454
 
455
    public IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType,
456
                                                ImageWriteParam param)
457
    {
458
      return null;
459
    }
460
 
461
    public IIOMetadata getDefaultStreamMetadata (ImageWriteParam param)
462
    {
463
      return null;
464
    }
465
 
466
  public void write (IIOMetadata streamMetadata, IIOImage i, ImageWriteParam param)
467
    throws IOException
468
    {
469
      RenderedImage image = i.getRenderedImage();
470
      Raster ras = image.getData();
471
      int width = ras.getWidth();
472
      int height = ras.getHeight();
473
      ColorModel model = image.getColorModel();
474
      int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
475
 
476
      if (pixels == null)
477
        {
478
          BufferedImage img = new BufferedImage(width, height,
479
                                                (model != null && model.hasAlpha() ?
480
                                                 BufferedImage.TYPE_INT_ARGB
481
                                                 : BufferedImage.TYPE_INT_RGB));
482
          int[] pix = new int[4];
483
          for (int y = 0; y < height; ++y)
484
            for (int x = 0; x < width; ++x)
485
              img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix)));
486
          pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(),
487
                                                         img.getRaster());
488
          model = img.getColorModel();
489
        }
490
 
491
      processImageStarted(1);
492
      streamImage(pixels, this.ext, width, height, model.hasAlpha(),
493
                  (DataOutput) this.getOutput());
494
      processImageComplete();
495
    }
496
  }
497
 
498
  private static class GdkPixbufReader
499
    extends ImageReader
500
    implements ImageConsumer
501
  {
502
    // ImageConsumer parts
503
    GdkPixbufDecoder dec;
504
    BufferedImage bufferedImage;
505
    ColorModel defaultModel;
506
    int width;
507
    int height;
508
    String ext;
509
 
510
    public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext)
511
    {
512
      super(ownerSpi);
513
      this.ext = findFormatName(ext, false);
514
    }
515
 
516
    public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext, GdkPixbufDecoder d)
517
    {
518
      this(ownerSpi, ext);
519
      dec = d;
520
    }
521
 
522
    public void setDimensions(int w, int h)
523
    {
524
      processImageStarted(1);
525
      width = w;
526
      height = h;
527
    }
528
 
529
    public void setProperties(Hashtable props) {}
530
 
531
    public void setColorModel(ColorModel model)
532
    {
533
      defaultModel = model;
534
    }
535
 
536
    public void setHints(int flags) {}
537
 
538
    public void setPixels(int x, int y, int w, int h,
539
                          ColorModel model, byte[] pixels,
540
                          int offset, int scansize)
541
    {
542
    }
543
 
544
    public void setPixels(int x, int y, int w, int h,
545
                          ColorModel model, int[] pixels,
546
                          int offset, int scansize)
547
    {
548
      if (model == null)
549
        model = defaultModel;
550
 
551
      if (bufferedImage == null)
552
        {
553
          bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ?
554
                                                             BufferedImage.TYPE_INT_ARGB
555
                                                             : BufferedImage.TYPE_INT_RGB));
556
        }
557
 
558
      int pixels2[];
559
      if (model != null)
560
        {
561
          pixels2 = new int[pixels.length];
562
          for (int yy = 0; yy < h; yy++)
563
            for (int xx = 0; xx < w; xx++)
564
              {
565
                int i = yy * scansize + xx;
566
                pixels2[i] = model.getRGB (pixels[i]);
567
              }
568
        }
569
      else
570
        pixels2 = pixels;
571
 
572
      bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize);
573
      processImageProgress(y / (height == 0 ? 1 : height));
574
    }
575
 
576
    public void imageComplete(int status)
577
    {
578
      processImageComplete();
579
    }
580
 
581
    public BufferedImage getBufferedImage()
582
    {
583
      if (bufferedImage == null && dec != null)
584
        dec.startProduction (this);
585
      return bufferedImage;
586
    }
587
 
588
    // ImageReader parts
589
 
590
    public int getNumImages(boolean allowSearch)
591
      throws IOException
592
    {
593
      return 1;
594
    }
595
 
596
    public IIOMetadata getImageMetadata(int i)
597
    {
598
      return null;
599
    }
600
 
601
    public IIOMetadata getStreamMetadata()
602
      throws IOException
603
    {
604
      return null;
605
    }
606
 
607
    public Iterator getImageTypes(int imageIndex)
608
      throws IOException
609
    {
610
      BufferedImage img = getBufferedImage();
611
      Vector vec = new Vector();
612
      vec.add(new ImageTypeSpecifier(img));
613
      return vec.iterator();
614
    }
615
 
616
    public int getHeight(int imageIndex)
617
      throws IOException
618
    {
619
      return getBufferedImage().getHeight();
620
    }
621
 
622
    public int getWidth(int imageIndex)
623
      throws IOException
624
    {
625
      return getBufferedImage().getWidth();
626
    }
627
 
628
    public void setInput(Object input,
629
                         boolean seekForwardOnly,
630
                         boolean ignoreMetadata)
631
    {
632
      super.setInput(input, seekForwardOnly, ignoreMetadata);
633
      dec = new GdkPixbufDecoder((InputStream) getInput());
634
    }
635
 
636
    public BufferedImage read(int imageIndex, ImageReadParam param)
637
      throws IOException
638
    {
639
      return getBufferedImage ();
640
    }
641
  }
642
 
643
  // remaining helper class and static method is a convenience for the Gtk
644
  // peers, for loading a BufferedImage in off a disk file without going
645
  // through the whole imageio system. 
646
 
647
  public static BufferedImage createBufferedImage (String filename)
648
  {
649
    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
650
                                             "png", // reader auto-detects, doesn't matter
651
                                             new GdkPixbufDecoder (filename));
652
    return r.getBufferedImage ();
653
  }
654
 
655
  public static BufferedImage createBufferedImage (URL u)
656
  {
657
    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
658
                                             "png", // reader auto-detects, doesn't matter
659
                                             new GdkPixbufDecoder (u));
660
    return r.getBufferedImage ();
661
  }
662
 
663
  public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
664
                                                   int imagelength)
665
  {
666
    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
667
                                             "png", // reader auto-detects, doesn't matter
668
                                             new GdkPixbufDecoder (imagedata,
669
                                                                   imageoffset,
670
                                                                   imagelength));
671
    return r.getBufferedImage ();
672
  }
673
 
674
  public static BufferedImage createBufferedImage (ImageProducer producer)
675
  {
676
    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null);
677
    producer.startProduction(r);
678
    return r.getBufferedImage ();
679
  }
680
 
681
}

powered by: WebSVN 2.1.0

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