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.

PDFImageXObject.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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.pdf;
  19. // Java
  20. import java.io.IOException;
  21. import java.io.OutputStream;
  22. /* modified by JKT to integrate with 0.12.0 */
  23. /* modified by Eric SCHAEFFER to integrate with 0.13.0 */
  24. /**
  25. * PDF XObject
  26. *
  27. * A derivative of the PDF Object, is a PDF Stream that has not only a
  28. * dictionary but a stream of image data.
  29. * The dictionary just provides information like the stream length.
  30. * This outputs the image dictionary and the image data.
  31. * This is used as a reference for inserting the same image in the
  32. * document in another place.
  33. */
  34. public class PDFImageXObject extends PDFXObject {
  35. private PDFImage pdfimage;
  36. /**
  37. * create an XObject with the given number and name and load the
  38. * image in the object
  39. *
  40. * @param xnumber the pdf object X number
  41. * @param img the pdf image that contains the image data
  42. */
  43. public PDFImageXObject(int xnumber, PDFImage img) {
  44. super();
  45. put("Name", new PDFName("Im" + xnumber));
  46. pdfimage = img;
  47. }
  48. /**
  49. * Output the image as PDF.
  50. * This sets up the image dictionary and adds the image data stream.
  51. *
  52. * @param stream the output stream to write the data
  53. * @throws IOException if there is an error writing the data
  54. * @return the length of the data written
  55. */
  56. public int output(OutputStream stream) throws IOException {
  57. int length = super.output(stream);
  58. // let it gc
  59. // this object is retained as a reference to inserting
  60. // the same image but the image data is no longer needed
  61. pdfimage = null;
  62. return length;
  63. }
  64. /** {@inheritDoc} */
  65. protected void populateStreamDict(Object lengthEntry) {
  66. super.populateStreamDict(lengthEntry);
  67. if (pdfimage.isPS()) {
  68. populateDictionaryFromPS();
  69. } else {
  70. populateDictionaryFromImage();
  71. }
  72. }
  73. private void populateDictionaryFromPS() {
  74. getDocumentSafely().getProfile().verifyPSXObjectsAllowed();
  75. put("Subtype", new PDFName("PS"));
  76. }
  77. private void populateDictionaryFromImage() {
  78. put("Subtype", new PDFName("Image"));
  79. put("Width", new Integer(pdfimage.getWidth()));
  80. put("Height", new Integer(pdfimage.getHeight()));
  81. put("BitsPerComponent", new Integer(pdfimage.getBitsPerComponent()));
  82. PDFICCStream pdfICCStream = pdfimage.getICCStream();
  83. if (pdfICCStream != null) {
  84. put("ColorSpace", new PDFArray(this,
  85. new Object[] {new PDFName("ICCBased"), pdfICCStream}));
  86. } else {
  87. PDFDeviceColorSpace cs = pdfimage.getColorSpace();
  88. put("ColorSpace", new PDFName(cs.getName()));
  89. }
  90. if (pdfimage.isInverted()) {
  91. /* PhotoShop generates CMYK values that's inverse,
  92. * this will invert the values - too bad if it's not
  93. * a PhotoShop image...
  94. */
  95. final Float zero = new Float(0.0f);
  96. final Float one = new Float(1.0f);
  97. PDFArray decode = new PDFArray(this);
  98. for (int i = 0, c = pdfimage.getColorSpace().getNumComponents(); i < c; i++) {
  99. decode.add(one);
  100. decode.add(zero);
  101. }
  102. put("Decode", decode);
  103. }
  104. if (pdfimage.isTransparent()) {
  105. PDFColor transp = pdfimage.getTransparentColor();
  106. PDFArray mask = new PDFArray(this);
  107. if (pdfimage.getColorSpace().isGrayColorSpace()) {
  108. mask.add(new Integer(transp.red255()));
  109. mask.add(new Integer(transp.red255()));
  110. } else {
  111. mask.add(new Integer(transp.red255()));
  112. mask.add(new Integer(transp.red255()));
  113. mask.add(new Integer(transp.green255()));
  114. mask.add(new Integer(transp.green255()));
  115. mask.add(new Integer(transp.blue255()));
  116. mask.add(new Integer(transp.blue255()));
  117. }
  118. put("Mask", mask);
  119. }
  120. PDFReference ref = pdfimage.getSoftMaskReference();
  121. if (ref != null) {
  122. put("SMask", ref);
  123. }
  124. //Important: do this at the end so previous values can be overwritten.
  125. pdfimage.populateXObjectDictionary(getDictionary());
  126. }
  127. /** {@inheritDoc} */
  128. protected void outputRawStreamData(OutputStream out) throws IOException {
  129. pdfimage.outputContents(out);
  130. }
  131. /** {@inheritDoc} */
  132. protected int getSizeHint() throws IOException {
  133. return 0;
  134. }
  135. /** {@inheritDoc} */
  136. protected void prepareImplicitFilters() {
  137. PDFFilter pdfFilter = pdfimage.getPDFFilter();
  138. if (pdfFilter != null) {
  139. getFilterList().ensureFilterInPlace(pdfFilter);
  140. }
  141. }
  142. /**
  143. * {@inheritDoc}
  144. * This class uses the PDFImage instance to determine the default filter.
  145. */
  146. protected String getDefaultFilterName() {
  147. return pdfimage.getFilterHint();
  148. }
  149. }