Browse Source

AFP Renderer: Bugfix for 1 bit images where the width is not a multiple of 8.

Essentially, I rewrote convertToGrayScaleImage() to properly padding at the end of each scanline if necessary.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@561280 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_95beta
Jeremias Maerki 17 years ago
parent
commit
f088e7bbf9
2 changed files with 55 additions and 31 deletions
  1. 47
    26
      src/java/org/apache/fop/render/afp/AFPRenderer.java
  2. 8
    5
      status.xml

+ 47
- 26
src/java/org/apache/fop/render/afp/AFPRenderer.java View File

import org.apache.fop.area.RegionReference; import org.apache.fop.area.RegionReference;
import org.apache.fop.area.RegionViewport; import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait; import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.TextArea;
import org.apache.fop.area.inline.WordArea; import org.apache.fop.area.inline.WordArea;
import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContext;
import org.apache.fop.render.afp.extensions.AFPElementMapping; import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPPageSetup; import org.apache.fop.render.afp.extensions.AFPPageSetup;
import org.apache.fop.render.afp.fonts.AFPFontInfo;
import org.apache.fop.render.afp.fonts.AFPFont; import org.apache.fop.render.afp.fonts.AFPFont;
import org.apache.fop.render.afp.fonts.AFPFontInfo;
import org.apache.fop.render.afp.fonts.CharacterSet; import org.apache.fop.render.afp.fonts.CharacterSet;
import org.apache.fop.render.afp.fonts.FopCharacterSet; import org.apache.fop.render.afp.fonts.FopCharacterSet;
import org.apache.fop.render.afp.fonts.OutlineFont; import org.apache.fop.render.afp.fonts.OutlineFont;
if (!fopimage.load(FopImage.BITMAP)) { if (!fopimage.load(FopImage.BITMAP)) {
return; return;
} }
convertToGrayScaleImage(io, fopimage.getBitmaps());
convertToGrayScaleImage(io, fopimage.getBitmaps(),
fopimage.getWidth(), fopimage.getHeight());
} }
} else { } else {
if (!fopimage.load(FopImage.BITMAP)) { if (!fopimage.load(FopImage.BITMAP)) {
return; return;
} }
convertToGrayScaleImage(io, fopimage.getBitmaps());
convertToGrayScaleImage(io, fopimage.getBitmaps(),
fopimage.getWidth(), fopimage.getHeight());
} }
} else { } else {
if (!fopimage.load(FopImage.BITMAP)) { if (!fopimage.load(FopImage.BITMAP)) {
io.setImageIDESize((byte)24); io.setImageIDESize((byte)24);
io.setImageData(fopimage.getBitmaps()); io.setImageData(fopimage.getBitmaps());
} else { } else {
convertToGrayScaleImage(io, fopimage.getBitmaps());
convertToGrayScaleImage(io, fopimage.getBitmaps(),
fopimage.getWidth(), fopimage.getHeight());
} }
} }
} }
} else { } else {
//TODO Teach it how to handle grayscale BufferedImages directly //TODO Teach it how to handle grayscale BufferedImages directly
//because this is pretty inefficient //because this is pretty inefficient
convertToGrayScaleImage(io, buf);
convertToGrayScaleImage(io, buf, bi.getWidth(), bi.getHeight());
} }
} catch (IOException ioe) { } catch (IOException ioe) {
log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe); log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
return (int)Math.round(mpt / DPI_CONVERSION_FACTOR_240); return (int)Math.round(mpt / DPI_CONVERSION_FACTOR_240);
} }


private void convertToGrayScaleImage(ImageObject io, byte[] raw) {
/**
* Converts a byte array containing 24 bit RGB image data to a grayscale image.
* @param io the target image object
* @param raw the buffer containing the RGB image data
* @param width the width of the image in pixels
* @param height the height of the image in pixels
*/
private void convertToGrayScaleImage(ImageObject io, byte[] raw, int width, int height) {
int pixelsPerByte = 8 / bitsPerPixel; int pixelsPerByte = 8 / bitsPerPixel;
byte[] bw = new byte[raw.length / (3 * pixelsPerByte)];
int k = 0;
for (int i = 0, j = 0; i < raw.length; i += 3, j++) {
if (j == pixelsPerByte) {
j = 0;
k++;
if (k == bw.length) {
break;
}
}
// see http://www.jguru.com/faq/view.jsp?EID=221919
double greyVal = 0.212671d * ((int) raw[i] & 0xff)
+ 0.715160d * ((int) raw[i + 1] & 0xff)
+ 0.072169d * ((int) raw[i + 2] & 0xff);
switch (bitsPerPixel) {
int bytewidth = (width / pixelsPerByte);
if ((width % pixelsPerByte) != 0) {
bytewidth++;
}
byte[] bw = new byte[height * bytewidth];
byte ib;
for (int y = 0; y < height; y++) {
ib = 0;
int i = 3 * y * width;
for (int x = 0; x < width; x++, i += 3) {
// see http://www.jguru.com/faq/view.jsp?EID=221919
double greyVal = 0.212671d * ((int) raw[i] & 0xff)
+ 0.715160d * ((int) raw[i + 1] & 0xff)
+ 0.072169d * ((int) raw[i + 2] & 0xff);

switch (bitsPerPixel) {
case 1: case 1:
if (greyVal > 128) {
bw[k] |= (byte)(1 << j);
if (greyVal < 128) {
ib |= (byte)(1 << (7 - (x % 8)));
} }
break; break;
case 4: case 4:
greyVal /= 16; greyVal /= 16;
bw[k] |= (byte)((byte)greyVal << (j * 4));
ib |= (byte)((byte)greyVal << ((1 - (x % 2)) * 4));
break; break;
case 8: case 8:
bw[k] = (byte)greyVal;
ib = (byte)greyVal;
break; break;
default:
throw new UnsupportedOperationException(
"Unsupported bits per pixel: " + bitsPerPixel);
}
if ((x % pixelsPerByte) == (pixelsPerByte - 1) || ((x + 1) == width)) {
bw[(y * bytewidth) + (x / pixelsPerByte)] = ib;
ib = 0;
}
} }
} }
io.setImageIDESize((byte)bitsPerPixel); io.setImageIDESize((byte)bitsPerPixel);

+ 8
- 5
status.xml View File



<changes> <changes>
<release version="FOP Trunk"> <release version="FOP Trunk">
<action context="code" dev="MM" type="add">
<action context="Code" dev="JM" type="fix">
AFP Renderer: Bugfix for 1 bit images where the width is not a multiple of 8.
</action>
<action context="Code" dev="MM" type="add">
Support for keep-together.within-line="always". Support for keep-together.within-line="always".
</action> </action>
<action context="Code" dev="MM" type="fix"> <action context="Code" dev="MM" type="fix">
Fixed incomplete support for Unicode Word Joiner characters (U+2060 and U+FEFF). Fixed incomplete support for Unicode Word Joiner characters (U+2060 and U+FEFF).
</action> </action>
<action context="code" dev="AD" type="add" fixes-bug="42785" due-to="Max Berger">
<action context="Code" dev="AD" type="add" fixes-bug="42785" due-to="Max Berger">
Support alignment-adjust for images. Support alignment-adjust for images.
</action> </action>
<action context="code" dev="AD" type="add" fixes-bug="41044" due-to="Richard Wheeldon">
<action context="Code" dev="AD" type="add" fixes-bug="41044" due-to="Richard Wheeldon">
Partial application of the patch in Bugzilla 41044: Partial application of the patch in Bugzilla 41044:
* addition of a generic PropertyCache to be used by all Property * addition of a generic PropertyCache to be used by all Property
types that can be safely canonicalized types that can be safely canonicalized
* modified EnumProperty, StringProperty, NumberProperty, EnumNumber * modified EnumProperty, StringProperty, NumberProperty, EnumNumber
and FixedLength to make use of the cache infrastructure and FixedLength to make use of the cache infrastructure
</action> </action>
<action context="code" dev="AD" type="update" fixes-bug="41656">
<action context="Code" dev="AD" type="update" fixes-bug="41656">
Refactoring in the fo package: Refactoring in the fo package:
-> removal of the childNodes instance member in fop.fo.FObj -> removal of the childNodes instance member in fop.fo.FObj
-> addition of a firstChild instance member in fop.fo.FObj -> addition of a firstChild instance member in fop.fo.FObj
-> addition of a FONodeIterator interface in FONode + corresponding implementation in FObj -> addition of a FONodeIterator interface in FONode + corresponding implementation in FObj
-> changed implementations of FObj.addChildNode(), .removeChild() and .getChildNodes() -> changed implementations of FObj.addChildNode(), .removeChild() and .getChildNodes()
</action> </action>
<action context="code" dev="AD" type="update" fixes-bug="42089" due-to="Adrian Cumiskey">
<action context="Code" dev="AD" type="update" fixes-bug="42089" due-to="Adrian Cumiskey">
Code cleanup and restructuring: Code cleanup and restructuring:
Refactoring of PageSequenceLayoutManager and provide common FObj id property use Refactoring of PageSequenceLayoutManager and provide common FObj id property use
</action> </action>

Loading…
Cancel
Save