You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BmpImage.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * $Id$
  3. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. /**
  8. * FopImage object for BMP images.
  9. * @author Art WELCH
  10. * @see AbstractFopImage
  11. * @see FopImage
  12. */
  13. package org.apache.fop.image;
  14. // Java
  15. import java.net.URL;
  16. import java.io.InputStream;
  17. import java.io.IOException;
  18. // FOP
  19. import org.apache.fop.datatypes.ColorSpace;
  20. import org.apache.fop.pdf.PDFColor;
  21. import org.apache.fop.image.analyser.ImageReader;
  22. import org.apache.fop.fo.FOUserAgent;
  23. public class BmpImage extends AbstractFopImage {
  24. public BmpImage(URL href, ImageReader imgReader) {
  25. super(href, imgReader);
  26. }
  27. protected boolean loadBitmap(FOUserAgent ua) {
  28. int wpos = 18;
  29. int hpos = 22; // offset positioning for w and height in bmp files
  30. int[] headermap = new int[54];
  31. int filepos = 0;
  32. InputStream file = null;
  33. byte palette[] = null;
  34. try {
  35. file = this.m_href.openStream();
  36. boolean eof = false;
  37. while ((!eof) && (filepos < 54)) {
  38. int input = file.read();
  39. if (input == -1)
  40. eof = true;
  41. else
  42. headermap[filepos++] = input;
  43. }
  44. if (headermap[28] == 4 || headermap[28] == 8) {
  45. int palettesize = 1 << headermap[28];
  46. palette = new byte[palettesize * 3];
  47. int countr = 0;
  48. while (!eof && countr < palettesize) {
  49. int count2 = 2;
  50. while (!eof && count2 >= -1) {
  51. int input = file.read();
  52. if (input == -1)
  53. eof = true;
  54. else if (count2 >= 0) {
  55. palette[countr * 3 + count2] =
  56. (byte)(input & 0xFF);
  57. }
  58. count2--;
  59. filepos++;
  60. }
  61. countr++;
  62. }
  63. }
  64. } catch (IOException e) {
  65. ua.getLogger().error("Error while loading image "
  66. + this.m_href.toString() + " : "
  67. + e.getClass() + " - "
  68. + e.getMessage(), e);
  69. return false;
  70. }
  71. // gets h & w from headermap
  72. this.m_width = headermap[wpos] + headermap[wpos + 1] * 256 +
  73. headermap[wpos + 2] * 256 * 256 +
  74. headermap[wpos + 3] * 256 * 256 * 256;
  75. this.m_height = headermap[hpos] + headermap[hpos + 1] * 256 +
  76. headermap[hpos + 2] * 256 * 256 +
  77. headermap[hpos + 3] * 256 * 256 * 256;
  78. int imagestart = headermap[10] + headermap[11] * 256 +
  79. headermap[12] * 256 * 256 + headermap[13] * 256 * 256 * 256;
  80. this.m_bitsPerPixel = headermap[28];
  81. this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
  82. int bytes = 0;
  83. if (this.m_bitsPerPixel == 1)
  84. bytes = (this.m_width + 7) / 8;
  85. else if (this.m_bitsPerPixel == 24)
  86. bytes = this.m_width * 3;
  87. else if (this.m_bitsPerPixel == 4 || this.m_bitsPerPixel == 8)
  88. bytes = this.m_width / (8 / this.m_bitsPerPixel);
  89. else {
  90. ua.getLogger().error("Image (" + this.m_href.toString()
  91. + ") has " + this.m_bitsPerPixel
  92. + " which is not a supported BMP format.");
  93. return false;
  94. }
  95. if ((bytes & 0x03) != 0) {
  96. bytes |= 0x03;
  97. bytes++;
  98. }
  99. // Should take care of the ColorSpace and bitsPerPixel
  100. this.m_bitmapsSize = this.m_width * this.m_height * 3;
  101. this.m_bitmaps = new byte[this.m_bitmapsSize];
  102. int[] temp = new int[bytes * this.m_height];
  103. try {
  104. int input;
  105. int count = 0;
  106. file.skip((long)(imagestart - filepos));
  107. while ((input = file.read()) != -1)
  108. temp[count++] = input;
  109. file.close();
  110. } catch (IOException e) {
  111. ua.getLogger().error("Error while loading image "
  112. + this.m_href.toString() + " : "
  113. + e.getClass() + " - "
  114. + e.getMessage(), e);
  115. return false;
  116. }
  117. for (int i = 0; i < this.m_height; i++) {
  118. int x = 0;
  119. int j = 0;
  120. while (j < bytes) {
  121. int p = temp[(this.m_height - i - 1) * bytes + j];
  122. if (this.m_bitsPerPixel == 24 && x < this.m_width) {
  123. int countr = 2;
  124. do {
  125. this.m_bitmaps[3 * (i * this.m_width + x) +
  126. countr] =
  127. (byte)(temp[(this.m_height - i - 1) *
  128. bytes + j] & 0xFF);
  129. j++;
  130. } while (--countr >= 0)
  131. ;
  132. x++;
  133. } else if (this.m_bitsPerPixel == 1) {
  134. for (int countr = 0;
  135. countr < 8 && x < this.m_width; countr++) {
  136. if ((p & 0x80) != 0) {
  137. this.m_bitmaps[3 *
  138. (i * this.m_width + x)] = (byte) 0xFF;
  139. this.m_bitmaps[3 * (i * this.m_width + x) +
  140. 1] = (byte) 0xFF;
  141. this.m_bitmaps[3 * (i * this.m_width + x) +
  142. 2] = (byte) 0xFF;
  143. } else {
  144. this.m_bitmaps[3 *
  145. (i * this.m_width + x)] = (byte) 0;
  146. this.m_bitmaps[3 * (i * this.m_width + x) +
  147. 1] = (byte) 0;
  148. this.m_bitmaps[3 * (i * this.m_width + x) +
  149. 2] = (byte) 0;
  150. }
  151. p <<= 1;
  152. x++;
  153. }
  154. j++;
  155. } else if (this.m_bitsPerPixel == 4) {
  156. for (int countr = 0;
  157. countr < 2 && x < this.m_width; countr++) {
  158. int pal = ((p & 0xF0) >> 4) * 3;
  159. this.m_bitmaps[3 * (i * this.m_width + x)] =
  160. palette[pal];
  161. this.m_bitmaps[3 * (i * this.m_width + x) +
  162. 1] = palette[pal + 1];
  163. this.m_bitmaps[3 * (i * this.m_width + x) +
  164. 2] = palette[pal + 2];
  165. p <<= 4;
  166. x++;
  167. }
  168. j++;
  169. } else if (this.m_bitsPerPixel == 8) {
  170. if (x < this.m_width) {
  171. p *= 3;
  172. this.m_bitmaps[3 * (i * this.m_width + x)] =
  173. palette[p];
  174. this.m_bitmaps[3 * (i * this.m_width + x) +
  175. 1] = palette[p + 1];
  176. this.m_bitmaps[3 * (i * this.m_width + x) +
  177. 2] = palette[p + 2];
  178. j++;
  179. x++;
  180. } else
  181. j = bytes;
  182. } else
  183. j++;
  184. }
  185. }
  186. // This seems really strange to me, but I noticed that JimiImage hardcodes
  187. // m_bitsPerPixel to 8. If I do not do this Acrobat is unable to read the resultant PDF,
  188. // so we will hardcode this...
  189. this.m_bitsPerPixel = 8;
  190. return true;
  191. }
  192. }