Bug 92381 - Poppler doesn't display text in separation colorspace with alternate colorspace DeviceGray
Summary: Poppler doesn't display text in separation colorspace with alternate colorspa...
Status: RESOLVED FIXED
Alias: None
Product: poppler
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: poppler-bugs
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-10 10:27 UTC by Thomas Freitag
Modified: 2015-12-02 21:16 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
PDF with text in separation colorspace (604.38 KB, application/pdf)
2015-10-10 10:27 UTC, Thomas Freitag
Details
Same PDF with changed function (605.91 KB, application/pdf)
2015-10-10 12:33 UTC, Thomas Freitag
Details
display text in separation colorspace with inverted function (3.62 KB, patch)
2015-10-10 15:32 UTC, Thomas Freitag
Details | Splinter Review
ignore the alternateSpace and tintTransform (2.56 KB, patch)
2015-10-11 09:47 UTC, Thomas Freitag
Details | Splinter Review
ignore the alternateSpace and tintTransform (2.62 KB, patch)
2015-10-30 10:00 UTC, Thomas Freitag
Details | Splinter Review

Description Thomas Freitag 2015-10-10 10:27:24 UTC
Created attachment 118794 [details]
PDF with text in separation colorspace

The text in the attached PDF is not displayed. Reason for it is the usage of a separation colorspace:

cs /CS0
scn 1

where CS0 is something like

[/Separation/Black/DeviceGray 10 0 R]

I looked into the source code and figured out that "scn 1" results in white color, i.e. RGB(255,255,255). But the PDF spec says for separation colorspaces:

A colour value in a Separation colour space shall consist of a single tint component in the range 0.0 to 1.0. The value 0.0 shall represent the minimum amount of colorant that can be applied; 1.0 shall represent the maximum. Tints shall always be treated as subtractive colours, even if the device produces output for the designated component by an additive method. Thus, a tint value of 0.0 denotes the lightest colour that can be achieved with the given colorant, and 1.0 is the darkest.

Therefore "scn 1" should result in RGB(0,0,0). 

I have already a solution for it, but I want to regtest it first, because I deeply wonder why we haven't encounter this before!
Comment 1 Thomas Freitag 2015-10-10 12:33:30 UTC
Created attachment 118796 [details]
Same PDF with changed function

Digging a little bit deeper into it I encountered that it is the exponential function of the separation colorspace:

24 0 obj <</C0 [1.0 ] /C1 [1.0 ] /Domain [0 1 ] /FunctionType 2 /N 1 /Range [0 1 ] >> endobj

If I change it to

24 0 obj <</C0 [1.0 ] /C1 [0.0 ] /Domain [0 1 ] /FunctionType 2 /N 1 /Range [0 1 ] >> endobj

it works well also with poppler. But acrobat always shows the text in any combination of C0/C1 with values 0.0 and 1.0!!!
Comment 2 Thomas Freitag 2015-10-10 15:28:50 UTC
It seems as if noone of the free renderer is able to render it the same as acrobat does it, even the browsers which supports PDF native now like firefox or chrome don't display the text.

But since acrobat is still the measure of all things and at least the RIPs based on the adobe library display the text, I've tried to create a patch for poppler that does it the same and regtested it. I'll upload it in a few seconds.
Comment 3 Thomas Freitag 2015-10-10 15:32:02 UTC
Created attachment 118801 [details] [review]
display text in separation colorspace with inverted function

This patch displays the text how acrobat does it
Comment 4 Thomas Freitag 2015-10-11 06:19:24 UTC
Thinking a little bit more about my patch I think it is not maintainable, even if it works. So I think about to do it in a more clearer way, but I need to do some tests with acrobat to see how it behaves in such a case.
Comment 5 Thomas Freitag 2015-10-11 07:12:08 UTC
Sorry for any confusing comments before. I made a lot of tests with acrobat and wondered about the results until I figured out what is the reason, s. chapter 8.6.6.4 of the spec:

At the moment the colour space is set to a Separation space, the conforming reader shall determine whether the device has an available colorant corresponding to the name of the requested space. If so, the conforming reader shall ignore the alternateSpace and tintTransform parameters; subsequent painting operations within the space shall apply the designated colorant directly, according to the tint values supplied.

Since the colorant is Black and this is always available, alternateSpace and tintTransform parameters must be ignored and the tint value is used to paint on the Black colorant directly. So my former patch was definitely wrong and I will provide a new one according to this spec.
Comment 6 Thomas Freitag 2015-10-11 09:43:08 UTC
I run my new patch which I will upload in a few seconds now through a regression test and encountered 42 unexpected failures. But all of them uses a Separation colorspace with name Black, and only the gray values are slightly different. See i.e. bug-poppler25404.pdf:

It uses 
[/Separation /Black /DeviceCMYK 12 0 R]
where the function converts it first to a CMYK value and then we use
GfxDeviceCMYKColorSpace::getRGB()
with a complex matrix multiplication to get it back to RGB
This of course results in different gray values than the new, much simpler gray calculation!

So this is what I expected and can accept and is even closer to the spec.
Comment 7 Thomas Freitag 2015-10-11 09:47:11 UTC
Created attachment 118822 [details] [review]
ignore the alternateSpace and tintTransform

This patch ignores the alternateSpace and tintTransform when the separation colorspace defines a known subtractive colorant.
Comment 8 Thomas Freitag 2015-10-30 09:50:10 UTC
To be honest, the spec says indeed:

At the moment the colour space is set to a Separation space, the conforming reader shall determine whether the device has an available colorant corresponding to the name of the requested space. If so, the conforming reader shall ignore the alternateSpace and tintTransform parameters; subsequent painting operations within the space shall apply the designated colorant directly, according to the tint values supplied.

But then I stopped reading, but the next paragraph restricts this:

The preceding paragraph applies only to subtractive output devices such as printers and imagesetters. For an additive device such as a computer display, a Separation colour space never applies a process colorant directly; it always reverts to the alternate colour space as described below. This is because the model of applying process colorants independently does not work as intended on an additive device.

So my patch is completely correct only for the method GfxSeparationColorSpace::getCMYK where a subtractive output device is simulated, but not the methods GfxSeparationColorSpace::getGray and GfxSeparationColorSpace::getRGB, which an additive device uses. That's probably also the reason, why only acrobat and even not ghostscript shows the text, acrobat always simulates a printing preview.

But without the changes in getGray() and getRGB() neither pdftoppm nor evince nor okular shows the text, just if pdftoppm compiled with CMYK and then the usage of one of the CMYK options would show it
Comment 9 Thomas Freitag 2015-10-30 10:00:39 UTC
Created attachment 119296 [details] [review]
ignore the alternateSpace and tintTransform

As a reasonable compromise in my eyes this new patch now also checks the alternate colorspace, and if this is DeviceGray in case of a separation colorspace with name black this patch treats is as if it is really a DeviceGray and so ignore tintTransform and alternate colorspace just in this case when using getGray() and getRGB().

This also removes all unexpected failures in my regression test, but still shows the text with pdftoppm or in evince or in okular. If You still don't agree, please feel free to remove the changes in getGray() and getRGB(), but commit the changes in getCMYK() because the changes in getCMYK() are following the spec!
Comment 10 Albert Astals Cid 2015-12-02 21:16:26 UTC
Pushed


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.