123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /*
- * Copyright 1999-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.image;
-
- // Java
- import java.io.IOException;
- import java.awt.color.ColorSpace;
-
- /**
- * Bitmap image.
- * This supports loading a bitmap image into bitmap data.
- *
- * @author Art WELCH
- * @see AbstractFopImage
- * @see FopImage
- */
- public class BmpImage extends AbstractFopImage {
- /**
- * Create a bitmap image with the image data.
- *
- * @param imgInfo the image information
- */
- public BmpImage(FopImage.ImageInfo imgInfo) {
- super(imgInfo);
- }
-
- /**
- * Load the bitmap.
- * This laods the bitmap data from the bitmap image.
- *
- * @return true if it was loaded successfully
- */
- protected boolean loadBitmap() {
- int wpos = 18;
- int hpos = 22; // offset positioning for w and height in bmp files
- int[] headermap = new int[54];
- int filepos = 0;
- byte[] palette = null;
- try {
- boolean eof = false;
- while ((!eof) && (filepos < 54)) {
- int input = inputStream.read();
- if (input == -1) {
- eof = true;
- } else {
- headermap[filepos++] = input;
- }
- }
-
- if (headermap[28] == 4 || headermap[28] == 8) {
- int palettesize = 1 << headermap[28];
- palette = new byte[palettesize * 3];
- int countr = 0;
- while (!eof && countr < palettesize) {
- int count2 = 2;
- while (!eof && count2 >= -1) {
- int input = inputStream.read();
- if (input == -1) {
- eof = true;
- } else if (count2 >= 0) {
- palette[countr * 3 + count2] = (byte)(input & 0xFF);
- }
- count2--;
- filepos++;
- }
- countr++;
- }
- }
- } catch (IOException e) {
- log.error("Error while loading image "
- + "" + " : "
- + e.getClass() + " - "
- + e.getMessage(), e);
- return false;
- }
- // gets h & w from headermap
- this.width = headermap[wpos]
- + headermap[wpos + 1] * 256
- + headermap[wpos + 2] * 256 * 256
- + headermap[wpos + 3] * 256 * 256 * 256;
- this.height = headermap[hpos]
- + headermap[hpos + 1] * 256
- + headermap[hpos + 2] * 256 * 256
- + headermap[hpos + 3] * 256 * 256 * 256;
-
- int imagestart = headermap[10]
- + headermap[11] * 256
- + headermap[12] * 256 * 256
- + headermap[13] * 256 * 256 * 256;
- this.bitsPerPixel = headermap[28];
- this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
- int bytes = 0;
- if (this.bitsPerPixel == 1) {
- bytes = (this.width + 7) / 8;
- } else if (this.bitsPerPixel == 24) {
- bytes = this.width * 3;
- } else if (this.bitsPerPixel == 4 || this.bitsPerPixel == 8) {
- bytes = this.width / (8 / this.bitsPerPixel);
- } else {
- log.error("Image (" + ""
- + ") has " + this.bitsPerPixel
- + " which is not a supported BMP format.");
- return false;
- }
- if ((bytes & 0x03) != 0) {
- bytes |= 0x03;
- bytes++;
- }
-
- // Should take care of the ColorSpace and bitsPerPixel
- this.bitmapsSize = this.width * this.height * 3;
- this.bitmaps = new byte[this.bitmapsSize];
-
- int[] temp = new int[bytes * this.height];
- try {
- int input;
- int count = 0;
- inputStream.skip((long)(imagestart - filepos));
- while ((input = inputStream.read()) != -1) {
- if (count >= temp.length) {
- log.warn("Data longer than expected while loading image");
- break;
- } else {
- temp[count++] = input;
- }
- }
- inputStream.close();
- inputStream = null;
- } catch (IOException e) {
- log.error("Error while loading image "
- + "" + " : "
- + e.getClass() + " - "
- + e.getMessage(), e);
- return false;
- }
-
- for (int i = 0; i < this.height; i++) {
- int x = 0;
- int j = 0;
- while (j < bytes) {
- int p = temp[(this.height - i - 1) * bytes + j];
-
- if (this.bitsPerPixel == 24 && x < this.width) {
- int countr = 2;
- do {
- this.bitmaps[3 * (i * this.width + x) + countr] =
- (byte)(temp[(this.height - i - 1)
- * bytes + j] & 0xFF);
- j++;
- } while (--countr >= 0)
- ;
- x++;
- } else if (this.bitsPerPixel == 1) {
- for (int countr = 0;
- countr < 8 && x < this.width; countr++) {
- if ((p & 0x80) != 0) {
- this.bitmaps[3 * (i * this.width + x)] = (byte) 0xFF;
- this.bitmaps[3 * (i * this.width + x) + 1] = (byte) 0xFF;
- this.bitmaps[3 * (i * this.width + x) + 2] = (byte) 0xFF;
- } else {
- this.bitmaps[3 * (i * this.width + x)] = (byte) 0;
- this.bitmaps[3 * (i * this.width + x) + 1] = (byte) 0;
- this.bitmaps[3 * (i * this.width + x) + 2] = (byte) 0;
- }
- p <<= 1;
- x++;
- }
- j++;
- } else if (this.bitsPerPixel == 4) {
- for (int countr = 0;
- countr < 2 && x < this.width; countr++) {
- int pal = ((p & 0xF0) >> 4) * 3;
- this.bitmaps[3 * (i * this.width + x)] = palette[pal];
- this.bitmaps[3 * (i * this.width + x) + 1] = palette[pal + 1];
- this.bitmaps[3 * (i * this.width + x) + 2] = palette[pal + 2];
- p <<= 4;
- x++;
- }
- j++;
- } else if (this.bitsPerPixel == 8) {
- if (x < this.width) {
- p *= 3;
- this.bitmaps[3 * (i * this.width + x)] = palette[p];
- this.bitmaps[3 * (i * this.width + x) + 1] = palette[p + 1];
- this.bitmaps[3 * (i * this.width + x) + 2] = palette[p + 2];
- j++;
- x++;
- } else {
- j = bytes;
- }
- } else {
- j++;
- }
- }
- }
-
- // This seems really strange to me, but I noticed that
- // JimiImage hardcodes bitsPerPixel to 8. If I do not
- // do this Acrobat is unable to read the resultant PDF,
- // so we will hardcode this...
- this.bitsPerPixel = 8;
-
- return true;
- }
-
- }
|