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