[poppler] Color Management

Hal V. Engel hvengel at astound.net
Fri Feb 27 12:45:12 PST 2009


On Friday 27 February 2009 02:06:05 am Koji Otani wrote:
> Hi
>
> Thank you for your comments.
>
> First, poppler is a library. So, applications using poppler should be
> responsible for location of profiles, I think.
> Applications (not poppler) can know
> on which device output is displayed and which
> profile is appropriate one.

This is correct.  I was mostly pointing out how end users would expect this to 
work eventually with the intent of making sure that the poppler API would 
allow for that to happen.  It appears that the API does but there are no 
current apps, even demo apps included with poppler, that make the calls for 
this to occur so it is untested at this time.  

Apps that are not CM aware like Okular built against poppler git head are much 
better behaved when rendering ICC based pdf objects than before. Poppler now 
has a reasonable default behavior when it encounters ICC based objects in 
spite of not having access to the correct output profiles.   This is a good 
thing and a big step in the right direction.

>
> I think that what we should do next about this is to add some
> API (that set location of profiles) to the poppler external API (glib API).

Having taken a look at okular as an example of how applications are coded I 
see that they are interfacing to poppler through the API defined in poppler-
qt4.h perhaps believing that this provides a complete interface.  Of course 
the API for setting the output profiles and for setting up the color 
transforms is not exposed in poppler-qt4.h.  Okular basically does things in 
about the same way as qt4/demos/poppler_qt4viewer so this appears to be fairly 
typical of how many apps are/will be coded.   

Perhaps a good way to validate the API would be to incorporate basic CM 
awareness into the demo apps.  In addition, this would then give application 
developers some example code that would help guide their work in this area.

Speaking of the API, this is a minor issue, but one that should be fixed 
before applications start using the CM APIs.  The "displayProfile" is actually 
the output profile and it could be for any type of output device such as a 
CMYK printer or even a N channel device.  For example a program using poppler 
to generate raster output for a printer would call either setDisplayProfile() 
or setDiplayProfileName() before calling setupColorProfiles() to setup the 
correct transforms for getting output for the printer.  This is somewhat 
counter intuitive.  The code looks like it handles this correctly so I am 
pointing this out mostly to make the API more accessible since it would make 
things clearer if this where named outputProfile rather than displayProfile.  
The same thing applies to other parts of the API that use displayProfile or 
display or Display as part of their name.  These should all be changed to 
output* or Output* for clarity.  

>
> Though current code looks /usr/share/poppler/ColorProfiles/display.icc
>  and  ~/.xpdf/ColorProfiles/display.icc, this is only default behavior.
> It seems OK to change these default to other files
> such as /usr/share/color/icc/poppler.icc and ~/.color/icc/poppler.icc.

Looking at the code it appears that it will try to load display.icc by 
default.  I don't find any references to poppler.icc in the code.  Of course 
neither of these (display.icc or poppler.icc) exist in any location on most 
machines including mine.   So I am not sure what profile is actually being 
used by the current code.

In addition, it is accepted practice that if no display or output profile is 
specified by the user or is available through system calls that this should 
default to sRGB.  I have attached a patch that changes the section of 
GfxColorSpace::setupColorProfiles() that sets up the output (display) profile 
so that it defaults to sRGB.  This patch also changes references to 
displayProfile and displayTransform and other things like this to use output 
instead of display.  The patch does not address the profile path issue since 
this should probably be handled using Oyranos since this is a more generalized 
solution.

I tested the above code with okular and poppler_qt4viewer and  it appears to 
be working correctly.  At least it builds and the apps run without apparent 
errors.

Again I would like to thank Koji for his hard work on this since it is a 
significant improvement to poppler even at this early stage.  In fact so much 
so that I hope it is included in a formal release sometime soon.  I will be 
looking this over as time permits and will make additional comments as                
necessary and perhaps even supply a few patches.  I will also try to take a 
look at qt4/demos/poppler_qt4viewer to see if perhaps I can find some time to 
create a CM awareness patch for it.

Hal


>
> -------------
> Koji Otani.
>
>
> From: "Hal V. Engel" <hvengel at astound.net>
> Subject: [poppler] Color Management
> Date: Thu, 26 Feb 2009 15:29:11 -0800
> Message-ID: <200902261529.14470.hvengel at astound.net>
>
> hvengel> I have been using the Color Management patches that Koji Otani
> posted to this hvengel> list in Dec since that time.  And after these were
> merged into git trunk I hvengel> have been using git head.  These are a
> significant step forward and I would hvengel> like to thank Koji for his
> hard work and Albert for taking the time to review hvengel> the patch set
> and getting it committed.  This is a significant step forward hvengel>
> although it will take more work to get this in a fully working condition.
> hvengel>
> hvengel> One issue is how display profiles are currently selected (or
> actually not hvengel> selected is more correct).
> hvengel>
> hvengel> In a follow up note on Dec. 14 James Cloos wrote:
> hvengel>
> hvengel> "I've only tested with a few alternate display profiles.  Nothing
> broke, hvengel> but I havn't been able to tell that a different profile was
> in use." hvengel>
> hvengel> The reason that James didn't notice different display profiles
> making a hvengel> difference is that the current code does not correctly
> pick up changes to the hvengel> display profile settings in X11 and it does
> not use the X11 _ICC_PROFILE atom. hvengel>
> hvengel> In addition there are other issues with the code related to
> locating profiles hvengel> as well.
> hvengel>
> hvengel> Having had a look at the code let me make some comments related to
> these hvengel> issues.
> hvengel>
> hvengel> 1. Where to look for profiles on a *nix system.
> hvengel>
> hvengel> As early as May 2004 OpenICC had a proposal to use
> /usr/share/color/icc and hvengel> ~/.color/icc for system and user ICC
> profile directories.  This later became a hvengel> formal standards
> proposal and that has been through a number of revisions. hvengel> This
> link
> hvengel>
> hvengel> 
> http://www.oyranos.com/wiki/index.php?title=OpenIccDirectoryProposal
> hvengel>
> hvengel> has the latest version of the proposed standard which is an
> extension of the hvengel> widely used XDG base directory specification. 
> This standard may be subject to hvengel> more revisions but it is
> considered the working standard for where ICC hvengel> profiles should be
> located on *nix machines and is now fairly stable. hvengel>
> hvengel> 2. X11 display profiles.
> hvengel>
> hvengel> X11 has had a _ICC_PROFILE atom for some time now.  This is based
> on a draft hvengel> specification that came out of the OpenICC group in
> 2005 which can be found hvengel> here:
> hvengel>
> hvengel> http://www.burtonini.com/computing/x-icc-profiles-spec-0.1.html
> hvengel>
> hvengel> This draft had issues with some multi monitor setups and was later
> revised but hvengel> I can't find the revisions on-line right now.  But I
> do have a copy of a note hvengel> to the OpenICC list that summarizes those
> changes.
> hvengel>
> hvengel> "Remove: ?Currently there is only one atom defined.
> hvengel> and: ? ? ?The _ICC_PROFILE atom is set on the root window for each
> screen. hvengel>
> hvengel>
> hvengel> And add:
> hvengel>
> hvengel> The atom name for the first screen in a root window is
> _ICC_Profile. hvengel>
> hvengel> For root windows spanning more than one screen, as typical in
> Xinerama hvengel> multihead configurations, a atom for each screen is added
> holding the hvengel> appropriate ICC profile. All screens in a root window
> starting from hvengel> number one use _ICC_Profile as atom name extended
> with an underscore plus hvengel> the screen number, e.g. _ICC_Profile_1 .
> hvengel>
> hvengel> followed by your text:
> hvengel>
> hvengel> The atoms are of type XA_CARDINAL with 8-bit elements. The value
> of the hvengel> atoms should be a literal ICC profile, that applications
> can read and hvengel> parse directly."
> hvengel>
> hvengel> I know the updated specification was published somewhere but I can
> locate it hvengel> at this time.
> hvengel>
> hvengel> So how is this used?
> hvengel>
> hvengel> Here is a snippet of code that shows how this might be done using
> GTK+ (I hvengel> think this was pulled out of the GIMP code base around
> 6-2005): hvengel>
> hvengel> static cmsHPROFILE *
> hvengel> get_screen_profile (GdkScreen *screen)
> hvengel> {
> hvengel>        Display *dpy;
> hvengel>        Atom icc_atom, type;
> hvengel>        int format;
> hvengel>        gulong nitems;
> hvengel>        gulong bytes_after;
> hvengel>        guchar *str;
> hvengel>        int result;
> hvengel>        cmsHPROFILE *profile;
> hvengel>
> hvengel>        g_return_val_if_fail (screen != NULL, NULL);
> hvengel>
> hvengel>        dpy = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display
> (screen)); hvengel>        icc_atom = gdk_x11_get_xatom_by_name_for_display
> gdk_screen_get_display hvengel> (screen), "_ICC_PROFILE");
> hvengel>
> hvengel>        result = XGetWindowProperty (dpy, GDK_WINDOW_XID
> hvengel> 				    (gdk_screen_get_root_window (screen)),
> hvengel>                                     icc_atom, 0, G_MAXLONG,
> hvengel>                                     False, XA_CARDINAL, &type,
> &format, hvengel> 				    &nitems, &bytes_after, (guchar **)&str);
> hvengel>
> hvengel>        if (nitems) {
> hvengel>                profile = cmsOpenProfileFromMem(str, nitems);
> hvengel>                XFree (str);
> hvengel>                return profile;
> hvengel>        } else {
> hvengel>                g_printerr("No profile, not correcting\n");
> hvengel>                return NULL;
> hvengel>        }
> hvengel> }
> hvengel>
> hvengel> For those using the Qt widget set I found this piece of untested
> but plausible hvengel> code (this was posted to the kde-core-devel list by
> Lubos Lunak): hvengel>
> hvengel> static cmsHPROFILE *
> hvengel> get_screen_profile (int screen)
> hvengel> {
> hvengel>        Display *dpy;
> hvengel>        Atom icc_atom, type;
> hvengel>        int format;
> hvengel>        long nitems;
> hvengel>        long bytes_after;
> hvengel>        unsigned char *str;
> hvengel>        int result;
> hvengel>        cmsHPROFILE *profile = NULL;
> hvengel>
> hvengel>        static Atom icc_atom = XInternAtom( qt_xdisplay(),
> "_ICC_PROFILE", hvengel> False );
> hvengel>
> hvengel>        if ( XGetWindowProperty ( qt_xdisplay(), qt_xrootwin(
> screen ), hvengel>                                               icc_atom,
> 0, INT_MAX, False, hvengel>                                              
> XA_CARDINAL, &type, &format, hvengel>                                      
>        &nitems, &bytes_after, hvengel>                                     
>          (unsigned char **)&str)) { hvengel> 	if( nitems ) {
> hvengel>                profile = cmsOpenProfileFromMem(str, nitems);
> hvengel>                XFree (str);
> hvengel>                return profile;
> hvengel>        } else {
> hvengel>                kdDebug() << "No profile, not correcting" << endl;
> hvengel>                return NULL;
> hvengel>        }
> hvengel> }
> hvengel>
> hvengel> Using the X11 _ICC_PROFILE atom(s) will fix the issue that James
> was seeing. hvengel> But the code also needs to be updated to search for
> profiles in the correct hvengel> locations.  In addition it should allow
> user programs to override using the hvengel> _ICC_PROFILE X11 atom.
> hvengel>
> hvengel> Hal
> hvengel>
> hvengel>
> hvengel>
> hvengel> _______________________________________________
> hvengel> poppler mailing list
> hvengel> poppler at lists.freedesktop.org
> hvengel> http://lists.freedesktop.org/mailman/listinfo/poppler

-------------- next part --------------
A non-text attachment was scrubbed...
Name: GfxState-hvengel.diff
Type: text/x-patch
Size: 16813 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/poppler/attachments/20090227/88756a83/attachment-0001.bin 


More information about the poppler mailing list