1 /* 2 * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /*- 27 * Reads xbitmap format images into a DIBitmap structure. 28 */ 29 package sun.awt.image; 30 31 import java.io.*; 32 import java.awt.image.*; 33 34 /** 35 * Parse files of the form: 36 * 37 * #define foo_width w 38 * #define foo_height h 39 * static char foo_bits[] = { 40 * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn, 41 * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn, 42 * 0xnn,0xnn,0xnn,0xnn}; 43 * 44 * @author James Gosling 45 */ 46 public class XbmImageDecoder extends ImageDecoder { 47 private static byte[] XbmColormap = {(byte) 255, (byte) 255, (byte) 255, 48 0, 0, 0}; 49 private static int XbmHints = (ImageConsumer.TOPDOWNLEFTRIGHT | 50 ImageConsumer.COMPLETESCANLINES | 51 ImageConsumer.SINGLEPASS | 52 ImageConsumer.SINGLEFRAME); 53 54 public XbmImageDecoder(InputStreamImageSource src, InputStream is) { 55 super(src, is); 56 if (!(input instanceof BufferedInputStream)) { 57 // If the topmost stream is a metered stream, 58 // we take forever to decode the image... 59 input = new BufferedInputStream(input, 80); 60 } 61 } 62 63 64 /** 65 * An error has occurred. Throw an exception. 66 */ 67 private static void error(String s1) throws ImageFormatException { 68 throw new ImageFormatException(s1); 69 } 70 71 /** 72 * produce an image from the stream. 73 */ 74 public void produceImage() throws IOException, ImageFormatException { 75 char[] nm = new char[80]; 76 int c; 77 int i = 0; 78 int state = 0; 79 int H = 0; 80 int W = 0; 81 int x = 0; 82 int y = 0; 83 boolean start = true; 84 byte[] raster = null; 85 IndexColorModel model = null; 86 while (!aborted && (c = input.read()) != -1) { 87 if ('a' <= c && c <= 'z' || 88 'A' <= c && c <= 'Z' || 89 '0' <= c && c <= '9' || c == '#' || c == '_') { 90 if (i < 78) 91 nm[i++] = (char) c; 92 } else if (i > 0) { 93 int nc = i; 94 i = 0; 95 if (start) { 96 if (nc != 7 || 97 nm[0] != '#' || 98 nm[1] != 'd' || 99 nm[2] != 'e' || 100 nm[3] != 'f' || 101 nm[4] != 'i' || 102 nm[5] != 'n' || 103 nm[6] != 'e') 104 { 105 error("Not an XBM file"); 106 } 107 start = false; 108 } 109 if (nm[nc - 1] == 'h') 110 state = 1; /* expecting width */ 111 else if (nm[nc - 1] == 't' && nc > 1 && nm[nc - 2] == 'h') 112 state = 2; /* expecting height */ 113 else if (nc > 2 && state < 0 && nm[0] == '0' && nm[1] == 'x') { 114 int n = 0; 115 for (int p = 2; p < nc; p++) { 116 c = nm[p]; 117 if ('0' <= c && c <= '9') 118 c = c - '0'; 119 else if ('A' <= c && c <= 'Z') 120 c = c - 'A' + 10; 121 else if ('a' <= c && c <= 'z') 122 c = c - 'a' + 10; 123 else 124 c = 0; 125 n = n * 16 + c; 126 } 127 for (int mask = 1; mask <= 0x80; mask <<= 1) { 128 if (x < W) { 129 if ((n & mask) != 0) 130 raster[x] = 1; 131 else 132 raster[x] = 0; 133 } 134 x++; 135 } 136 if (x >= W) { 137 if (setPixels(0, y, W, 1, model, raster, 0, W) <= 0) { 138 return; 139 } 140 x = 0; 141 if (y++ >= H) { 142 break; 143 } 144 } 145 } else { 146 int n = 0; 147 for (int p = 0; p < nc; p++) 148 if ('0' <= (c = nm[p]) && c <= '9') 149 n = n * 10 + c - '0'; 150 else { 151 n = -1; 152 break; 153 } 154 if (n > 0 && state > 0) { 155 if (state == 1) 156 W = n; 157 else 158 H = n; 159 if (W == 0 || H == 0) 160 state = 0; 161 else { 162 model = new IndexColorModel(8, 2, XbmColormap, 163 0, false, 0); 164 setDimensions(W, H); 165 setColorModel(model); 166 setHints(XbmHints); 167 headerComplete(); 168 raster = new byte[W]; 169 state = -1; 170 } 171 } 172 } 173 } 174 } 175 input.close(); 176 imageComplete(ImageConsumer.STATICIMAGEDONE, true); 177 } 178 }