1 /* XBMDecoder.java -- Decodes X-bitmaps
2    Copyright (C) 1999, 2004  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.image;
40 
41 import java.awt.image.ColorModel;
42 import java.awt.image.ImageConsumer;
43 import java.io.BufferedReader;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.InputStreamReader;
47 import java.io.Reader;
48 import java.net.URL;
49 import java.util.StringTokenizer;
50 import java.util.Vector;
51 
52 public class XBMDecoder extends ImageDecoder
53 {
54   BufferedReader reader;
55   static final ColorModel cm = ColorModel.getRGBdefault ();
56   static final int black = 0xff000000;
57   static final int transparent = 0x00000000;
58   static final int masktable[] = { 0x01, 0x02, 0x04, 0x08,
59                                    0x10, 0x20, 0x40, 0x80 };
60 
XBMDecoder(String filename)61   public XBMDecoder (String filename)
62   {
63     super (filename);
64   }
65 
XBMDecoder(URL url)66   public XBMDecoder (URL url)
67   {
68     super (url);
69   }
70 
produce(Vector v, InputStream is)71   public void produce (Vector v, InputStream is) throws IOException
72   {
73     reader = new BufferedReader (new InputStreamReader (is));
74     int width = -1, height = -1;
75 
76     for (int i = 0; i < 2; i++)
77       {
78         String line = reader.readLine ();
79         StringTokenizer st = new StringTokenizer (line);
80 
81         st.nextToken ();                // #define
82         st.nextToken ();                // name_[width|height]
83         if (i == 0)
84           width = Integer.parseInt (st.nextToken (), 10);
85         else
86           height = Integer.parseInt (st.nextToken (), 10);
87       }
88 
89     for (int i = 0; i < v.size (); i++)
90       {
91         ImageConsumer ic = (ImageConsumer) v.elementAt (i);
92 
93         ic.setDimensions (width, height);
94         ic.setColorModel (cm);
95         ic.setHints (ImageConsumer.COMPLETESCANLINES
96                      | ImageConsumer.SINGLEFRAME
97                      | ImageConsumer.SINGLEPASS
98                      | ImageConsumer.TOPDOWNLEFTRIGHT);
99       }
100 
101     /* skip to the byte array */
102     while (reader.read () != '{') { }
103 
104     /* loop through each scanline */
105     for (int line = 0; line < height; line++)
106       {
107         int scanline[] = getScanline (reader, width);
108 
109         for (int i = 0; i < v.size (); i++)
110           {
111             ImageConsumer ic = (ImageConsumer) v.elementAt (i);
112             ic.setPixels (0, 0 + line, width, 1, cm, scanline, 0, width);
113           }
114       }
115 
116     /* tell each ImageConsumer that we're finished */
117     for (int i = 0; i < v.size (); i++)
118       {
119         ImageConsumer ic = (ImageConsumer) v.elementAt (i);
120         ic.imageComplete (ImageConsumer.STATICIMAGEDONE);
121       }
122   }
123 
getScanline(Reader in, int len)124   public static int[] getScanline (Reader in, int len) throws IOException
125   {
126     char byteStr[] = new char[2];
127     int scanline[] = new int[len];
128     int x = 0;
129 
130     while (x < len)
131       {
132         int ch = in.read ();
133         if (ch == '0')
134           {
135             in.read ();         // 'x'
136 
137             byteStr[0] = (char) in.read ();
138             byteStr[1] = (char) in.read ();
139 
140             int byteVal = Integer.parseInt (new String (byteStr), 16);
141 
142             for (int i = 0; i < 8; i++, x++)
143               {
144                 if (x == len)   // condition occurs if bitmap is padded
145                   return scanline;
146 
147                 scanline[x] = ((byteVal & masktable[i]) != 0) ?
148                                black : transparent;
149               }
150           }
151       }
152 
153     return scanline;
154   }
155 }
156