[prev in list] [next in list] [prev in thread] [next in thread] 

List:       fop-cvs
Subject:    cvs commit: xml-fop/src/org/apache/fop/render/ps PSStream.java PSRenderer.java
From:       tore () apache ! org
Date:       2001-11-16 19:36:41
[Download RAW message or body]

tore        01/11/16 11:36:41

  Modified:    src/org/apache/fop/datatypes ColorSpace.java
               src/org/apache/fop/image/analyser ImageReaderFactory.java
               src/org/apache/fop/image FopImageFactory.java JpegImage.java
               src/org/apache/fop/pdf PDFXObject.java PDFDocument.java
               src/org/apache/fop/render/ps PSStream.java PSRenderer.java
  Added:       src/org/apache/fop/image/analyser EPSReader.java
               src/org/apache/fop/image EPSImage.java
               src/org/apache/fop/pdf PDFICCStream.java
  Log:
  Support for CMYK jpeg's and ICC profiles
  Initial support for EPS images (only limited support in PDFRenderer)
  (need to fix PSRenderer as soon as new area tree and rendering stuff are finished)
  
  Revision  Changes    Path
  1.4       +49 -11    xml-fop/src/org/apache/fop/datatypes/ColorSpace.java
  
  Index: ColorSpace.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/datatypes/ColorSpace.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ColorSpace.java	2001/07/30 20:29:19	1.3
  +++ ColorSpace.java	2001/11/16 19:36:40	1.4
  @@ -1,5 +1,5 @@
   /*
  - * $Id: ColorSpace.java,v 1.3 2001/07/30 20:29:19 tore Exp $
  + * $Id: ColorSpace.java,v 1.4 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -8,36 +8,74 @@
   package org.apache.fop.datatypes;
   
   public class ColorSpace {
  +    private boolean hasICCProfile;
  +    private byte[] iccProfile;
  +    private int numComponents;
  +    
       // Ok... so I had some grand purpose for this, but I can't recall.
       // I'm just writing it
  -
  +    
       public static int DEVICE_UNKNOWN = -1;
       public static int DEVICE_GRAY = 1;
       // what's the *official* spelling?
       // public static int DEVICE_GREY = 1;
       public static int DEVICE_RGB = 2;
       public static int DEVICE_CMYK = 3;
  -
  +    
  +    
       // Are there any others?
   
       protected int currentColorSpace = -1;
   
       public ColorSpace(int theColorSpace) {
           this.currentColorSpace = theColorSpace;
  -
  +        hasICCProfile = false;
  +        numComponents = calculateNumComponents();
       }
  -
  -    public int getColorSpace() {
  -        return (this.currentColorSpace);
  +    
  +    private int calculateNumComponents() {
  +        if (currentColorSpace == DEVICE_GRAY)
  +            return 1;
  +        else if (currentColorSpace == DEVICE_RGB)
  +            return 3;
  +        else if (currentColorSpace == DEVICE_CMYK)
  +            return 4;
  +        else
  +            return 0;
       }
   
       public void setColorSpace(int theColorSpace) {
           this.currentColorSpace = theColorSpace;
  +        numComponents = calculateNumComponents();
       }
  -
  +    
  +    public boolean hasICCProfile() {
  +        return hasICCProfile;
  +    }
  +    
  +    public byte[] getICCProfile() {
  +        if (hasICCProfile)
  +            return iccProfile;
  +        else
  +            return new byte[0];
  +    }
  +    
  +    public void setICCProfile(byte[] iccProfile) {
  +        this.iccProfile = iccProfile;
  +        hasICCProfile = true;
  +    }
  +    
  +    public int getColorSpace() {
  +        return (this.currentColorSpace);
  +    }
  +    
  +    public int getNumComponents() {
  +        return numComponents;
  +    }
  +    
       public String getColorSpacePDFString() {    // this is for PDF Output. Does \
                anyone else need a string representation?
  -
  -
  +        
  +        
           // shouldn't this be a select-case? I can never remember
           // the syntax for that.
           if (this.currentColorSpace == this.DEVICE_RGB) {
  @@ -50,5 +88,5 @@
               return ("DeviceRGB");
           }
       }
  -
  +    
   }
  
  
  
  1.7       +2 -1      \
xml-fop/src/org/apache/fop/image/analyser/ImageReaderFactory.java  
  Index: ImageReaderFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/image/analyser/ImageReaderFactory.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ImageReaderFactory.java	2001/07/30 20:29:27	1.6
  +++ ImageReaderFactory.java	2001/11/16 19:36:40	1.7
  @@ -1,5 +1,5 @@
   /*
  - * $Id: ImageReaderFactory.java,v 1.6 2001/07/30 20:29:27 tore Exp $
  + * $Id: ImageReaderFactory.java,v 1.7 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -42,6 +42,7 @@
           formats.addElement(new GIFReader());
           formats.addElement(new PNGReader());
           formats.addElement(new TIFFReader());
  +        formats.addElement(new EPSReader());
           formats.addElement(new SVGReader());
           //
   
  
  
  
  1.1                  xml-fop/src/org/apache/fop/image/analyser/EPSReader.java
  
  Index: EPSReader.java
  ===================================================================
  /*
   * $Id: EPSReader.java,v 1.1 2001/11/16 19:36:40 tore Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.image.analyser;
  
  // Java
  import java.io.BufferedInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  
  
  // FOP
  import org.apache.fop.messaging.*;
  import org.apache.fop.image.SVGImage;
  
  import org.xml.sax.InputSource;
  import org.xml.sax.XMLReader;
  
  
  /**
   * ImageReader object for SVG document image type.
   */
  public class EPSReader extends AbstractImageReader {
      private long[] bbox;
      private boolean isAscii; // True if plain ascii eps file
      
  	// offsets if not ascii
      long psStart = 0;
      long psLength = 0;
      long wmfStart = 0;
      long wmfLength = 0;
      long tiffStart = 0;
      long tiffLength = 0;
      
  	/** raw eps file */
      private byte[] rawEps;
  	/** eps part */
      private byte[] epsFile;
      private byte[] preview = null;
      
      private long getLong(byte[] buf, int idx) {
          int b1 = buf[idx] & 0xff;
          int b2 = buf[idx+1] & 0xff;
          int b3 = buf[idx+2] & 0xff;
          int b4 = buf[idx+3] & 0xff;
          
          return (long)((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
      }
      
      public boolean verifySignature(String uri, BufferedInputStream fis)
          throws IOException {
          boolean isEPS = false;
          this.imageStream = fis;
          fis.mark(32);
          byte[] header = new byte[30];
          fis.read(header, 0, 30);
          fis.reset();
          
              // Check if binary header
          if (getLong(header, 0) == 0xC6D3D0C5) {
              isAscii = false;
              isEPS = true;
              
              psStart = getLong(header, 4);
              psLength = getLong(header, 8);
              wmfStart = getLong(header, 12);
              wmfLength = getLong(header, 16);
              tiffStart = getLong(header, 20);
              tiffLength = getLong(header, 24);
              
          } else {
                  // Check if plain ascii
              byte[] epsh = "%!PS".getBytes();
              if (epsh[0] == header[0] &&
                  epsh[1] == header[1] &&
                  epsh[2] == header[2] &&
                  epsh[3] == header[3]) {
                  isAscii = true;
                  isEPS = true;
              }
          }
          
          if (isEPS) {
              readEPSImage(fis);
              bbox = readBBox();
              
              if (bbox != null) {
                  width = (int)(bbox[2]-bbox[0]);
                  height = (int)(bbox[3]-bbox[1]);
              } else {
  		 // Ain't eps if no BoundingBox
                  isEPS = false;
              }
          }
          
          return isEPS;
      }
      
  	/** read the eps file and extract eps part */
      private void readEPSImage(BufferedInputStream fis) throws IOException {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          byte[] file;
          byte[] readBuf = new byte[20480];
          int bytes_read;
          int index = 0;
          boolean cont = true;
          
          
          try {
              while ((bytes_read = fis.read(readBuf)) != -1) {
                  baos.write(readBuf, 0, bytes_read);
              }
          } catch (java.io.IOException ex) {
              throw new IOException("Error while loading EPS image " + \
ex.getMessage());  }
          
          file = baos.toByteArray();
          
          if (isAscii) {
              rawEps = null;
              epsFile = new byte[file.length];
              System.arraycopy(file, 0, epsFile, 0, epsFile.length);
          } else {
              rawEps = new byte[file.length];
              epsFile = new byte[(int)psLength];
              System.arraycopy(file, 0, rawEps, 0, rawEps.length);
              System.arraycopy(rawEps, (int)psStart, epsFile, 0, (int)psLength);
          }
      }
      
      public byte[] getEpsFile() {
          return epsFile;
      }
      
  	/* Get embedded preview or null */
      public byte[] getPreview() {
          InputStream is = null;
          if (preview == null) {
              if (tiffLength > 0) {
                  preview = new byte[(int)tiffLength];
                  System.arraycopy(rawEps, (int)tiffStart, preview, 0, \
(int)tiffLength);  }
          }
          return preview;
      }
      
  	/** Extract bounding box from eps part
           */
      private long[] readBBox() {
          long[] mbbox = null;
          int idx = 0;
          byte[] bbxName = "%%BoundingBox: ".getBytes();
          boolean found = false;
          
          while (!found && (epsFile.length  > (idx + bbxName.length))) {
              boolean sfound = true;
              int i = idx;
              for (i = idx; sfound && (i-idx) < bbxName.length; i++) {
                  if (bbxName[i - idx] != epsFile[i])
                      sfound = false;
              }
              if (sfound) {
                  found = true;
                  idx = i;
              } else {
                  idx++;
              }
          }
          
          if (!found)
              return mbbox;
          
          
          mbbox = new long[4];
          idx += readLongString(mbbox, 0, idx);
          idx += readLongString(mbbox, 1, idx);
          idx += readLongString(mbbox, 2, idx);
          idx += readLongString(mbbox, 3, idx);
          
          return mbbox;
      }
      
      private int readLongString(long[] mbbox, int i, int idx) {
          while (idx < epsFile.length &&
                 (epsFile[idx] == 32))
              idx++;
          
          int nidx = idx;
          
          while (nidx < epsFile.length &&
                 (epsFile[nidx] >= 48 && epsFile[nidx] <= 57))
              nidx++;
          
          byte[] num = new byte[nidx - idx];
          System.arraycopy(epsFile, idx, num, 0, nidx-idx);
          String ns = new String(num);
          mbbox[i] = Long.parseLong(ns);
          
          return (1+nidx - idx);
      }
      
      public String getMimeType() {
          return "image/eps";
      }
      
  	/**
           * Return the BoundingBox
           */
      public int[] getBBox() {
          int[] bbox = new int[4];
          bbox[0] = (int)this.bbox[0];
          bbox[1] = (int)this.bbox[1];
          bbox[2] = (int)this.bbox[2];
          bbox[3] = (int)this.bbox[3];
          return bbox;
      }
  }
  
  
  
  
  1.27      +3 -1      xml-fop/src/org/apache/fop/image/FopImageFactory.java
  
  Index: FopImageFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/image/FopImageFactory.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- FopImageFactory.java	2001/11/09 11:32:41	1.26
  +++ FopImageFactory.java	2001/11/16 19:36:40	1.27
  @@ -1,5 +1,5 @@
   /*
  - * $Id: FopImageFactory.java,v 1.26 2001/11/09 11:32:41 keiron Exp $
  + * $Id: FopImageFactory.java,v 1.27 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -132,6 +132,8 @@
           } else if ("image/bmp".equals(imgMimeType)) {
               imgClassName = "org.apache.fop.image.BmpImage";
               // imgClassName = "org.apache.fop.image.JAIImage";
  +        } else if ("image/eps".equals(imgMimeType)) {
  +            imgClassName = "org.apache.fop.image.EPSImage";
           } else if ("image/png".equals(imgMimeType)) {
               imgClassName = "org.apache.fop.image.JimiImage";
               // imgClassName = "org.apache.fop.image.JAIImage";
  
  
  
  1.2       +71 -42    xml-fop/src/org/apache/fop/image/JpegImage.java
  
  Index: JpegImage.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/image/JpegImage.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JpegImage.java	2001/09/18 08:17:07	1.1
  +++ JpegImage.java	2001/11/16 19:36:40	1.2
  @@ -1,5 +1,5 @@
   /*
  - * $Id: JpegImage.java,v 1.1 2001/09/18 08:17:07 keiron Exp $
  + * $Id: JpegImage.java,v 1.2 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -28,30 +28,34 @@
    * @see FopImage
    */
   public class JpegImage extends AbstractFopImage {
  +    boolean found_icc_profile = false;
  +    boolean found_dimensions = false;
  +    
       public JpegImage(URL href) throws FopImageException {
           super(href);
       }
  -
  +    
       public JpegImage(URL href,
                        ImageReader imgReader) throws FopImageException {
           super(href, imgReader);
       }
  -
  +    
       protected void loadImage() throws FopImageException {
           ByteArrayOutputStream baos = new ByteArrayOutputStream();
  +        ByteArrayOutputStream iccStream = new ByteArrayOutputStream();
           InputStream inStream;
  -
  +        this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_UNKNOWN);
           byte[] readBuf = new byte[4096];
           int bytes_read;
           int index = 0;
           boolean cont = true;
  -
  +        
           this.m_compressionType = new DCTFilter();
           this.m_compressionType.setApplied(true);
  -
  +        
           try {
               inStream = this.m_href.openStream();
  -
  +            
               while ((bytes_read = inStream.read(readBuf)) != -1) {
                   baos.write(readBuf, 0, bytes_read);
               }
  @@ -60,70 +64,96 @@
                                           this.m_href.toString() + " : " + \
ex.getClass() +  " - " + ex.getMessage());
           }
  -
  +        
           this.m_bitmaps = baos.toByteArray();
           this.m_bitsPerPixel = 8;
           this.m_isTransparent = false;
  -
  +        
           if (this.m_bitmaps.length > (index + 2) &&
  -                uByte(this.m_bitmaps[index]) == 255 &&
  -                uByte(this.m_bitmaps[index + 1]) == 216) {
  +            uByte(this.m_bitmaps[index]) == 255 &&
  +            uByte(this.m_bitmaps[index + 1]) == 216) {
               index += 2;
  -
  +            
               while (index < this.m_bitmaps.length && cont) {
  -                //check to be sure this is the begining of a header
  +                    //check to be sure this is the begining of a header
                   if (this.m_bitmaps.length > (index + 2) &&
  -                        uByte(this.m_bitmaps[index]) == 255) {
  -
  -                    //192 or 194 are the header bytes that contain the jpeg width \
height and color depth.  +                    uByte(this.m_bitmaps[index]) == 255) {
  +                    
  +                        //192 or 194 are the header bytes that contain the jpeg \
width height and color depth.  if (uByte(this.m_bitmaps[index + 1]) == 192 ||
  -                            uByte(this.m_bitmaps[index + 1]) == 194) {
  -
  +                        uByte(this.m_bitmaps[index + 1]) == 194) {
  +                        
                           this.m_height = calcBytes(this.m_bitmaps[index + 5],
                                                     this.m_bitmaps[index + 6]);
                           this.m_width = calcBytes(this.m_bitmaps[index + 7],
                                                    this.m_bitmaps[index + 8]);
  -
  +                        
                           if (this.m_bitmaps[index + 9] == 1) {
  -                            this.m_colorSpace = new ColorSpace(
  -                                                  ColorSpace.DEVICE_GRAY);
  +                            \
this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_GRAY);  } else if \
                (this.m_bitmaps[index + 9] == 3) {
  -                            this.m_colorSpace =
  -                              new ColorSpace(ColorSpace.DEVICE_RGB);
  -                        } else {
  +                            \
this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_RGB);  +                        } \
else if (this.m_bitmaps[index + 9] == 4) {  +                            \
this.m_colorSpace.setColorSpace(ColorSpace.DEVICE_CMYK);  +                        }
  +                        
  +                        found_dimensions = true;
  +                        if (found_icc_profile) {
                               cont = false;
  -                            throw new FopImageException(
  -                              "\n2 Error while loading image " +
  -                              this.m_href.toString() +
  -                              " : JpegImage - Invalid JPEG Header (bad color space \
                " +
  -                              this.m_bitmaps[index + 9] + ").");
  +                            break;
                           }
  -
  -                        cont = false;
  -                        break;
  -
  -                    } else { // if (uByte(this.m_bitmaps[index + 1]) == \
headers[headerIndex]) {  +                        index += \
calcBytes(this.m_bitmaps[index + 2],  +                                           \
this.m_bitmaps[index + 3]) + 2;  +                        
  +                    } else if (uByte(this.m_bitmaps[index+1]) == 226 &&
  +                               this.m_bitmaps.length > (index+60)) {
  +                            // Check if ICC profile
  +                        byte[] icc_string = new byte[11];
  +                        System.arraycopy(this.m_bitmaps, index+4, icc_string, 0, \
11);  +                        
  +                        if ("ICC_PROFILE".equals(new String(icc_string))){
  +                            int chunkSize = calcBytes(this.m_bitmaps[index + 2],
  +                                                      this.m_bitmaps[index + 3]) + \
2;  +                            
  +                            if (iccStream.size() == 0)
  +                                iccStream.write(this.m_bitmaps, index+18,
  +                                                chunkSize - 20);
  +                            else
  +                                iccStream.write(this.m_bitmaps, index+16,
  +                                                chunkSize - 18);
  +                            
  +                        }
  +                        
  +                        index += calcBytes(this.m_bitmaps[index + 2],
  +                                           this.m_bitmaps[index + 3]) + 2;
  +                    } else {
                           index += calcBytes(this.m_bitmaps[index + 2],
                                              this.m_bitmaps[index + 3]) + 2;
                       }
  -
  +                    
                   } else {
                       cont = false;
  -                    throw new FopImageException(
  -                      "\n2 Error while loading image " +
  -                      this.m_href.toString() + " : JpegImage - Invalid JPEG Header \
(bad header byte).");  }
               }
           } else {
               throw new FopImageException( "\n1 Error while loading image " +
  -                                         this.m_href.toString() + " : JpegImage - \
Invalid JPEG Header.");  +                                         \
this.m_href.toString() +  +                                         " : JpegImage - \
Invalid JPEG Header.");  +        }
  +        if (iccStream.size() > 0) {
  +            byte[] align = new byte[((iccStream.size()) % 8) + 8];
  +            try {iccStream.write(align);} catch (Exception e) {
  +                throw new FopImageException( "\n1 Error while loading image " +
  +                                             this.m_href.toString() + " : " +
  +                                             e.getMessage());
  +            }
  +            this.m_colorSpace.setICCProfile(iccStream.toByteArray());
           }
       }
  -
  +    
       private int calcBytes(byte bOne, byte bTwo) {
           return (uByte(bOne) * 256) + uByte(bTwo);
       }
  -
  +    
       private int uByte(byte bIn) {
           if (bIn < 0) {
               return 256 + bIn;
  @@ -132,5 +162,4 @@
           }
       }
   }
  -
   
  
  
  
  1.1                  xml-fop/src/org/apache/fop/image/EPSImage.java
  
  Index: EPSImage.java
  ===================================================================
  /*
   * $Id: EPSImage.java,v 1.1 2001/11/16 19:36:40 tore Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.image;
  
  // Java
  import java.net.URL;
  import java.net.URLConnection;
  import java.io.InputStream;
  import java.io.IOException;
  
  // FOP
  import org.apache.fop.apps.Driver;
  import org.apache.fop.messaging.*;
  import org.apache.fop.datatypes.ColorSpace;
  import org.apache.fop.pdf.PDFColor;
  import org.apache.fop.image.analyser.ImageReader;
  import org.apache.fop.image.analyser.EPSReader;
  
  import org.xml.sax.InputSource;
  import org.xml.sax.XMLReader;
  
  
  /**
   * @see AbstractFopImage
   * @see FopImage
   */
  public class EPSImage extends AbstractFopImage {
      private String docName;
      private int[] bbox;
      
      private byte[] epsImage = null;
      private EPSReader epsReader = null;
      
  	/**
           * Initialize docName and bounding box
           */
      private void init(URL href) {
          bbox = new int[4];
          bbox[0] = 0;
          bbox[1] = 0;
          bbox[2] = 0;
          bbox[3] = 0;
          
          docName = href.toString();
      }
      
  	/**
           * Return the name of the eps
           */
      public String getDocName() {
          return docName;
      }
      
  	/**
           * Return the bounding box
           */
      public int[] getBBox() {
          return bbox;
      }
      
      public EPSImage(URL href) throws FopImageException {
          super(href);
          init(href);
      }
      
      public EPSImage(URL href,
                      ImageReader imgReader) throws FopImageException {
          super(href, imgReader);
          init(href);
          if (imgReader instanceof EPSReader) {
              EPSReader eimgReader = (EPSReader)imgReader;
              epsReader = eimgReader;
              epsImage = eimgReader.getEpsFile();
              m_bitmaps = epsImage;
              bbox = eimgReader.getBBox();
          }
      }
      
      protected void loadImage() throws FopImageException {
              // Image is loaded in reader
      }
      
      public byte[] getEPSImage() throws FopImageException {
         	if (epsImage == null)
              MessageHandler.errorln("ERROR LOADING EXTERNAL EPS");
          return epsImage;
      }
      
  }
  
  
  
  1.16      +168 -55   xml-fop/src/org/apache/fop/pdf/PDFXObject.java
  
  Index: PDFXObject.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/pdf/PDFXObject.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- PDFXObject.java	2001/11/12 13:10:11	1.15
  +++ PDFXObject.java	2001/11/16 19:36:40	1.16
  @@ -1,5 +1,5 @@
   /*
  - * $Id: PDFXObject.java,v 1.15 2001/11/12 13:10:11 keiron Exp $
  + * $Id: PDFXObject.java,v 1.16 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -17,7 +17,11 @@
   
   // FOP
   import org.apache.fop.datatypes.ColorSpace;
  +import org.apache.fop.pdf.PDFDocument;
  +import org.apache.fop.pdf.PDFICCStream;
   import org.apache.fop.image.FopImage;
  +import org.apache.fop.image.EPSImage;
  +import org.apache.fop.image.JpegImage;
   import org.apache.fop.image.FopImageException;
   
   /**
  @@ -28,23 +32,51 @@
    * the dictionary just provides information like the stream length
    */
   public class PDFXObject extends PDFObject {
  -
  +    private boolean isPS;
  +    private PDFDocument pdfDoc;
  +    private PDFICCStream pdfICCStream;
  +    
       FopImage fopimage;
       int Xnum;
   
  -
       /**
        * create an Xobject with the given number and name and load the
        * image in the object
        */
       public PDFXObject(int number, int Xnumber, FopImage img) {
  +        this(number, Xnumber, img, null);
  +    }
  +
  +    public PDFXObject(int number, int Xnumber, FopImage img, PDFDocument pdfdoc) {
           super(number);
  +        isPS = false;
           this.Xnum = Xnumber;
           if (img == null)
               MessageHandler.errorln("FISH");
           fopimage = img;
  +        this.pdfDoc = pdfdoc;
  +        pdfICCStream = null;
  +        try {
  +            if (fopimage instanceof JpegImage) {
  +                    /* hasICCProfile is not initialized before
  +                       the bitmaps is read - should maybe fix this in
  +                       the JpegImage instead...
  +                    */
  +                fopimage.getBitmaps();
  +                JpegImage jpegimage = (JpegImage)fopimage;
  +                if (jpegimage.getColorSpace().hasICCProfile()) {
  +                    pdfICCStream = pdfDoc.makePDFICCStream();
  +                    pdfICCStream.setColorSpace(jpegimage.getColorSpace());
  +                    pdfICCStream.addDefaultFilters();
  +                }
  +            }
  +        } catch (Exception e) {
  +            MessageHandler.errorln("Error while reading image " +
  +                                   fopimage.getURL() +
  +                                   ": " + e.getMessage());
  +        }
       }
  -
  +    
       /**
        * @return the PDF XObject number
        */
  @@ -58,66 +90,147 @@
       protected int output(OutputStream stream) throws IOException {
           int length = 0;
           int i = 0;
  -        int x, y;
  -
  +        
           try {
  -            // delegate the stream work to PDFStream
  -            PDFStream imgStream = new PDFStream(0);
  -
  -            imgStream.setData(fopimage.getBitmaps());
  -
  -            /*
  -             * Added by Eric Dalquist
  -             * If the DCT filter hasn't been added to the object we add it here
  -             */
  -            if (fopimage.getPDFFilter() != null) {
  -                imgStream.addFilter(fopimage.getPDFFilter());
  -            }
  -
  -            imgStream.addDefaultFilters();
  -
  -            String dictEntries = imgStream.applyFilters();
  -
  -            String p = this.number + " " + this.generation + " obj\n";
  -            p = p + "<</Type /XObject\n";
  -            p = p + "/Subtype /Image\n";
  -            p = p + "/Name /Im" + Xnum + "\n";
  -            p = p + "/Length " + imgStream.getDataLength() + "\n";
  -            p = p + "/Width " + fopimage.getWidth() + "\n";
  -            p = p + "/Height " + fopimage.getHeight() + "\n";
  -            p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n";
  -            ColorSpace cs = fopimage.getColorSpace();
  -            p = p + "/ColorSpace /" + cs.getColorSpacePDFString() + "\n";
  -            if (fopimage.isTransparent()) {
  -                PDFColor transp = fopimage.getTransparentColor();
  -                p = p + "/Mask [" + transp.red255() + " " + transp.red255()
  -                    + " " + transp.green255() + " " + transp.green255() + " "
  -                    + transp.blue255() + " " + transp.blue255() + "]\n";
  +            if (fopimage instanceof EPSImage) {
  +                isPS = true;
  +                EPSImage epsImage = (EPSImage)fopimage;
  +                int[] bbox = epsImage.getBBox();
  +                int bboxw = bbox[2] - bbox[0];
  +                int bboxh = bbox[3] - bbox[1];
  +                
  +                    // delegate the stream work to PDFStream
  +                PDFStream imgStream = new PDFStream(0);
  +                
  +                StringBuffer preamble = new StringBuffer();
  +                preamble.append("%%BeginDocument: " + epsImage.getDocName() + \
"\n");  +                
  +                preamble.append("userdict begin                 % Push userdict on \
dict stack\n");  +                preamble.append("/PreEPS_state save def\n");
  +                preamble.append("/dict_stack countdictstack def\n");
  +                preamble.append("/ops_count count 1 sub def\n");
  +                preamble.append("/showpage {} def\n");
  +                
  +                
  +                preamble.append((double)(1f/(double)bboxw) + " " + \
(double)(1f/(double)bboxh) + " scale\n");  +            	preamble.append(-bbox[0] + " \
" + (-bbox[1]) + " translate\n");  +            	preamble.append(bbox[0] + " " + \
bbox[1] + " " + bboxw + " " + bboxh + " rectclip\n");  +            \
preamble.append("newpath\n");  +                
  +                StringBuffer post = new StringBuffer();
  +                post.append("%%EndDocument\n");
  +                post.append("count ops_count sub {pop} repeat\n");
  +                post.append("countdictstack dict_stack sub {end} repeat\n");
  +                post.append("PreEPS_state restore\n");
  +                post.append("end % userdict\n");
  +                
  +                byte[] preBytes = preamble.toString().getBytes();
  +                byte[] postBytes = post.toString().getBytes();
  +                byte[] imgData = new byte[preBytes.length + postBytes.length + \
fopimage.getBitmaps().length];  +                
  +                System.arraycopy (preBytes, 0, imgData, 0, preBytes.length);
  +                System.arraycopy (fopimage.getBitmaps(), 0, imgData, \
preBytes.length, fopimage.getBitmaps().length);  +                System.arraycopy \
(postBytes, 0, imgData, preBytes.length + fopimage.getBitmaps().length, \
postBytes.length);  +                
  +                
  +                imgStream.setData(imgData);
  +                imgStream.addDefaultFilters();
  +                
  +                String dictEntries = imgStream.applyFilters();
  +                
  +                String p = this.number + " " + this.generation + " obj\n";
  +                p = p + "<</Type /XObject\n";
  +                p = p + "/Subtype /PS\n";
  +                p = p + "/Length " + imgStream.getDataLength();
  +                
  +	            // don't know if it's the good place (other objects can have \
references to it)  +                fopimage.close();
  +                p = p + dictEntries;
  +                p = p + ">>\n";
  +                
  +	            // push the pdf dictionary on the writer
  +                byte[] pdfBytes = p.getBytes();
  +                stream.write(pdfBytes);
  +                length += pdfBytes.length;
  +	            // push all the image data on  the writer and takes care of length \
for trailer  +                length += imgStream.outputStreamData(stream);
  +                
  +                pdfBytes = ("endobj\n").getBytes();
  +                stream.write(pdfBytes);
  +                length += pdfBytes.length;
  +                
  +            } else {
  +
  +	            // delegate the stream work to PDFStream
  +                PDFStream imgStream = new PDFStream(0);
  +                
  +                imgStream.setData(fopimage.getBitmaps());
  +                
  +	            /*
  +	             * Added by Eric Dalquist
  +	             * If the DCT filter hasn't been added to the object we add it here
  +	             */
  +                if (fopimage.getPDFFilter() != null) {
  +                    imgStream.addFilter(fopimage.getPDFFilter());
  +                }
  +                
  +                imgStream.addDefaultFilters();
  +                
  +                String dictEntries = imgStream.applyFilters();
  +                
  +                String p = this.number + " " + this.generation + " obj\n";
  +                p = p + "<</Type /XObject\n";
  +                p = p + "/Subtype /Image\n";
  +                p = p + "/Name /Im" + Xnum + "\n";
  +                p = p + "/Length " + imgStream.getDataLength() + "\n";
  +                p = p + "/Width " + fopimage.getWidth() + "\n";
  +                p = p + "/Height " + fopimage.getHeight() + "\n";
  +                p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n";
  +                
  +                if (pdfICCStream != null ) {
  +                    p = p + "/ColorSpace [/ICCBased " + \
pdfICCStream.referencePDF() + "]\n";  +                } else {
  +                    ColorSpace cs = fopimage.getColorSpace();
  +                    p = p + "/ColorSpace /" + cs.getColorSpacePDFString() + "\n";
  +                }
  +                
  +                    /* PhotoShop generates CMYK values that's inverse,
  +                       this will invert the values - too bad if it's not a \
PhotoShop image...*/  +                if (fopimage.getColorSpace().getColorSpace() \
== ColorSpace.DEVICE_CMYK) {  +                    p = p + "/Decode [ 1.0 0.0 1.0 0.0 \
1.0 0.0 1.1 0.0 ]\n";  +                }
  +                
  +                if (fopimage.isTransparent()) {
  +                    PDFColor transp = fopimage.getTransparentColor();
  +                    p = p + "/Mask [" + transp.red255() + " " + transp.red255()
  +                        + " " + transp.green255() + " " + transp.green255() + " "
  +                        + transp.blue255() + " " + transp.blue255() + "]\n";
  +                }
  +                p = p + dictEntries;
  +                p = p + ">>\n";
  +                
  +	            // don't know if it's the good place (other objects can have \
references to it)  +                fopimage.close();
  +                
  +	            // push the pdf dictionary on the writer
  +                byte[] pdfBytes = p.getBytes();
  +                stream.write(pdfBytes);
  +                length += pdfBytes.length;
  +	            // push all the image data on  the writer and takes care of length \
for trailer  +                length += imgStream.outputStreamData(stream);
  +                
  +                pdfBytes = ("endobj\n").getBytes();
  +                stream.write(pdfBytes);
  +                length += pdfBytes.length;
               }
  -            p = p + dictEntries;
  -            p = p + ">>\n";
  -
  -            // don't know if it's the good place (other objects can have \
                references to it)
  -            fopimage.close();
  -
  -            // push the pdf dictionary on the writer
  -            byte[] pdfBytes = p.getBytes();
  -            stream.write(pdfBytes);
  -            length += pdfBytes.length;
  -            // push all the image data on  the writer and takes care of length for \
                trailer
  -            length += imgStream.outputStreamData(stream);
  -
  -            pdfBytes = ("endobj\n").getBytes();
  -            stream.write(pdfBytes);
  -            length += pdfBytes.length;
           } catch (FopImageException imgex) {
               MessageHandler.errorln("Error in XObject : "
                                      + imgex.getMessage());
           }
  -
  +        
           return length;
       }
  -
  +    
       byte[] toPDF() {
           return null;
       }
  
  
  
  1.35      +15 -3     xml-fop/src/org/apache/fop/pdf/PDFDocument.java
  
  Index: PDFDocument.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/pdf/PDFDocument.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- PDFDocument.java	2001/11/15 08:12:35	1.34
  +++ PDFDocument.java	2001/11/16 19:36:40	1.35
  @@ -1,5 +1,5 @@
   /*
  - * $Id: PDFDocument.java,v 1.34 2001/11/15 08:12:35 keiron Exp $
  + * $Id: PDFDocument.java,v 1.35 2001/11/16 19:36:40 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -758,7 +758,19 @@
           return encoding;
       }
   
  -
  +        /**
  +         * Create a PDFICCStream
  +         @see PDFXObject
  +         @see org.apache.fop.image.JpegImage
  +         @see org.apache.fop.datatypes.ColorSpace
  +        */
  +    public PDFICCStream makePDFICCStream() {
  +        PDFICCStream iccStream = new PDFICCStream(++this.objectcount);
  +        this.objects.addElement(iccStream);
  +        return iccStream;
  +    }
  +    
  +    
       /**
        * make a Type1 /Font object
        *
  @@ -917,7 +929,7 @@
               return xObject.getXNumber();
           // else, create a new one
           xObject = new PDFXObject(++this.objectcount, ++this.xObjectCount,
  -                                 img);
  +                                 img, this);
           this.objects.add(xObject);
           this.xObjects.add(xObject);
           this.xObjectsMap.put(url, xObject);
  
  
  
  1.1                  xml-fop/src/org/apache/fop/pdf/PDFICCStream.java
  
  Index: PDFICCStream.java
  ===================================================================
  /*
   * $Id: PDFICCStream.java,v 1.1 2001/11/16 19:36:40 tore Exp $
   * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
   * For details on use and redistribution please refer to the
   * LICENSE file included with these sources.
   */
  
  package org.apache.fop.pdf;
  import org.apache.fop.datatypes.ColorSpace;
  
  public class PDFICCStream extends PDFStream {
      private int origLength;
      private int len1, len3;
      private byte[] originalData = null;
      
      private ColorSpace cs;
      
      public void setColorSpace(ColorSpace cs) throws java.io.IOException {
          this.cs = cs;
          setData(cs.getICCProfile());
      }
      
      public PDFICCStream(int num) {
          super(num);
          cs = null;
      }
      
      public PDFICCStream(int num, ColorSpace cs) throws java.io.IOException {
          super(num);
          setColorSpace(cs);
      }
      
          // overload the base object method so we don't have to copy
          // byte arrays around so much
      protected int output(java.io.OutputStream stream)
          throws java.io.IOException {
          int length = 0;
          String filterEntry = applyFilters();
          StringBuffer pb = new StringBuffer();
          pb.append(this.number).append(" ").append(this.generation).append(" obj\n<< \
");  pb.append("/N ").append(cs.getNumComponents()).append(" ");
          
          if (cs.getColorSpace() > 0)
              pb.append("/Alternate /").append(cs.getColorSpacePDFString()).append(" \
");  
          pb.append("/Length ").append((_data.size() + 1)).append(" \
").append(filterEntry);  pb.append(" >>\n");
          byte[] p = pb.toString().getBytes();
          stream.write(p);
          length += p.length;
          length += outputStreamData(stream);
          p = "endobj\n".getBytes();
          stream.write(p);
          length += p.length;
          return length;
      }
  }
  
  
  
  1.3       +7 -3      xml-fop/src/org/apache/fop/render/ps/PSStream.java
  
  Index: PSStream.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/ps/PSStream.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PSStream.java	2001/07/30 20:29:33	1.2
  +++ PSStream.java	2001/11/16 19:36:41	1.3
  @@ -1,5 +1,5 @@
   /*
  - * $Id: PSStream.java,v 1.2 2001/07/30 20:29:33 tore Exp $
  + * $Id: PSStream.java,v 1.3 2001/11/16 19:36:41 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -14,12 +14,16 @@
       public PSStream(OutputStream out) {
           super(out);
       }
  -
  +    
       public void write(String cmd) throws IOException {
           if (cmd.length() > 255)
               throw new RuntimeException("PostScript command exceeded limit of 255 \
characters");  write(cmd.getBytes("US-ASCII"));
           write('\n');
       }
  -
  +    
  +    public void writeByteArr(byte[] cmd) throws IOException {
  +        write(cmd);
  +        write('\n');
  +    }
   }
  
  
  
  1.18      +30 -1     xml-fop/src/org/apache/fop/render/ps/PSRenderer.java
  
  Index: PSRenderer.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/ps/PSRenderer.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- PSRenderer.java	2001/11/02 11:06:08	1.17
  +++ PSRenderer.java	2001/11/16 19:36:41	1.18
  @@ -1,5 +1,5 @@
   /*
  - * $Id: PSRenderer.java,v 1.17 2001/11/02 11:06:08 keiron Exp $
  + * $Id: PSRenderer.java,v 1.18 2001/11/16 19:36:41 tore Exp $
    * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
    * For details on use and redistribution please refer to the
    * LICENSE file included with these sources.
  @@ -311,6 +311,35 @@
           write("%%EndProlog");
           write("%%BeginSetup");
           writeFontDict(fontInfo);
  +
  +        /* Write proc for including EPS */
  +        write("%%BeginResource: procset EPSprocs");
  +        write("%%Title: EPS encapsulation procs");
  +        
  +        write("/BeginEPSF { %def");
  +        write("/b4_Inc_state save def         % Save state for cleanup");
  +        write("/dict_count countdictstack def % Count objects on dict stack");
  +        write("/op_count count 1 sub def      % Count objects on operand stack");
  +        write("userdict begin                 % Push userdict on dict stack");
  +        write("/showpage { } def              % Redefine showpage, { } = null \
proc");  +        write("0 setgray 0 setlinecap         % Prepare graphics state");
  +        write("1 setlinewidth 0 setlinejoin");
  +        write("10 setmiterlimit [ ] 0 setdash newpath");
  +        write("/languagelevel where           % If level not equal to 1 then");
  +        write("{pop languagelevel             % set strokeadjust and");
  +        write("1 ne                           % overprint to their defaults.");
  +        write("{false setstrokeadjust false setoverprint");
  +        write("} if");
  +        write("} if");
  +        write("} bind def");
  +        
  +        write("/EndEPSF { %def");
  +        write("count op_count sub {pop} repeat            % Clean up stacks");
  +        write("countdictstack dict_count sub {end} repeat");
  +        write("b4_Inc_state restore");
  +        write("} bind def");
  +        write("%%EndResource");
  +        
           write("%%EndSetup");
           write("FOPFonts begin");
       }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: fop-cvs-help@xml.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic