001: /*
002: * Copyright 1995-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*-
027: * Reads xbitmap format images into a DIBitmap structure.
028: */
029: package sun.awt.image;
030:
031: import java.io.*;
032: import java.awt.image.*;
033:
034: /**
035: * Parse files of the form:
036: *
037: * #define foo_width w
038: * #define foo_height h
039: * static char foo_bits[] = {
040: * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,
041: * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,
042: * 0xnn,0xnn,0xnn,0xnn};
043: *
044: * @version 1.26 05/05/07
045: * @author James Gosling
046: */
047: public class XbmImageDecoder extends ImageDecoder {
048: private static byte XbmColormap[] = { (byte) 255, (byte) 255,
049: (byte) 255, 0, 0, 0 };
050: private static int XbmHints = (ImageConsumer.TOPDOWNLEFTRIGHT
051: | ImageConsumer.COMPLETESCANLINES
052: | ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
053:
054: public XbmImageDecoder(InputStreamImageSource src, InputStream is) {
055: super (src, is);
056: if (!(input instanceof BufferedInputStream)) {
057: // If the topmost stream is a metered stream,
058: // we take forever to decode the image...
059: input = new BufferedInputStream(input, 80);
060: }
061: }
062:
063: /**
064: * An error has occurred. Throw an exception.
065: */
066: private static void error(String s1) throws ImageFormatException {
067: throw new ImageFormatException(s1);
068: }
069:
070: /**
071: * produce an image from the stream.
072: */
073: public void produceImage() throws IOException, ImageFormatException {
074: char nm[] = new char[80];
075: int c;
076: int i = 0;
077: int state = 0;
078: int H = 0;
079: int W = 0;
080: int x = 0;
081: int y = 0;
082: boolean start = true;
083: byte raster[] = null;
084: IndexColorModel model = null;
085: while (!aborted && (c = input.read()) != -1) {
086: if ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
087: || '0' <= c && c <= '9' || c == '#' || c == '_') {
088: if (i < 78)
089: nm[i++] = (char) c;
090: } else if (i > 0) {
091: int nc = i;
092: i = 0;
093: if (start) {
094: if (nc != 7 || nm[0] != '#' || nm[1] != 'd'
095: || nm[2] != 'e' || nm[3] != 'f'
096: || nm[4] != 'i' || nm[5] != 'n'
097: || nm[6] != 'e') {
098: error("Not an XBM file");
099: }
100: start = false;
101: }
102: if (nm[nc - 1] == 'h')
103: state = 1; /* expecting width */
104: else if (nm[nc - 1] == 't' && nc > 1
105: && nm[nc - 2] == 'h')
106: state = 2; /* expecting height */
107: else if (nc > 2 && state < 0 && nm[0] == '0'
108: && nm[1] == 'x') {
109: int n = 0;
110: for (int p = 2; p < nc; p++) {
111: c = nm[p];
112: if ('0' <= c && c <= '9')
113: c = c - '0';
114: else if ('A' <= c && c <= 'Z')
115: c = c - 'A' + 10;
116: else if ('a' <= c && c <= 'z')
117: c = c - 'a' + 10;
118: else
119: c = 0;
120: n = n * 16 + c;
121: }
122: for (int mask = 1; mask <= 0x80; mask <<= 1) {
123: if (x < W) {
124: if ((n & mask) != 0)
125: raster[x] = 1;
126: else
127: raster[x] = 0;
128: }
129: x++;
130: }
131: if (x >= W) {
132: if (setPixels(0, y, W, 1, model, raster, 0, W) <= 0) {
133: return;
134: }
135: x = 0;
136: if (y++ >= H) {
137: break;
138: }
139: }
140: } else {
141: int n = 0;
142: for (int p = 0; p < nc; p++)
143: if ('0' <= (c = nm[p]) && c <= '9')
144: n = n * 10 + c - '0';
145: else {
146: n = -1;
147: break;
148: }
149: if (n > 0 && state > 0) {
150: if (state == 1)
151: W = n;
152: else
153: H = n;
154: if (W == 0 || H == 0)
155: state = 0;
156: else {
157: model = new IndexColorModel(8, 2,
158: XbmColormap, 0, false, 0);
159: setDimensions(W, H);
160: setColorModel(model);
161: setHints(XbmHints);
162: headerComplete();
163: raster = new byte[W];
164: state = -1;
165: }
166: }
167: }
168: }
169: }
170: input.close();
171: imageComplete(ImageConsumer.STATICIMAGEDONE, true);
172: }
173: }
|