Package: libimlib2
Version: 1.2.1-2
Severity: normal
Tags: patch
*** Please type your report below this line ***
Viewing TIFF images with an alpha channel shows semitransparent
pixels as too dark. imlib2 uses unpremultiplied-by-alpha colour
components (cf. src/lib/blend.h), but in
src/modules/loaders/loader_tiff.c, the raster() function neglects
to divide by alpha the RGB colour components of premultiplied
pixels fed to it by TIFFRGBAImageGet().
To reproduce: Make a TIFF image with a white background and a
50% semitransparent white box in it. View the image with feh.
Note how the box is darker than when the image is viewed in gimp,
for example.
-- System Information:
Debian Release: testing/unstable
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16-2-amd64-k8-smp
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1) (ignored: LC_ALL set to
en_US)
Versions of packages libimlib2 depends on:
ii libbz2-1.0 1.0.3-3 high-quality block-sorting file co
ii libc6 2.3.6-15 GNU C Library: Shared libraries
ii libfreetype6 2.2.1-2 FreeType 2 font engine, shared lib
ii libjpeg62 6b-13 The Independent JPEG Group's JPEG
ii libpng12-0 1.2.8rel-5.1 PNG library - runtime
ii libtiff4 3.8.2-5 Tag Image File Format (TIFF) libra
ii libungif4g 4.1.4-2 shared library for GIF images (run
ii libx11-6 2:1.0.0-7 X11 client-side library
ii libxext6 1:1.0.0-4 X11 miscellaneous extension librar
ii zlib1g 1:1.2.3-13 compression library - runtime
libimlib2 recommends no packages.
-- no debconf information
--- imlib2-1.2.1/src/modules/loaders/loader_tiff.c 2004-12-14
05:50:46.000000000 +0200
+++ imlib2-1.2.1-tiffalpha/src/modules/loaders/loader_tiff.c 2006-08-02
23:45:17.787205647 +0300
@@ -97,13 +97,57 @@
for (j = 0; j < w; j++)
{
- pixel_value = (*(pixel++));
- (*(buffer_pixel++)) =
- (TIFFGetA(pixel_value) << 24) |
- (TIFFGetR(pixel_value) << 16) | (TIFFGetG(pixel_value) << 8) |
- TIFFGetB(pixel_value);
+ unsigned a;
+ pixel_value = (*(pixel++));
+ a = TIFFGetA(pixel_value);
+ /* Convert premultiplied alpha to unpremultiplied alpha used by
+ * imlib2. Note: TIFFRGBAImageGet() always gives us premultiplied
+ * alpha, regardless of the type of alpha in the image, and we
+ * can't rely on the .alpha field of TIFFRGBAImage. The behaviour
+ * seems to be (cf. tiff-3.7.2/libtiff/tif_getimage.c):
+ *
+ * a) If the image has no EXTRASAMPLES information at all, assume
+ * it's really associated alpha, perform no transformation on the
+ * pixels, and override the .alpha field of TIFFRGBAImage to be
+ * EXTRASAMPLE_ASSOCALPHA.
+ *
+ * b) If the image has one EXTRASAMPLE_UNASSALPHA, premultiply all
+ * pixels' RGB values by alpha. Sets the .alpha field of
+ * TIFFRGBAImage to EXTRASAMPLE_UNASSALPHA.
+ *
+ * c) If the image has one EXTRASAMPLE_ASSOCALPHA, perform no
+ * transformation on the pixels. Set the .alpha field of
+ * TIFFRGBAImage to EXTRASAMPLE_ASSOCALPHA. */
+ if (a == 255)
+ {
+ (*(buffer_pixel++)) =
+ (a << 24) |
+ (TIFFGetR(pixel_value) << 16) |
+ (TIFFGetG(pixel_value) << 8) |
+ TIFFGetB(pixel_value);
+ }
+ else if (!a)
+ {
+ (*(buffer_pixel++)) = 0;
+ }
+ else
+ {
+ /* need to divide by alpha; watch out for overflow. */
+ unsigned b = TIFFGetB(pixel_value);
+ unsigned g = TIFFGetG(pixel_value);
+ unsigned r = TIFFGetR(pixel_value);
+ if (b < a) b = b*255/a; else b = 255;
+ if (g < a) g = g*255/a; else g = 255;
+ if (r < a) r = r*255/a; else r = 255;
+ (*(buffer_pixel++)) =
+ (a << 24) |
+ (r << 16) |
+ (g << 8) |
+ (b << 0);
+ }
}
}
+
if (img->progress)
{