Title: Some changes to reflect DPI stored in images

Currently, I changed only JPEG class to reflect DPI.
To add support to other image types, only change
the corresponding analyzer.
I compile this changes with FOP 0.20.2 without any errors

/*****************************************************************/
/* org.apache.fop.fo.flow.ExternalGraphic */
/* changed function "layout" of ExternalGraphic class */
/* here is only short fragment of changed code */
/*****************************************************************/
    public Status layout(Area area) throws FOPException {

        try {
            FopImage img = FopImageFactory.Make(src);
            // if width / height needs to be computed
            if ((width == 0) || (height == 0)) {
                // aspect ratio
                double imgWidth = img.getWidth();
                double imgHeight = img.getHeight();
                int imgDPIx = img.getDPIx();
                int imgDPIy = img.getDPIy();

                if ((imgDPIx > 0)&&(imgDPIy > 0))
                {
                          // 72 dpi is the default resolution of PDF
                    imgWidth = (int)(imgWidth*72/imgDPIx);
                    imgHeight = (int)(imgHeight*72/imgDPIx);
                }

                if ((width == 0) && (height == 0)) {
                    width = (int)((imgWidth * 1000d));
                    height = (int)((imgHeight * 1000d));
                } else if (height == 0) {
                    height = (int)((imgHeight * ((double)width)) / imgWidth);
                } else if (width == 0) {
                    width = (int)((imgWidth * ((double)height)) / imgHeight);
                }
            }
            // scale image if it doesn't fit in the area/page
            // Need to be more tested...
...........

/*****************************************************************/
/* org.apache.fop.image.FopImage */
/* added 2 function to FopImage interface*/
/*****************************************************************/

public interface FopImage {

    // image DPI
    public int getDPIx() throws FopImageException;
    public int getDPIy() throws FopImageException;

}
/*****************************************************************/
/* org.apache.fop.image.AbstractFopImage */
/* some changes to support DPI */
/*****************************************************************/

public abstract class AbstractFopImage implements FopImage {

    /**
     * Image DPI horizontal (in dots per inch).
     */
    protected int m_dpi_x = 0;

    /**
     * Image DPI vertical (in dots per inch).
     */
    protected int m_dpi_y = 0;

    /**
     * Constructor.
     * Construct a new FopImage object and initialize its default properties:
     * <UL>
     * <LI>image width
     * <LI>image height
     * </UL>
     * The image data isn't kept in memory.
     * @param href image URL
     * @return a new FopImage object
     * @exception FopImageException an error occured during initialization
     */
    public AbstractFopImage(URL href) throws FopImageException {
        this.m_href = href;
        try {
            this.m_imageReader =
                ImageReaderFactory.Make(this.m_href.toExternalForm(),
                                        this.m_href.openStream());
        } catch (Exception e) {
            throw new FopImageException(e.getMessage());
        }
        this.m_width = this.m_imageReader.getWidth();
        this.m_height = this.m_imageReader.getHeight();
        this.m_dpi_x = this.m_imageReader.getDPIx();
        this.m_dpi_y = this.m_imageReader.getDPIy();
    }

    /**
     * Constructor.
     * Construct a new FopImage object and initialize its default properties:
     * <UL>
     * <LI>image width
     * <LI>image height
     * </UL>
     * The image data isn't kept in memory.
     * @param href image URL
     * imgReader ImageReader object
     * @return a new FopImage object
     * @exception FopImageException an error occured during initialization
     */
    public AbstractFopImage(URL href,
                            ImageReader imgReader) throws FopImageException {
        this.m_href = href;
        this.m_imageReader = imgReader;
        this.m_width = this.m_imageReader.getWidth();
        this.m_height = this.m_imageReader.getHeight();
        this.m_dpi_x = this.m_imageReader.getDPIx();
        this.m_dpi_y = this.m_imageReader.getDPIy();
    }

    /**
     * Return the image DPI horizontal
     * @return the image DPI horizontal
     * @exception FopImageException an error occured during property retriaval
     */
    public int getDPIx() throws FopImageException {
        if (this.m_dpi_x == 0)
            this.loadImage();

        return this.m_dpi_x;
    }

    /**
     * Return the image DPI vertical.
     * @return the image DPI vertical
     * @exception FopImageException an error occured during property retriaval
     */
    public int getDPIy() throws FopImageException {
        if (this.m_dpi_y == 0)
            this.loadImage();

        return this.m_dpi_y;
    }
}

/*****************************************************************/
/* org.apache.fop.image.analyzer.AbstractImageReader */
/* added 2 function an property to AbstractImageReader class */
/*****************************************************************/
public abstract class AbstractImageReader implements ImageReader {

    /**
     * Image dpi horizontal.
     */
    protected int dpi_x = 0;

    /**
     * Image dpi vertical.
     */
    protected int dpi_y = 0;

    public int getDPIx() {
        return this.dpi_x;
    }

    public int getDPIy() {
        return this.dpi_y;
    }

}

/*****************************************************************/
/* org.apache.fop.image.analyzer.ImageReader */
/* added 2 function to ImageReader interface */
/*****************************************************************/

public interface ImageReader {

    /**
     * Return the image dpi
     * @return image dpi horizontal
     */
    public int getDPIx();

    /**
     * Return the image dpi.
     * @return image dpi vertical
     */
    public int getDPIy();
}

/*****************************************************************/
/* org.apache.fop.image.analyzer.JPEGReader */
/* changed only function setDimension       */
/*****************************************************************/
    protected void setDimension() throws IOException {
        try {
            int marker = NULL, units, xDensity, yDensity;
            long length, skipped;
            byte[] buf = new byte[5];
            outer:
            while (imageStream.available() > 0) {
                while ((marker = imageStream.read()) != MARK) {
                    ;
                }
                do {
                    marker = imageStream.read();
                } while (marker == MARK);
                switch (marker) {
                case SOI:
                    break;
                case NULL:
                    break;
                case SOF1:
                case SOF2:
                case SOF3:    // SOF3 and SOFA are only supported by PDF 1.3
                case SOFA:
                    this.skip(3);
                    this.height = this.read2bytes();
                    this.width = this.read2bytes();
                    break outer;
                case APP0:
                    this.skip(2);
                    //check for "JFIF" in APP0 marker segment
                    for (byte i=0;i<5;i++) buf[i] = (byte)(imageStream.read());
                    if ((buf[0] != 0x4A)||(buf[1] != 0x46)||(buf[2] != 0x49)||
                        (buf[3] != 0x46)||(buf[4] != 0x00)) break outer;

                    this.skip(2);
                    units = imageStream.read();
                    xDensity = this.read2bytes();
                    yDensity = this.read2bytes();
                    if (units == 2) // pixels per centimeter
                    {
                        this.dpi_x = (int)(xDensity / 2.54);
                        this.dpi_y = (int)(yDensity / 2.54);
                    }
                    else if (units == 1) // pixels per inch
                    {
                        this.dpi_x = xDensity;
                        this.dpi_y = yDensity;
                    }
                    break outer;
                default:
                    length = this.read2bytes();
                    skipped = this.skip(length - 2);
                    if (skipped != length - 2)
                        throw new IOException("Skipping Error");
                }
            }
        } catch (IOException ioe) {
            try {
                this.imageStream.reset();
            } catch (IOException exbis) {}
            throw ioe;
        }
    }

Reply via email to