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.

AbstractImageAdapter.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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.render.pdf;
  19. import java.awt.color.ColorSpace;
  20. import java.awt.color.ICC_Profile;
  21. import org.apache.commons.logging.Log;
  22. import org.apache.commons.logging.LogFactory;
  23. import org.apache.xmlgraphics.image.loader.Image;
  24. import org.apache.fop.pdf.PDFColor;
  25. import org.apache.fop.pdf.PDFConformanceException;
  26. import org.apache.fop.pdf.PDFDeviceColorSpace;
  27. import org.apache.fop.pdf.PDFDictionary;
  28. import org.apache.fop.pdf.PDFDocument;
  29. import org.apache.fop.pdf.PDFICCBasedColorSpace;
  30. import org.apache.fop.pdf.PDFICCStream;
  31. import org.apache.fop.pdf.PDFImage;
  32. import org.apache.fop.pdf.PDFReference;
  33. import org.apache.fop.util.ColorProfileUtil;
  34. /**
  35. * Abstract PDFImage implementation for the PDF renderer.
  36. */
  37. public abstract class AbstractImageAdapter implements PDFImage {
  38. /** logging instance */
  39. private static Log log = LogFactory.getLog(AbstractImageAdapter.class);
  40. private String key;
  41. /** the image */
  42. protected Image image;
  43. private PDFICCStream pdfICCStream = null;
  44. /**
  45. * Creates a new PDFImage from an Image instance.
  46. * @param image the image
  47. * @param key XObject key
  48. */
  49. public AbstractImageAdapter(Image image, String key) {
  50. this.image = image;
  51. this.key = key;
  52. if (log.isDebugEnabled()) {
  53. log.debug("New ImageAdapter created for key: " + key);
  54. }
  55. }
  56. /** {@inheritDoc} */
  57. public String getKey() {
  58. // key to look up XObject
  59. return this.key;
  60. }
  61. /**
  62. * Returns the image's color space.
  63. * @return the color space
  64. */
  65. protected ColorSpace getImageColorSpace() {
  66. return image.getColorSpace();
  67. }
  68. /** {@inheritDoc} */
  69. public void setup(PDFDocument doc) {
  70. ICC_Profile prof = getEffectiveICCProfile();
  71. PDFDeviceColorSpace pdfCS = toPDFColorSpace(getImageColorSpace());
  72. if (prof != null) {
  73. pdfICCStream = setupColorProfile(doc, prof, pdfCS);
  74. }
  75. if (doc.getProfile().getPDFAMode().isPDFA1LevelB()) {
  76. if (pdfCS != null
  77. && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_RGB
  78. && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_GRAY
  79. && prof == null) {
  80. //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3
  81. //FOP is currently restricted to DeviceRGB if PDF/A-1 is active.
  82. throw new PDFConformanceException(
  83. "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK: "
  84. + image.getInfo());
  85. }
  86. }
  87. }
  88. /**
  89. * Returns the effective ICC profile for the image.
  90. * @return an ICC profile or null
  91. */
  92. protected ICC_Profile getEffectiveICCProfile() {
  93. return image.getICCProfile();
  94. }
  95. private static PDFICCStream setupColorProfile(PDFDocument doc,
  96. ICC_Profile prof, PDFDeviceColorSpace pdfCS) {
  97. boolean defaultsRGB = ColorProfileUtil.isDefaultsRGB(prof);
  98. String desc = ColorProfileUtil.getICCProfileDescription(prof);
  99. if (log.isDebugEnabled()) {
  100. log.debug("Image returns ICC profile: " + desc + ", default sRGB=" + defaultsRGB);
  101. }
  102. PDFICCBasedColorSpace cs = doc.getResources().getICCColorSpaceByProfileName(desc);
  103. PDFICCStream pdfICCStream;
  104. if (!defaultsRGB) {
  105. if (cs == null) {
  106. pdfICCStream = doc.getFactory().makePDFICCStream();
  107. pdfICCStream.setColorSpace(prof, pdfCS);
  108. cs = doc.getFactory().makeICCBasedColorSpace(null, null, pdfICCStream);
  109. } else {
  110. pdfICCStream = cs.getICCStream();
  111. }
  112. } else {
  113. if (cs == null && desc.startsWith("sRGB")) {
  114. //It's the default sRGB profile which we mapped to DefaultRGB in PDFRenderer
  115. cs = doc.getResources().getColorSpace("DefaultRGB");
  116. }
  117. if (cs == null) {
  118. // sRGB hasn't been set up for the PDF document
  119. // so install but don't set to DefaultRGB
  120. cs = PDFICCBasedColorSpace.setupsRGBColorSpace(doc);
  121. }
  122. pdfICCStream = cs.getICCStream();
  123. }
  124. return pdfICCStream;
  125. }
  126. /** {@inheritDoc} */
  127. public int getWidth() {
  128. return image.getSize().getWidthPx();
  129. }
  130. /** {@inheritDoc} */
  131. public int getHeight() {
  132. return image.getSize().getHeightPx();
  133. }
  134. /** {@inheritDoc} */
  135. public boolean isTransparent() {
  136. return false;
  137. }
  138. /** {@inheritDoc} */
  139. public PDFColor getTransparentColor() {
  140. return null;
  141. }
  142. /** {@inheritDoc} */
  143. public String getMask() {
  144. return null;
  145. }
  146. /** @return null (if not overridden) */
  147. public String getSoftMask() {
  148. return null;
  149. }
  150. /** {@inheritDoc} */
  151. public PDFReference getSoftMaskReference() {
  152. return null;
  153. }
  154. /** {@inheritDoc} */
  155. public boolean isInverted() {
  156. return false;
  157. }
  158. /** {@inheritDoc} */
  159. public boolean isPS() {
  160. return false;
  161. }
  162. /** {@inheritDoc} */
  163. public PDFICCStream getICCStream() {
  164. return pdfICCStream;
  165. }
  166. /** {@inheritDoc} */
  167. public void populateXObjectDictionary(PDFDictionary dict) {
  168. //nop
  169. }
  170. /**
  171. * Converts a ColorSpace object to a PDFColorSpace object.
  172. * @param cs ColorSpace instance
  173. * @return PDFColorSpace new converted object
  174. */
  175. public static PDFDeviceColorSpace toPDFColorSpace(ColorSpace cs) {
  176. if (cs == null) {
  177. return null;
  178. }
  179. PDFDeviceColorSpace pdfCS = new PDFDeviceColorSpace(0);
  180. switch (cs.getType()) {
  181. case ColorSpace.TYPE_CMYK:
  182. pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_CMYK);
  183. break;
  184. case ColorSpace.TYPE_GRAY:
  185. pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_GRAY);
  186. break;
  187. default:
  188. pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
  189. }
  190. return pdfCS;
  191. }
  192. }