4 import java.awt.image.*;
18 private static String defaultDirectory;
20 public void run(String path) {
23 BMPDecoder bmp =
new BMPDecoder();
24 FileInputStream is = null;
26 is =
new FileInputStream(path);
30 String msg = e.getMessage();
31 if (msg==null || msg.equals(
""))
37 MemoryImageSource mis = bmp.makeImageSource();
38 if (mis==null)
IJ.
write(
"mis=null");
39 Image img = Toolkit.getDefaultToolkit().createImage(mis);
40 FileInfo fi =
new FileInfo();
41 fi.fileFormat = FileInfo.BMP;
42 File fp =
new File(path);
43 fi.fileName = fp.getName();
44 fi.directory = fp.getParent();
66 int actualSizeOfBitmap;
77 private int readInt() throws IOException {
83 return ((b4 << 24) + (b3 << 16) + (b2 << 8) + (b1 << 0));
87 private short readShort() throws IOException {
91 return (
short)((b2 << 8) + b1);
95 void getFileHeader() throws IOException, Exception {
97 short fileType = 0x4d42;
102 fileType = readShort();
103 if (fileType != 0x4d42)
104 throw new Exception(
"Not a BMP file");
105 fileSize = readInt();
106 reserved1 = readShort();
107 reserved2 = readShort();
108 bitmapOffset = readInt();
111 void getBitmapHeader() throws IOException {
127 planes = readShort();
128 bitsPerPixel = readShort();
129 compression = readInt();
130 sizeOfBitmap = readInt();
131 horzResolution = readInt();
132 vertResolution = readInt();
133 colorsUsed = readInt();
134 colorsImportant = readInt();
136 topDown = (height < 0);
137 noOfPixels = width * height;
140 scanLineSize = ((width * bitsPerPixel + 31) / 32) * 4;
142 if (sizeOfBitmap != 0)
143 actualSizeOfBitmap = sizeOfBitmap;
146 actualSizeOfBitmap = scanLineSize * height;
149 actualColorsUsed = colorsUsed;
152 if (bitsPerPixel < 16)
153 actualColorsUsed = 1 << bitsPerPixel;
155 actualColorsUsed = 0;
158 void getPalette() throws IOException {
159 noOfEntries = actualColorsUsed;
162 r =
new byte[noOfEntries];
163 g =
new byte[noOfEntries];
164 b =
new byte[noOfEntries];
167 for (
int i = 0; i < noOfEntries; i++) {
168 b[i] = (byte)is.read();
169 g[i] = (byte)is.read();
170 r[i] = (byte)is.read();
171 reserved = is.read();
177 void unpack(byte[] rawData,
int rawOffset,
int bpp, byte[] byteData,
int byteOffset,
int w)
throws Exception {
184 case 1: mask = (byte)0x01; pixPerByte = 8;
break;
185 case 4: mask = (byte)0x0f; pixPerByte = 2;
break;
186 case 8: mask = (byte)0xff; pixPerByte = 1;
break;
188 throw new Exception(
"Unsupported bits-per-pixel value: " + bpp);
193 for (
int ii = 0; ii < pixPerByte; ii++) {
194 byte br = rawData[k];
196 byteData[j] = (byte)(br & mask);
206 void unpack24(byte[] rawData,
int rawOffset,
int[] intData,
int intOffset,
int w) {
210 for (
int i = 0; i < w; i++) {
211 int b0 = (((int)(rawData[k++])) & mask);
212 int b1 = (((int)(rawData[k++])) & mask) << 8;
213 int b2 = (((int)(rawData[k++])) & mask) << 16;
214 intData[j] = 0xff000000 | b0 | b1 | b2;
219 void unpack32(byte[] rawData,
int rawOffset,
int[] intData,
int intOffset,
int w) {
223 for (
int i = 0; i < w; i++) {
224 int b0 = (((int)(rawData[k++])) & mask);
225 int b1 = (((int)(rawData[k++])) & mask) << 8;
226 int b2 = (((int)(rawData[k++])) & mask) << 16;
227 int b3 = (((int)(rawData[k++])) & mask) << 24;
228 intData[j] = 0xff000000 | b0 | b1 | b2;
233 void getPixelData() throws IOException, Exception {
237 long skip = bitmapOffset - curPos;
243 int len = scanLineSize;
244 if (bitsPerPixel > 8)
245 intData =
new int[width * height];
247 byteData =
new byte[width * height];
248 rawData =
new byte[actualSizeOfBitmap];
250 int offset = (height - 1) * width;
251 for (
int i = height - 1; i >= 0; i--) {
252 int n = is.read(rawData, rawOffset, len);
253 if (n < len)
throw new Exception(
"Scan line ended prematurely after " + n +
" bytes");
254 if (bitsPerPixel==24)
255 unpack24(rawData, rawOffset, intData, offset, width);
256 else if (bitsPerPixel==32)
257 unpack32( rawData, rawOffset, intData, offset, width);
259 unpack(rawData, rawOffset, bitsPerPixel, byteData, offset, width);
266 public void read(InputStream is)
throws IOException, Exception {
271 throw new Exception(
"Compression not supported");
277 public MemoryImageSource makeImageSource() {
279 MemoryImageSource mis;
281 if (noOfEntries > 0) {
283 cm =
new IndexColorModel(bitsPerPixel,
284 noOfEntries, r, g, b);
287 cm = ColorModel.getRGBdefault();
292 if (bitsPerPixel > 8) {
294 mis =
new MemoryImageSource(width,
295 height, cm, intData, 0, width);
298 mis =
new MemoryImageSource(width,
299 height, cm, byteData, 0, width);