You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by Eric SCHAEFFER <es...@posterconseil.com> on 2000/05/11 11:24:37 UTC

Image Support Final (I hope)

Ok, we need to go ahead!

FOPImage Interface :

package org.apache.fop.image;

import org.apache.fop.datatypes.ColorSpace;
import org.apache.fop.datatypes.CompressionFilter;
import org.apache.fop.pdf.PDFColor;

public interface FOPImage {
 // constructors

 // load image headers to init the object.
 // If href protocol isn't file://, can load the entire image
 // and keep it in memory.
 // Should cache the input stream, and load data when needed.
 public FOPImage(URL href) throws FOPImageException;
 // init only the image size, and load image data when needed.
 public FOPImage(URL href, int width, int height) throws FOPImageException;

 // get image general properties

 // Ressource location
 public String getURL();

 // image size
 public int getWidth();
 public int getHeight();

 // DeviceGray, DeviceRGB, or DeviceCMYK
 public ColorSpace getColorSpace() throws FOPImageException;

 // bits per pixel
 public int getBitsPerPixel() throws FOPImageException;

 // For transparent images
 boolean isTransparent() throws FOPImageException;
 PDFColor getTransparentColor() throws FOPImageException;

 // get the image bytes, and bytes properties

 // get uncompressed image bytes
 public byte[] getBitmaps() throws FOPImageException;
// width * (bitsPerPixel / 8) * height, no ?
 public int getBitmapsSize() throws FOPImageException;

 // get compressed image bytes
 // I don't know if we really need it, nor if it
 // should be changed...
 public byte[] getRessourceBytes() throws FOPImageException;
 public int getRessourceBytesSize() throws FOPImageException;
 public CompressionFilter getCompressionFilter() throws FOPImageException,
UnsupportedFilterException;

 // release memory
 public void close();
}

I introduce a new class : org.apache.fop.datatypes.CompressionFilter
This class handle PDF filters compression. The problem is that they can be
chained, and I want this class to be able to return the PDF string
corresponding to the compressed data. And the PDF syntax says that all filters
are written first, before the compressed data.

For this, I suggest a class org.apache.fop.datatypes.Filter to represent a
filter (I don't know what's the best : an interface, and classes to represent
the differents PDF filters and their specific parameters or a single class and
a method to set specific parameters in a key/value way), and another class
org.apache.fop.pdf.PDFFilters that can compress data using one or several
filters.

public class PDFFilters {
    public PDFFilters();
    public void setData(byte[] data);
    public void encode(CompressionFilter filter);
    public String toString();
    public void write(Stream st);
    ... etc ...
}

I don't know how the viewer works, but it could be interresting to use this
class to do the reverse work: read a string or a stream and decode binary
data.

The only question that I always have is : how to avoid decompression and
(re)compression if the compression filter can be used directly in the PDF
stream ?


Eric.

_______________________________________

Eric SCHAEFFER
eschaeffer@posterconseil.com

POSTER CONSEIL
118 rue de Tocqueville
75017 PARIS
FRANCE
Tel. : 33-140541058
Fax : 33-140541059
_______________________________________

-------------------------------------------------------------------
 Missed us in Orlando? Make it up with ApacheCON Europe in London!
------------------------- http://ApacheCon.Com --------------------



Re: Correction - Image Support Final (I hope)

Posted by Eric SCHAEFFER <es...@posterconseil.com>.
Hi,

If width/height properties depends on the real image size, then the renderer
must ask the FOPImage object its size (there's no other way).

The point is that's the renderer that makes the choice to ask for the real
image size or not. Thus, the FOPImage object can retrieve the image size at
construction if it's easier, but it's not an obligation.


Eric.

----- Original Message -----
From: Sebastian Rahtz <se...@computing-services.oxford.ac.uk>
To: <fo...@xml.apache.org>
Sent: Saturday, May 13, 2000 5:18 PM
Subject: Re: Correction - Image Support Final (I hope)


> Eric SCHAEFFER writes:
>
>  > If the XSL fo instruction contain the rendered image size, then the
>  > PDF writer don't have to request the real image size to compute the
>  > area size, and the FOPImage object don't have to recover the real
>  > image size at construction.
>
> and when width="50%"?
>
> Sebastian
>


Re: Correction - Image Support Final (I hope)

Posted by Sebastian Rahtz <se...@computing-services.oxford.ac.uk>.
Eric SCHAEFFER writes:

 > If the XSL fo instruction contain the rendered image size, then the
 > PDF writer don't have to request the real image size to compute the
 > area size, and the FOPImage object don't have to recover the real
 > image size at construction.

and when width="50%"?

Sebastian


Correction - Image Support Final (I hope)

Posted by Eric SCHAEFFER <es...@posterconseil.com>.
He guys, we going to the wrong way ! I thought about it yesterday evening :

In XSL, the width and height properties only tell us the desired rendered
image size. The FOPImage interface is here to represent an image, thus the
getWidth() and getHeight() methods must give us the real image size.

So, we don't need, and we should not have, a constructor with the image size.
If the XSL fo instruction contain the rendered image size, then the PDF writer
don't have to request the real image size to compute the area size, and the
FOPImage object don't have to recover the real image size at construction.

Simple, no ? (I'm so stupid sometimes ;-)

The FOPImage interface don't have to take care of the implementation (of
course, it should specify things that are possible to implement), it has only
to specify things according to the needs of objects that use it.
Thus, when implementing the FOPImage interface, do what you want: load only
image headers first, cache input stream, keep image in memory... Just do for
the best.

To represent PDF compression filters, we need a PDFFilter class. As I wrote it
in my previous mail, we should be able to chain them. My only problem is that
each PDF filter has specific parameters. We can use an Hashtable to set the
paramters, but I don't like this way of doing things because we don't control
parameters and we need to know their names. I prefere to have methods for each
parameter type and eventually throw an exception if this parameter isn't
supported for the current filter type.

We also need another class (PDFBinaryStream) to compress binary data using one
or several filters and write it to the PDF stream.

Eric.

Classes:

**********************************
FOPImage interface
**********************************

package org.apache.fop.image;

import org.apache.fop.datatypes.ColorSpace;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFFilter;

public interface FOPImage {
 // Init the object.
 // If href protocol isn't file://, can load the entire image
 // and keep it in memory.
 // Should cache the input stream, and load data when needed.
 public FOPImage(URL href) throws FOPImageException;

 // Get image general properties.
 // Methods throw exception because they can retrieve data
 // when needed.

 // Ressource location
 public String getURL();

 // image size
 public int getWidth() throws FOPImageException;
 public int getHeight() throws FOPImageException;

 // DeviceGray, DeviceRGB, or DeviceCMYK
 public ColorSpace getColorSpace() throws FOPImageException;

 // bits per pixel
 public int getBitsPerPixel() throws FOPImageException;

 // For transparent images
 boolean isTransparent() throws FOPImageException;
 PDFColor getTransparentColor() throws FOPImageException;

 // get the image bytes, and bytes properties

 // get uncompressed image bytes
 public byte[] getBitmaps() throws FOPImageException;
// width * (bitsPerPixel / 8) * height, no ?
 public int getBitmapsSize() throws FOPImageException;

 // get compressed image bytes
 // I don't know if we really need it, nor if it
 // should be changed...
 public byte[] getRessourceBytes() throws FOPImageException;
 public int getRessourceBytesSize() throws FOPImageException;
 // return null if no corresponding PDFFilter
 public PDFFilter getPDFFilter() throws FOPImageException;

 // release memory
 public void close();
}

**********************************
PDFFilter class
**********************************

package org.apache.fop.pdf;

public class PDFFilter {
 public static int ASCII_HEX_DECODE = 1;
 public static int ASCII_85_DECODE = 2;
 public static int LZW_DECODE = 3;
 public static int RUN_LENGTH_DECODE = 4;
 public static int CCITT_FAX_DECODE = 5;
 public static int DCT_DECODE = 6;
 public static int FLAT_DECODE = 7;

 // LZW - Flat
 private Integer m_predictor = null;
 // LZW - Flat - CCITT
 private Integer m_columns = null;
 // LZW - Flat
 private Integer m_colors = null;
 // LZW - Flat
 private Integer m_bitsPerComponent = null;
 // LZW
 private Integer m_earlyChange = null;
 // CCITT
 private Integer m_k = null
 // CCITT
 private Boolean m_endOfLine = null
 // CCITT
 private Boolean m_encodedByteAlign = null
 // CCITT
 private Integer m_rows = null
 // CCITT
 private Boolean m_endOfBlock = null
 // CCITT
 private Boolean m_blackLs1 = null
 // CCITT
 private Integer m_damagedRowsBeforeError = null

 public PDFFilter(int filter) {
  // ...
 }

 public int getType() {
  // ...
 }

 public void setPredictor(int value) throws
UnsupportedFilterParameterException {
  // ...
 }
 public int getPredictor() throws UnsupportedFilterParameterException {
  // ...
 }

// ... etc ...

}

**********************************
PDFBinaryStream class
**********************************

package org.apache.fop.pdf;

// Java
import java.utils.Vector;

public class PDFBinaryStream {

 private byte[] m_data;
 private int m_dataSize;
 private Vector m_filters;

 public PDFBianryStream() {
  // ...
 }

 public void setData(byte[] data) {
  // ...
 }

 public void encode(PDFFilter filter) {
  // ...
 }

 public String toPDF() {
  // ...
 }

}