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;
}
}
