/[classpath]/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
ViewVC logotype

Diff of /classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.1.6.2.1  
changed lines
  Added in v.1.6.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26