/* babl - dynamically extendable universal pixel conversion library.
* Copyright (C) 2005, Øyvind Kolås.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see
* .
*/
#include "config.h"
#include
#include
#include "babl.h"
#include "base/util.h"
static void rgba_to_cmyk (const Babl *conversion,char *src,
char *dst,
long n);
static void cmyk_to_rgba (const Babl *conversion,char *src,
char *dst,
long n);
static void rgba_to_cmy (const Babl *conversion,char *src,
char *dst,
long n);
static void cmy_to_rgba (const Babl *conversion,char *src,
char *dst,
long n);
int init (void);
int
init (void)
{
babl_component_new ("cyan", NULL);
babl_component_new ("yellow", NULL);
babl_component_new ("magenta", NULL);
babl_component_new ("key", NULL);
babl_model_new (
"name", "CMYK",
babl_component ("cyan"),
babl_component ("magenta"),
babl_component ("yellow"),
babl_component ("key"),
NULL
);
babl_model_new (
"name", "CMY",
babl_component ("cyan"),
babl_component ("magenta"),
babl_component ("yellow"),
NULL
);
babl_conversion_new (
babl_model ("RGBA"),
babl_model ("CMYK"),
"linear", rgba_to_cmyk,
NULL
);
babl_conversion_new (
babl_model ("CMYK"),
babl_model ("RGBA"),
"linear", cmyk_to_rgba,
NULL
);
babl_conversion_new (
babl_model ("RGBA"),
babl_model ("CMY"),
"linear", rgba_to_cmy,
NULL
);
babl_conversion_new (
babl_model ("CMY"),
babl_model ("RGBA"),
"linear", cmy_to_rgba,
NULL
);
babl_format_new (
"name", "CMYK float",
babl_model ("CMYK"),
babl_type ("float"),
babl_component ("cyan"),
babl_component ("magenta"),
babl_component ("yellow"),
babl_component ("key"),
NULL
);
babl_format_new (
"name", "CMY float",
babl_model ("CMY"),
babl_type ("float"),
babl_component ("cyan"),
babl_component ("magenta"),
babl_component ("yellow"),
NULL
);
babl_format_new (
"name", "CMYK u8",
babl_model ("CMYK"),
babl_type ("u8"),
babl_component ("cyan"),
babl_component ("magenta"),
babl_component ("yellow"),
babl_component ("key"),
NULL
);
return 0;
}
static void
rgba_to_cmyk (const Babl *conversion,char *src,
char *dst,
long n)
{
while (n--)
{
double red = linear_to_gamma_2_2 (((double *) src)[0]);
double green = linear_to_gamma_2_2 (((double *) src)[1]);
double blue = linear_to_gamma_2_2 (((double *) src)[2]);
double cyan, magenta, yellow, key;
double pullout = 1.0;
cyan = 1.0 - red;
magenta = 1.0 - green;
yellow = 1.0 - blue;
key = 1.0;
if (cyan < key) key = cyan;
if (magenta < key) key = magenta;
if (yellow < key) key = yellow;
key *= pullout;
if (key < 1.0)
{
cyan = (cyan - key) / (1.0 - key);
magenta = (magenta - key) / (1.0 - key);
yellow = (yellow - key) / (1.0 - key);
}
else
{
cyan = 0.0;
magenta = 0.0;
yellow = 0.0;
}
((double *) dst)[0] = cyan;
((double *) dst)[1] = magenta;
((double *) dst)[2] = yellow;
((double *) dst)[3] = key;
src += 4 * sizeof (double);
dst += 4 * sizeof (double);
}
}
static void
cmyk_to_rgba (const Babl *conversion,char *src,
char *dst,
long n)
{
while (n--)
{
double cyan = ((double *) src)[0];
double magenta = ((double *) src)[1];
double yellow = ((double *) src)[2];
double key = ((double *) src)[3];
double red, green, blue;
if (key < 1.0)
{
cyan = cyan * (1.0 - key) + key;
magenta = magenta * (1.0 - key) + key;
yellow = yellow * (1.0 - key) + key;
}
else
{
cyan = magenta = yellow = 1.0;
}
red = 1.0 - cyan;
green = 1.0 - magenta;
blue = 1.0 - yellow;
((double *) dst)[0] = gamma_2_2_to_linear (red);
((double *) dst)[1] = gamma_2_2_to_linear (green);
((double *) dst)[2] = gamma_2_2_to_linear (blue);
((double *) dst)[3] = 1.0;
src += 4 * sizeof (double);
dst += 4 * sizeof (double);
}
}
static void
rgba_to_cmy (const Babl *conversion,char *src,
char *dst,
long n)
{
while (n--)
{
double red = linear_to_gamma_2_2 (((double *) src)[0]);
double green = linear_to_gamma_2_2 (((double *) src)[1]);
double blue = linear_to_gamma_2_2 (((double *) src)[2]);
double cyan, magenta, yellow;
cyan = 1.0 - red;
magenta = 1.0 - green;
yellow = 1.0 - blue;
((double *) dst)[0] = cyan;
((double *) dst)[1] = magenta;
((double *) dst)[2] = yellow;
src += 4 * sizeof (double);
dst += 3 * sizeof (double);
}
}
static void
cmy_to_rgba (const Babl *conversion,char *src,
char *dst,
long n)
{
while (n--)
{
double cyan = ((double *) src)[0];
double magenta = ((double *) src)[1];
double yellow = ((double *) src)[2];
double red, green, blue;
red = 1.0 - cyan;
green = 1.0 - magenta;
blue = 1.0 - yellow;
((double *) dst)[0] = gamma_2_2_to_linear (red);
((double *) dst)[1] = gamma_2_2_to_linear (green);
((double *) dst)[2] = gamma_2_2_to_linear (blue);
((double *) dst)[3] = 1.0;
src += 3 * sizeof (double);
dst += 4 * sizeof (double);
}
}