1 17 18 19 20 package org.apache.fop.render.pdf; 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 import org.apache.fop.pdf.PDFConformanceException; 24 import org.apache.fop.pdf.PDFFilterList; 25 import org.apache.fop.pdf.PDFICCBasedColorSpace; 26 import org.apache.fop.pdf.PDFImage; 27 import org.apache.fop.pdf.PDFFilter; 28 import org.apache.fop.pdf.PDFICCStream; 29 import org.apache.fop.pdf.PDFColor; 30 import org.apache.fop.pdf.PDFDocument; 31 import org.apache.fop.pdf.DCTFilter; 32 import org.apache.fop.pdf.CCFFilter; 33 import org.apache.fop.pdf.PDFDeviceColorSpace; 34 import org.apache.fop.pdf.PDFXObject; 35 import org.apache.fop.pdf.BitmapImage; 36 import org.apache.fop.util.ColorProfileUtil; 37 38 import org.apache.fop.image.FopImage; 39 import org.apache.fop.image.EPSImage; 40 import org.apache.fop.image.TIFFImage; 41 42 import java.io.IOException ; 43 import java.io.OutputStream ; 44 import java.awt.color.ColorSpace ; 45 import java.awt.color.ICC_Profile ; 46 47 50 public class FopPDFImage implements PDFImage { 51 52 53 private static Log log = LogFactory.getLog(FopPDFImage.class); 54 55 private FopImage fopImage; 56 private PDFICCStream pdfICCStream = null; 57 private PDFFilter pdfFilter = null; 58 private String maskRef; 59 private String softMaskRef; 60 private boolean isPS = false; 61 private boolean isCCF = false; 62 private boolean isDCT = false; 63 private String key; 64 65 70 public FopPDFImage(FopImage image, String key) { 71 fopImage = image; 72 this.key = key; 73 isPS = (fopImage instanceof EPSImage); 74 } 75 76 79 public String getKey() { 80 return this.key; 82 } 83 84 87 public void setup(PDFDocument doc) { 88 if ("image/jpeg".equals(fopImage.getMimeType())) { 89 pdfFilter = new DCTFilter(); 90 pdfFilter.setApplied(true); 91 isDCT = true; 92 93 } else if ("image/tiff".equals(fopImage.getMimeType()) 94 && fopImage instanceof TIFFImage) { 95 TIFFImage tiffImage = (TIFFImage) fopImage; 96 if (tiffImage.getStripCount() == 1) { 97 int comp = tiffImage.getCompression(); 98 if (comp == 1) { 99 } else if (comp == 3) { 101 pdfFilter = new CCFFilter(); 102 pdfFilter.setApplied(true); 103 isCCF = true; 104 } else if (comp == 4) { 105 pdfFilter = new CCFFilter(); 106 pdfFilter.setApplied(true); 107 ((CCFFilter)pdfFilter).setDecodeParms("<< /K -1 /Columns " 108 + tiffImage.getWidth() + " >>"); 109 isCCF = true; 110 } else if (comp == 6) { 111 pdfFilter = new DCTFilter(); 112 pdfFilter.setApplied(true); 113 isDCT = true; 114 } 115 } 116 } 117 if (isPS || isDCT || isCCF) { 118 fopImage.load(FopImage.ORIGINAL_DATA); 119 } else { 120 fopImage.load(FopImage.BITMAP); 121 } 122 ICC_Profile prof = fopImage.getICCProfile(); 123 PDFDeviceColorSpace pdfCS = toPDFColorSpace(fopImage.getColorSpace()); 124 if (prof != null) { 125 boolean defaultsRGB = ColorProfileUtil.isDefaultsRGB(prof); 126 String desc = ColorProfileUtil.getICCProfileDescription(prof); 127 if (log.isDebugEnabled()) { 128 log.debug("Image returns ICC profile: " + desc + ", default sRGB=" + defaultsRGB); 129 } 130 PDFICCBasedColorSpace cs = doc.getResources().getICCColorSpaceByProfileName(desc); 131 if (!defaultsRGB) { 132 if (cs == null) { 133 pdfICCStream = doc.getFactory().makePDFICCStream(); 134 pdfICCStream.setColorSpace(prof, pdfCS); 135 cs = doc.getFactory().makeICCBasedColorSpace(null, null, pdfICCStream); 136 } else { 137 pdfICCStream = cs.getICCStream(); 138 } 139 } else { 140 if (cs == null && "sRGB".equals(desc)) { 141 cs = doc.getResources().getColorSpace("DefaultRGB"); 143 } 144 pdfICCStream = cs.getICCStream(); 145 } 146 } 147 if (fopImage.hasSoftMask()) { 149 doc.getProfile().verifyTransparencyAllowed(fopImage.getOriginalURI()); 150 byte [] softMask = fopImage.getSoftMask(); 153 if (softMask == null) { 154 return; 155 } 156 BitmapImage fopimg = new BitmapImage 157 ("Mask:" + key, fopImage.getWidth(), fopImage.getHeight(), 158 softMask, null); 159 fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY)); 160 PDFXObject xobj = doc.addImage(null, fopimg); 161 softMaskRef = xobj.referencePDF(); 162 } 163 if (doc.getProfile().getPDFAMode().isPDFA1LevelB()) { 164 if (pdfCS != null 165 && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_RGB 166 && pdfCS.getColorSpace() != PDFDeviceColorSpace.DEVICE_GRAY 167 && prof == null) { 168 throw new PDFConformanceException( 171 "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK: " 172 + fopImage.getOriginalURI()); 173 } 174 } 175 } 176 177 180 public int getWidth() { 181 return fopImage.getWidth(); 182 } 183 184 187 public int getHeight() { 188 return fopImage.getHeight(); 189 } 190 191 194 public PDFDeviceColorSpace getColorSpace() { 195 if (isCCF || isDCT || isPS) { 197 return toPDFColorSpace(fopImage.getColorSpace()); 198 } else { 199 return toPDFColorSpace(ColorSpace.getInstance(ColorSpace.CS_sRGB)); 200 } 201 } 202 203 206 public int getBitsPerPixel() { 207 if (isCCF) { 208 return fopImage.getBitsPerPixel(); 209 } else { 210 return 8; } 214 } 215 216 219 public boolean isTransparent() { 220 return fopImage.isTransparent(); 221 } 222 223 226 public PDFColor getTransparentColor() { 227 return new PDFColor(fopImage.getTransparentColor().getRed(), 228 fopImage.getTransparentColor().getGreen(), 229 fopImage.getTransparentColor().getBlue()); 230 } 231 232 235 public String getMask() { 236 return maskRef; 237 } 238 239 242 public String getSoftMask() { 243 return softMaskRef; 244 } 245 246 247 public boolean isInverted() { 248 return fopImage.isInverted(); 249 } 250 251 254 public boolean isPS() { 255 return isPS; 256 } 257 258 261 public PDFFilter getPDFFilter() { 262 return pdfFilter; 263 } 264 265 268 public void outputContents(OutputStream out) throws IOException { 269 if (isPS) { 270 outputPostScriptContents(out); 271 } else { 272 if (fopImage.getBitmapsSize() > 0) { 273 out.write(fopImage.getBitmaps()); 274 } else { 275 out.write(fopImage.getRessourceBytes()); 276 } 277 } 278 } 279 280 285 protected void outputPostScriptContents(OutputStream out) throws IOException { 286 EPSImage epsImage = (EPSImage) fopImage; 287 int[] bbox = epsImage.getBBox(); 288 int bboxw = bbox[2] - bbox[0]; 289 int bboxh = bbox[3] - bbox[1]; 290 291 294 StringBuffer preamble = new StringBuffer (); 295 preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n"); 296 297 preamble.append("userdict begin % Push userdict on dict stack\n"); 298 preamble.append("/PreEPS_state save def\n"); 299 preamble.append("/dict_stack countdictstack def\n"); 300 preamble.append("/ops_count count 1 sub def\n"); 301 preamble.append("/showpage {} def\n"); 302 303 304 preamble.append((double)(1f / (double) bboxw) + " " 305 + (double)(1f / (double) bboxh) + " scale\n"); 306 preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n"); 307 preamble.append(bbox[0] + " " + bbox[1] + " " 308 + bboxw + " " + bboxh + " rectclip\n"); 309 preamble.append("newpath\n"); 310 311 StringBuffer post = new StringBuffer (); 312 post.append("%%EndDocument\n"); 313 post.append("count ops_count sub {pop} repeat\n"); 314 post.append("countdictstack dict_stack sub {end} repeat\n"); 315 post.append("PreEPS_state restore\n"); 316 post.append("end % userdict\n"); 317 318 out.write(PDFDocument.encode(preamble.toString())); 320 out.write(((EPSImage)fopImage).getEPSImage()); 322 out.write(PDFDocument.encode(post.toString())); 324 } 325 326 329 public PDFICCStream getICCStream() { 330 return pdfICCStream; 331 } 332 333 338 public static PDFDeviceColorSpace toPDFColorSpace(ColorSpace cs) { 339 if (cs == null) { 340 return null; 341 } 342 343 PDFDeviceColorSpace pdfCS = new PDFDeviceColorSpace(0); 344 switch(cs.getType()) { 345 case ColorSpace.TYPE_CMYK: 346 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_CMYK); 347 break; 348 case ColorSpace.TYPE_RGB: 349 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_RGB); 350 break; 351 case ColorSpace.TYPE_GRAY: 352 pdfCS.setColorSpace(PDFDeviceColorSpace.DEVICE_GRAY); 353 break; 354 } 355 return pdfCS; 356 } 357 358 361 public String getFilterHint() { 362 if (isPS) { 363 return PDFFilterList.CONTENT_FILTER; 364 } else if (isDCT) { 365 return PDFFilterList.JPEG_FILTER; 366 } else if (isCCF) { 367 return PDFFilterList.TIFF_FILTER; 368 } else { 369 return PDFFilterList.IMAGE_FILTER; 370 } 371 } 372 373 } 374 375 | Popular Tags |