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.

AbstractFopImage.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.image;
  19. // Java
  20. import java.awt.color.ColorSpace;
  21. import java.awt.color.ICC_ColorSpace;
  22. import java.awt.color.ICC_Profile;
  23. import java.io.InputStream;
  24. import java.awt.Color;
  25. import org.apache.commons.io.IOUtils;
  26. import org.apache.commons.logging.Log;
  27. import org.apache.commons.logging.LogFactory;
  28. import org.apache.fop.datatypes.Length;
  29. /**
  30. * Base class to implement the FopImage interface.
  31. *
  32. * @see FopImage
  33. */
  34. public abstract class AbstractFopImage implements FopImage {
  35. /**
  36. * logging instance
  37. */
  38. protected static Log log = LogFactory.getLog(AbstractFopImage.class);
  39. /**
  40. * Keeps track of what has been loaded.
  41. */
  42. protected int loaded = 0;
  43. /**
  44. * Image width (in pixel).
  45. */
  46. protected int width = 0;
  47. /**
  48. * Image height (in pixel).
  49. */
  50. protected int height = 0;
  51. /** Horizontal bitmap resolution (in dpi) */
  52. protected double dpiHorizontal = 72.0f;
  53. /** Vertical bitmap resolution (in dpi) */
  54. protected double dpiVertical = 72.0f;
  55. /**
  56. * Image input stream.
  57. */
  58. protected InputStream inputStream = null;
  59. /**
  60. * ImageReader object (to obtain image header informations).
  61. */
  62. protected FopImage.ImageInfo imageInfo = null;
  63. /**
  64. * Image color space (java.awt.color.ColorSpace).
  65. */
  66. protected ColorSpace colorSpace = null;
  67. /**
  68. * Bits per pixel.
  69. */
  70. protected int bitsPerPixel = 0;
  71. /**
  72. * Image data (pixels, uncompressed).
  73. */
  74. protected byte[] bitmaps = null;
  75. /**
  76. * Image data (undecoded, compressed, for image formats that can be embedded without decoding.
  77. */
  78. protected byte[] raw = null;
  79. /**
  80. * Image transparency.
  81. */
  82. protected boolean isTransparent = false;
  83. /**
  84. * Transparent color (java.awt.Color).
  85. */
  86. protected Color transparentColor = null;
  87. /**
  88. * Photoshop generated CMYK JPEGs are inverted.
  89. */
  90. protected boolean invertImage = false;
  91. /**
  92. * Constructor.
  93. * Construct a new FopImage object and initialize its default properties:
  94. * <UL>
  95. * <LI>image width
  96. * <LI>image height
  97. * </UL>
  98. * The image data isn't kept in memory.
  99. * @param info image information
  100. */
  101. public AbstractFopImage(FopImage.ImageInfo info) {
  102. this.inputStream = info.inputStream;
  103. this.imageInfo = info;
  104. if (this.imageInfo.width != -1) {
  105. width = imageInfo.width;
  106. height = imageInfo.height;
  107. dpiHorizontal = imageInfo.dpiHorizontal;
  108. dpiVertical = imageInfo.dpiVertical;
  109. loaded = loaded | DIMENSIONS;
  110. }
  111. }
  112. /**
  113. * Get the mime type for this image.
  114. *
  115. * @return the mime type for the image
  116. */
  117. public String getMimeType() {
  118. return imageInfo.mimeType;
  119. }
  120. /** {@inheritDoc} */
  121. public String getOriginalURI() {
  122. return this.imageInfo.originalURI;
  123. }
  124. /**
  125. * Load image data and initialize its properties.
  126. *
  127. * @param type the type of loading to do
  128. * @return true if the loading was successful
  129. */
  130. public synchronized boolean load(int type) {
  131. if ((loaded & type) != 0) {
  132. return true;
  133. }
  134. boolean success = true;
  135. if (((type & DIMENSIONS) != 0) && ((loaded & DIMENSIONS) == 0)) {
  136. success = success && loadDimensions();
  137. if (!success) {
  138. return false;
  139. }
  140. loaded = loaded | DIMENSIONS;
  141. }
  142. if (((type & BITMAP) != 0) && ((loaded & BITMAP) == 0)) {
  143. success = success && loadBitmap();
  144. if (success) {
  145. loaded = loaded | BITMAP;
  146. }
  147. }
  148. if (((type & ORIGINAL_DATA) != 0) && ((loaded & ORIGINAL_DATA) == 0)) {
  149. success = success && loadOriginalData();
  150. if (success) {
  151. loaded = loaded | ORIGINAL_DATA;
  152. }
  153. }
  154. return success;
  155. }
  156. /**
  157. * Load the dimensions of the image.
  158. * All implementations should override this to get and
  159. * return the dimensions.
  160. *
  161. * @return true if the loading was successful
  162. */
  163. protected boolean loadDimensions() {
  164. return false;
  165. }
  166. /**
  167. * Load a bitmap array of the image.
  168. * If the renderer requires a bitmap image then the
  169. * implementations should override this to load the bitmap.
  170. *
  171. * @return true if the loading was successful
  172. */
  173. protected boolean loadBitmap() {
  174. return false;
  175. }
  176. /**
  177. * Load the original image data.
  178. * In some cases the original data can be used by the renderer.
  179. * This should load the data and any other associated information.
  180. *
  181. * @return true if the loading was successful
  182. */
  183. protected boolean loadOriginalData() {
  184. return false;
  185. }
  186. /**
  187. * Load the original image data. This is generic code for use by any
  188. * subclass that wants to use this from a loadOriginalData() implementation.
  189. *
  190. * @return true if the loading was successful
  191. */
  192. protected boolean loadDefaultOriginalData() {
  193. if (inputStream == null) {
  194. throw new IllegalStateException("inputStream is already null or was never set");
  195. }
  196. try {
  197. this.raw = IOUtils.toByteArray(inputStream);
  198. } catch (java.io.IOException ex) {
  199. log.error("Error while reading raw image: " + ex.getMessage(), ex);
  200. return false;
  201. } finally {
  202. IOUtils.closeQuietly(inputStream);
  203. inputStream = null;
  204. }
  205. return true;
  206. }
  207. /**
  208. * @return the image width (in pixels)
  209. */
  210. public int getWidth() {
  211. return this.width;
  212. }
  213. /**
  214. * @return the image height (in pixels)
  215. */
  216. public int getHeight() {
  217. return this.height;
  218. }
  219. /** {@inheritDoc} */
  220. public int getIntrinsicWidth() {
  221. return (int)(getWidth() * 72000 / getHorizontalResolution());
  222. }
  223. /** {@inheritDoc} */
  224. public int getIntrinsicHeight() {
  225. return (int)(getHeight() * 72000 / getVerticalResolution());
  226. }
  227. /** {@inheritDoc} */
  228. public Length getIntrinsicAlignmentAdjust() {
  229. return this.imageInfo.alignmentAdjust;
  230. }
  231. /** {@inheritDoc} */
  232. public double getHorizontalResolution() {
  233. return this.dpiHorizontal;
  234. }
  235. /** {@inheritDoc} */
  236. public double getVerticalResolution() {
  237. return this.dpiVertical;
  238. }
  239. /**
  240. * Return the image color space.
  241. * @return the image color space (java.awt.color.ColorSpace)
  242. */
  243. public ColorSpace getColorSpace() {
  244. return this.colorSpace;
  245. }
  246. /**
  247. * Get ICC profile for this image.
  248. * @return the icc profile or null if not applicable
  249. */
  250. public ICC_Profile getICCProfile() {
  251. if (this.colorSpace != null && this.colorSpace instanceof ICC_ColorSpace) {
  252. return ((ICC_ColorSpace)this.colorSpace).getProfile();
  253. }
  254. return null;
  255. }
  256. /**
  257. * Return the number of bits per pixel.
  258. * @return number of bits per pixel
  259. */
  260. public int getBitsPerPixel() {
  261. return this.bitsPerPixel;
  262. }
  263. /**
  264. * Return the image transparency.
  265. * @return true if the image is transparent
  266. */
  267. public boolean isTransparent() {
  268. return this.isTransparent;
  269. }
  270. /**
  271. * Check if this image has a soft mask.
  272. *
  273. * @return true if the image also has a soft transparency mask
  274. */
  275. public boolean hasSoftMask() {
  276. return false;
  277. }
  278. /**
  279. * Get the soft mask.
  280. * The soft mask should have the same bitdepth as the image data.
  281. *
  282. * @return the data array of soft mask values
  283. */
  284. public byte[] getSoftMask() {
  285. return null;
  286. }
  287. /**
  288. * Return the transparent color.
  289. * @return the transparent color (java.awt.Color)
  290. */
  291. public Color getTransparentColor() {
  292. return this.transparentColor;
  293. }
  294. /** @return true for CMYK images generated by Adobe Photoshop */
  295. public boolean isInverted() {
  296. return this.invertImage;
  297. }
  298. /**
  299. * Return the image data (pixels, uncompressed).
  300. * @return the image data
  301. */
  302. public byte[] getBitmaps() {
  303. return this.bitmaps;
  304. }
  305. /**
  306. * Return the image data size (number of bytes taken up by the uncompressed pixels).
  307. * @return the image data size
  308. */
  309. public int getBitmapsSize() {
  310. return (bitmaps != null ? bitmaps.length : 0);
  311. }
  312. /**
  313. * Return the original image data (compressed).
  314. * @return the original image data
  315. */
  316. public byte[] getRessourceBytes() {
  317. return raw;
  318. }
  319. /**
  320. * Return the original image data size (compressed).
  321. * @return the original image data size
  322. */
  323. public int getRessourceBytesSize() {
  324. return (raw != null ? raw.length : 0);
  325. }
  326. }