RSS/Atom feed Twitter
Site is read-only, email is disabled

Porting the decompose/compose plugin

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

1 of 1 message available
Toggle history

Please log in to manage your subscriptions.

Porting the decompose/compose plugin Alexander Hämmerle 04 Dec 20:09
Alexander Hämmerle
2011-12-04 20:09:13 UTC (almost 13 years ago)

Porting the decompose/compose plugin

Hi,

recently I recommenced porting the decompose/compose plugin to babl and so far nearly everything's fine. The only exception consists in the YCbCr-colorspace- algorithms which are causing some headache. Below I post the original code and what I've done with it. The conversion-problems are illustrated in the screenshots respectively (tried to keep them small, where do you normally link things like that?).
I think the errors in the conversion are kind of a type-casting problem. But until now I couldn't come up with a right way to port the algorithm. Any ideas about what is the problem are appreciated!

Thx, Alex

First the original code as it resides in decompose.c.

---> gimp/plug-ins/common/decompose.c:

#define FIX(a) ((int)((a)*256.0*256.0 + 0.5)) #define FIXY(a) ((int)((a)*256.0*256.0*219.0/255.0 + 0.5)) #define FIXC(a) ((int)((a)*256.0*256.0*224.0/255.0 + 0.5))

static void extract_ycbcr470 (const guchar *src, gint bpp, gint numpix, guchar **dst) {
register const guchar *rgb_src = src; register guchar *y_dst = dst[0];
register guchar *cb_dst = dst[1];
register guchar *cr_dst = dst[2];
register gint count = numpix, offset = bpp-3;

while (count-- > 0) {
register int r, g, b;
r= *(rgb_src++);
g= *(rgb_src++);
b= *(rgb_src++);
*(y_dst++) = ( FIXY(0.2989)*r + FIXY(0.5866)*g + FIXY(0.1145)*b + FIX(16.5))>>16;
*(cb_dst++) = (-FIXC(0.1688)*r - FIXC(0.3312)*g + FIXC(0.5000)*b + FIX(128.5))>>16;
*(cr_dst++) = ( FIXC(0.5000)*r - FIXC(0.4184)*g - FIXC(0.0816)*b + FIX(128.5))>>16;

rgb_src += offset; }
}

Here is how I ported the conversion to a babl-extensions and substituted the code in decompose.c

---> gimp/plug-ins/common/decompose.c:

static void extract_ycbcr470 (const guchar *src, gint bpp_src, gint numpix, guchar **dst) {
register const guchar *rgb_src = src; register guchar *y_dst = dst[0];
register guchar *cb_dst = dst[1];
register guchar *cr_dst = dst[2];
register gint count = numpix;
register const int bpp_dst = 3;
gdouble *ycbcr470_buffer;

const Babl *rgb = babl_format ("RGB u8"); const Babl *rgba = babl_format ("RGBA u8"); const Babl *ycbcr470 = babl_format ("YCbCr470 double"); const Babl *rgb_to_ycbcr470 = babl_fish (rgb, ycbcr470); const Babl *rgba_to_ycbcr470 = babl_fish (rgba, ycbcr470);

ycbcr470_buffer = malloc (numpix * bpp_dst * sizeof (gdouble));

if (bpp_src == 4) {
babl_process (rgba_to_ycbcr470, rgb_src, ycbcr470_buffer, numpix); }
else
{
babl_process (rgb_to_ycbcr470, rgb_src, ycbcr470_buffer, numpix); }

while (count--)
{
*y_dst++ = (guchar) (ycbcr470_buffer[0] * 255.0); *cb_dst++ = (guchar) (ycbcr470_buffer[1] * 255.0); *cr_dst++ = (guchar) (ycbcr470_buffer[2] * 255.0);

ycbcr470_buffer += bpp_dst; }
}

Here the babl-extension

---> babl/extensions/ycbcr.c:

#define FIX_1(a) ((double)((a)*256.0*256.0 + 0.5)) #define FIXY_1(a) ((double)((a)*256.0*256.0*219.0/255.0 + 0.5)) #define FIXC_1(a) ((double)((a)*256.0*256.0*224.0/255.0 + 0.5))

static long rgba_to_ycbcr470 (char *src,
char *dst,
long n)
{
double y, cb, cr;

while (n--) {
double red = ((double *) src)[0]; double green = ((double *) src)[1]; double blue = ((double *) src)[2];

y = ( FIXY_1(0.2989)*red + FIXY_1(0.5866)*green + FIXY_1(0.1145)*blue + FIX_1( 16.5))/65536;
cb = (-FIXC_1(0.1688)*red - FIXC_1(0.3312)*green + FIXC_1(0.5000)*blue + FIX_1(128.5))/65536;
cr = ( FIXC_1(0.5000)*red - FIXC_1(0.4184)*green - FIXC_1(0.0816)*blue + FIX_1(128.5))/65536;

((double *) dst)[0] = y; ((double *) dst)[1] = cb;
((double *) dst)[2] = cr;

src += 4 * sizeof (double); dst += 3 * sizeof (double);
}

return n;
}