[ 
https://issues.apache.org/jira/browse/FOP-2847?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Tobias Hain updated FOP-2847:
-----------------------------
    Description: 
h4. TL;NR

When using palette-based transparency via tRNS chunk in PNG images, the 
generated PDFs are broken.
h4. palette-based with transparency.
{quote}*8.5.2. Palette-Based with Transparency*

"The PNG spec forbids the use of a full alpha channel with palette-based 
images, but it does allow `cheap alpha` via the transparency chunk, tRNS [...] 
In effect, it transforms the palette from an RGB lookup table to an RGBA table 
[...] a single PNG transparency entry should come first"
{quote}
[http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.5.2]
h4. general PDF encoding strategy

Option 1:
{quote}most libraries just undo the palettization and use a full color image + 
mask.
{quote}
[https://forums.adobe.com/message/6148131#6148131]

Option 2:
{quote}SMask would be simpler since you could leave the palette in place
{quote}
[https://forums.adobe.com/message/6148557#6148557]
h4. what does FOP do

It creates a chroma-key mask:
{code:java}
 /Type /XObject
  /ColorSpace [/Indexed /DeviceRGB 255 <D9DB ...>]
  /Mask [182 182 151 151 158 158]
{code}
Acrobat Reader even fails to read those files while PDF viewers embedded into 
Chrome/Firefox read the file, but show visual glitches.

FOP doesn't implement Option 1 yet. None of the ImageLoaders is prepared to do 
that:
 [https://wiki.apache.org/xmlgraphics-fop/HowTo/ImageLoaderRawPNG]
 In fact the following results in missing Option 2:
{code:java}
public void setup(PDFDocument doc) {
  RenderedImage ri = getImage().getRenderedImage();
  // code deleted
  Raster raster = GraphicsUtil.getAlphaRaster(ri);
  if (raster != null) {
    AlphaRasterImage alphaImage = new AlphaRasterImage("Mask:" + getKey(), 
raster);
    this.softMask = doc.addImage(null, alphaImage).makeReference();
  }
{code}
[https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java]

In the above code raster will be null and therefore FOP fails to initialize a 
softMask. {{GraphicsUtil.getAlphaRaster()}} calls internally 
{{ColorModel.getAlphaRaster()}}, which returns null:
{quote}If this is an IndexColorModel which has alpha in the lookup table, this 
method will return null since there is no spatially discrete alpha channel.
{quote}
[https://docs.oracle.com/javase/8/docs/api/index.html?java/awt/image/ColorModel.html]

This code will then add the chroma key mask to the image:
{code:java}
protected void populateXObjectDictionaryForIndexColorModel(PDFDictionary dict, 
IndexColorModel icm) {
  // code deleted
  Integer index = getIndexOfFirstTransparentColorInPalette(icm);
  if (index != null) {
    PDFArray mask = new PDFArray(dict);
    mask.add(index);
    mask.add(index);
    dict.put("Mask", mask);
  }
}
{code}
[https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/AbstractImageAdapter.java]
h4. why care to support?

Libraries such as pngquant optimize images for web usage and low footprint and 
can not be used directly with Apache FOP as source images:
{quote}"*pngquant*: Lossy PNG optimizer, reducing a PNG image down to an 8 bit 
color palette with dithering. It will build indexed-color PNG's with alpha 
transparency colors conveyed in the tRNS chunk."
{quote}
[https://imagemagick.org/Usage/formats/#png_non-im]

 h4. sample data

{code}
!
{code}

  was:
h4.  TL;NR
When using palette-based transparency via tRNS chunk in PNG images, the 
generated PDFs are broken.
 
h4.  palette-based with transparency.
{quote}*8.5.2. Palette-Based with Transparency*

"The PNG spec forbids the use of a full alpha channel with palette-based 
images, but it does allow `cheap alpha` via the transparency chunk, tRNS [...] 
In effect, it transforms the palette from an RGB lookup table to an RGBA table 
[...]  a single PNG transparency entry should come first"{quote}
http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.5.2

h4. general PDF encoding strategy

Option 1:
{quote}most libraries just undo the palettization and use a full color image + 
mask.{quote}
https://forums.adobe.com/message/6148131#6148131

Option 2:
{quote}SMask would be simpler since you could leave the palette in place{quote}
https://forums.adobe.com/message/6148557#6148557

h4. what does FOP do

It creates a chroma-key mask:
 
{code}
 /Type /XObject
  /ColorSpace [/Indexed /DeviceRGB 255 <D9DB ...>]
  /Mask [182 182 151 151 158 158]
{code}

Acrobat Reader even fails to read those files while PDF viewers embedded into 
Chrome/Firefox read the file, but show visual glitches.

FOP doesn't implement Option 1 yet. None of the ImageLoaders is prepared to do 
that:
https://wiki.apache.org/xmlgraphics-fop/HowTo/ImageLoaderRawPNG
In fact the following results in missing Option 2:

{code}
public void setup(PDFDocument doc) {
  RenderedImage ri = getImage().getRenderedImage();
  // code deleted
  Raster raster = GraphicsUtil.getAlphaRaster(ri);
  if (raster != null) {
    AlphaRasterImage alphaImage = new AlphaRasterImage("Mask:" + getKey(), 
raster);
    this.softMask = doc.addImage(null, alphaImage).makeReference();
  }
{code}
https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java

In the above code raster will be null and therefore FOP fails to initialize a 
softMask. {{GraphicsUtil.getAlphaRaster()}} calls internally 
{{ColorModel.getAlphaRaster()}}, which returns null:
{quote}If this is an IndexColorModel which has alpha in the lookup table, this 
method will return null since there is no spatially discrete alpha 
channel.{quote}  
https://docs.oracle.com/javase/8/docs/api/index.html?java/awt/image/ColorModel.html

This code will then add the chroma key mask to the image:
{code}
protected void populateXObjectDictionaryForIndexColorModel(PDFDictionary dict, 
IndexColorModel icm) {
  // code deleted
  Integer index = getIndexOfFirstTransparentColorInPalette(icm);
  if (index != null) {
    PDFArray mask = new PDFArray(dict);
    mask.add(index);
    mask.add(index);
    dict.put("Mask", mask);
  }
}
{code}
https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/AbstractImageAdapter.java

h4. why care to support?

Libraries such as pngquant optimize images for web usage and low footprint and 
can not be used directly with Apache FOP as source images:
{quote}"*pngquant*: Lossy PNG optimizer, reducing a PNG image down to an 8 bit 
color palette with dithering. It will build indexed-color PNG's with alpha 
transparency colors conveyed in the tRNS chunk."{quote}
https://imagemagick.org/Usage/formats/#png_non-im



> Support palette-based transparency via tRNS chunk of PNG images in PDF export
> -----------------------------------------------------------------------------
>
>                 Key: FOP-2847
>                 URL: https://issues.apache.org/jira/browse/FOP-2847
>             Project: FOP
>          Issue Type: Bug
>          Components: renderer/pdf
>    Affects Versions: 2.3
>            Reporter: Tobias Hain
>            Priority: Major
>         Attachments: sample_image_palette_tRNS.png
>
>
> h4. TL;NR
> When using palette-based transparency via tRNS chunk in PNG images, the 
> generated PDFs are broken.
> h4. palette-based with transparency.
> {quote}*8.5.2. Palette-Based with Transparency*
> "The PNG spec forbids the use of a full alpha channel with palette-based 
> images, but it does allow `cheap alpha` via the transparency chunk, tRNS 
> [...] In effect, it transforms the palette from an RGB lookup table to an 
> RGBA table [...] a single PNG transparency entry should come first"
> {quote}
> [http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.5.2]
> h4. general PDF encoding strategy
> Option 1:
> {quote}most libraries just undo the palettization and use a full color image 
> + mask.
> {quote}
> [https://forums.adobe.com/message/6148131#6148131]
> Option 2:
> {quote}SMask would be simpler since you could leave the palette in place
> {quote}
> [https://forums.adobe.com/message/6148557#6148557]
> h4. what does FOP do
> It creates a chroma-key mask:
> {code:java}
>  /Type /XObject
>   /ColorSpace [/Indexed /DeviceRGB 255 <D9DB ...>]
>   /Mask [182 182 151 151 158 158]
> {code}
> Acrobat Reader even fails to read those files while PDF viewers embedded into 
> Chrome/Firefox read the file, but show visual glitches.
> FOP doesn't implement Option 1 yet. None of the ImageLoaders is prepared to 
> do that:
>  [https://wiki.apache.org/xmlgraphics-fop/HowTo/ImageLoaderRawPNG]
>  In fact the following results in missing Option 2:
> {code:java}
> public void setup(PDFDocument doc) {
>   RenderedImage ri = getImage().getRenderedImage();
>   // code deleted
>   Raster raster = GraphicsUtil.getAlphaRaster(ri);
>   if (raster != null) {
>     AlphaRasterImage alphaImage = new AlphaRasterImage("Mask:" + getKey(), 
> raster);
>     this.softMask = doc.addImage(null, alphaImage).makeReference();
>   }
> {code}
> [https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java]
> In the above code raster will be null and therefore FOP fails to initialize a 
> softMask. {{GraphicsUtil.getAlphaRaster()}} calls internally 
> {{ColorModel.getAlphaRaster()}}, which returns null:
> {quote}If this is an IndexColorModel which has alpha in the lookup table, 
> this method will return null since there is no spatially discrete alpha 
> channel.
> {quote}
> [https://docs.oracle.com/javase/8/docs/api/index.html?java/awt/image/ColorModel.html]
> This code will then add the chroma key mask to the image:
> {code:java}
> protected void populateXObjectDictionaryForIndexColorModel(PDFDictionary 
> dict, IndexColorModel icm) {
>   // code deleted
>   Integer index = getIndexOfFirstTransparentColorInPalette(icm);
>   if (index != null) {
>     PDFArray mask = new PDFArray(dict);
>     mask.add(index);
>     mask.add(index);
>     dict.put("Mask", mask);
>   }
> }
> {code}
> [https://github.com/apache/fop/blob/ff452f3685a02715aee791d651b58dd1797ddfd4/fop-core/src/main/java/org/apache/fop/render/pdf/AbstractImageAdapter.java]
> h4. why care to support?
> Libraries such as pngquant optimize images for web usage and low footprint 
> and can not be used directly with Apache FOP as source images:
> {quote}"*pngquant*: Lossy PNG optimizer, reducing a PNG image down to an 8 
> bit color palette with dithering. It will build indexed-color PNG's with 
> alpha transparency colors conveyed in the tRNS chunk."
> {quote}
> [https://imagemagick.org/Usage/formats/#png_non-im]
>  h4. sample data
> {code}
> !
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to