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.

GifImage.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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.image.ImageProducer;
  21. import java.awt.image.ColorModel;
  22. import java.awt.image.IndexColorModel;
  23. import java.awt.color.ColorSpace;
  24. import java.awt.Color;
  25. import java.io.InputStream;
  26. import java.io.IOException;
  27. import java.net.URLConnection;
  28. import org.apache.commons.io.IOUtils;
  29. /**
  30. * FopImage object for GIF images, using Java native classes.
  31. *
  32. * @see AbstractFopImage
  33. * @see FopImage
  34. */
  35. public class GifImage extends AbstractFopImage {
  36. /**
  37. * Create a new gif image.
  38. *
  39. * @param imgInfo the image info for this gif image
  40. */
  41. public GifImage(FopImage.ImageInfo imgInfo) {
  42. super(imgInfo);
  43. }
  44. /**
  45. * Load the bitmap for this gif image.
  46. * This loads the data and creates a bitmap byte array
  47. * of the image data.
  48. * To decode the image a dummy URLConnection is used that
  49. * will do the conversion.
  50. *
  51. * @return True if the load process succeeded
  52. */
  53. protected boolean loadBitmap() {
  54. int[] tmpMap = null;
  55. try {
  56. URLConnection con = new DummyConnection(inputStream);
  57. ImageProducer ip = (ImageProducer) con.getContent();
  58. if (ip == null) {
  59. return false;
  60. }
  61. FopImageConsumer consumer = new FopImageConsumer(ip);
  62. ip.startProduction(consumer);
  63. //Load the image into memory
  64. while (!consumer.isImageReady()) {
  65. Thread.sleep(500);
  66. }
  67. this.height = consumer.getHeight();
  68. this.width = consumer.getWidth();
  69. try {
  70. tmpMap = consumer.getImage();
  71. } catch (Exception ex) {
  72. log.error("Image grabbing interrupted : "
  73. + ex.getMessage(), ex);
  74. return false;
  75. }
  76. ColorModel cm = consumer.getColorModel();
  77. this.bitsPerPixel = 8;
  78. // this.bitsPerPixel = cm.getPixelSize();
  79. this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
  80. if (cm.hasAlpha()) {
  81. // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT
  82. int transparencyType = cm.getTransparency();
  83. if (transparencyType == java.awt.Transparency.OPAQUE) {
  84. this.isTransparent = false;
  85. } else if (transparencyType == java.awt.Transparency.BITMASK) {
  86. if (cm instanceof IndexColorModel) {
  87. IndexColorModel indexcm = (IndexColorModel) cm;
  88. this.isTransparent = false;
  89. byte[] alphas = new byte[indexcm.getMapSize()];
  90. byte[] reds = new byte[indexcm.getMapSize()];
  91. byte[] greens = new byte[indexcm.getMapSize()];
  92. byte[] blues = new byte[indexcm.getMapSize()];
  93. indexcm.getAlphas(alphas);
  94. indexcm.getReds(reds);
  95. indexcm.getGreens(greens);
  96. indexcm.getBlues(blues);
  97. for (int i = 0;
  98. i < indexcm.getMapSize();
  99. i++) {
  100. if ((alphas[i] & 0xFF) == 0) {
  101. this.isTransparent = true;
  102. this.transparentColor = new Color(
  103. (int)(reds[i] & 0xFF),
  104. (int)(greens[i] & 0xFF),
  105. (int)(blues[i] & 0xFF));
  106. break;
  107. }
  108. }
  109. } else {
  110. // TRANSLUCENT
  111. /*
  112. * this.isTransparent = false;
  113. * for (int i = 0; i < this.width * this.height; i++) {
  114. * if (cm.getAlpha(tmpMap[i]) == 0) {
  115. * this.isTransparent = true;
  116. * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]),
  117. * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i]));
  118. * break;
  119. * }
  120. * }
  121. */
  122. // use special API...
  123. this.isTransparent = false;
  124. }
  125. } else {
  126. this.isTransparent = false;
  127. }
  128. } else {
  129. this.isTransparent = false;
  130. }
  131. } catch (Exception ex) {
  132. log.error("Error while loading image (Gif): " + ex.getMessage(), ex);
  133. return false;
  134. } finally {
  135. IOUtils.closeQuietly(inputStream);
  136. inputStream = null;
  137. }
  138. // Should take care of the ColorSpace and bitsPerPixel
  139. this.bitmaps = new byte[this.width * this.height * 3];
  140. for (int i = 0; i < this.height; i++) {
  141. for (int j = 0; j < this.width; j++) {
  142. int p = tmpMap[i * this.width + j];
  143. int r = (p >> 16) & 0xFF;
  144. int g = (p >> 8) & 0xFF;
  145. int b = (p) & 0xFF;
  146. this.bitmaps[3 * (i * this.width + j)] = (byte)(r & 0xFF);
  147. this.bitmaps[3 * (i * this.width + j) + 1] = (byte)(g & 0xFF);
  148. this.bitmaps[3 * (i * this.width + j) + 2] = (byte)(b & 0xFF);
  149. }
  150. }
  151. return true;
  152. }
  153. /** {@inheritDoc} */
  154. protected boolean loadOriginalData() {
  155. return loadDefaultOriginalData();
  156. }
  157. /**
  158. * A dummy url connection for a gif image in an input stream.
  159. */
  160. protected static class DummyConnection extends URLConnection {
  161. private InputStream inputStream;
  162. DummyConnection(InputStream is) {
  163. super(null);
  164. inputStream = is;
  165. }
  166. /**
  167. * {@inheritDoc}
  168. */
  169. public InputStream getInputStream() throws IOException {
  170. return inputStream;
  171. }
  172. /**
  173. * {@inheritDoc}
  174. */
  175. public void connect() throws IOException {
  176. // do nothing
  177. }
  178. /**
  179. * {@inheritDoc}
  180. */
  181. public String getContentType() {
  182. return "image/gif";
  183. }
  184. /**
  185. * {@inheritDoc}
  186. */
  187. public int getContentLength() {
  188. try {
  189. return inputStream.available();
  190. } catch (IOException e) {
  191. return -1;
  192. }
  193. }
  194. }
  195. }