/* babl - dynamically extendable universal pixel conversion library.
* Copyright (C) 2012, Ø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-internal.h"
#include "babl-cpuaccel.h"
#include "extensions/util.h"
#include "base/util.h"
static void
conv_rgbaD_linear_rgbAD_gamma (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
double alpha = fsrc[3];
double used_alpha = babl_epsilon_for_zero (alpha);
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * used_alpha;
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * used_alpha;
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * used_alpha;
*fdst++ = alpha;
fsrc++;
}
}
static void
conv_rgbAD_linear_rgbAD_gamma (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
double alpha = fsrc[3];
if (alpha == 0.0)
{
*fdst++ = 0.0;
*fdst++ = 0.0;
*fdst++ = 0.0;
*fdst++ = 0.0;
fsrc+=4;
}
else
{
double alpha_recip = 1.0 / alpha;
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++ * alpha_recip) * alpha;
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++ * alpha_recip) * alpha;
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++ * alpha_recip) * alpha;
*fdst++ = *fsrc++;
}
}
}
static void
conv_rgbaD_linear_rgbaD_gamma (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
*fdst++ = *fsrc++;
}
}
#define conv_rgbaD_linear_rgbD_linear conv_rgbaD_gamma_rgbD_gamma
static void
conv_rgbaD_linear_rgbD_linear (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = *fsrc++;
*fdst++ = *fsrc++;
*fdst++ = *fsrc++;
fsrc++;
}
}
static void
conv_rgbD_linear_rgbD_gamma (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
}
}
static void
conv_rgbaD_gamma_rgbaD_linear (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
*fdst++ = *fsrc++;
}
}
static void
conv_rgbD_gamma_rgbD_linear (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
}
}
static void
conv_rgbD_linear_rgbaD_linear (const Babl *conversion,
unsigned char *src,
unsigned char *dst,
long samples)
{
const Babl *space = babl_conversion_get_destination_space (conversion);
const Babl **trc = (void*)space->space.trc;
double *fsrc = (double *) src;
double *fdst = (double *) dst;
int n = samples;
while (n--)
{
*fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
*fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
*fdst++ = 1.0;
}
}
#define conv_rgbD_gamma_rgbaD_gamma conv_rgbD_linear_rgbaD_linear
#define o(src, dst) \
babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
int init (void);
#include "babl-verify-cpu.inc"
int
init (void)
{
BABL_VERIFY_CPU();
{
const Babl *rgbaD_linear = babl_format_new (
babl_model ("RGBA"),
babl_type ("double"),
babl_component ("R"),
babl_component ("G"),
babl_component ("B"),
babl_component ("A"),
NULL);
const Babl *rgbAD_linear = babl_format_new (
babl_model ("RaGaBaA"),
babl_type ("double"),
babl_component ("Ra"),
babl_component ("Ga"),
babl_component ("Ba"),
babl_component ("A"),
NULL);
const Babl *rgbaD_gamma = babl_format_new (
babl_model ("R'G'B'A"),
babl_type ("double"),
babl_component ("R'"),
babl_component ("G'"),
babl_component ("B'"),
babl_component ("A"),
NULL);
const Babl *rgbAD_gamma = babl_format_new (
babl_model ("R'aG'aB'aA"),
babl_type ("double"),
babl_component ("R'a"),
babl_component ("G'a"),
babl_component ("B'a"),
babl_component ("A"),
NULL);
const Babl *rgbD_linear = babl_format_new (
babl_model ("RGB"),
babl_type ("double"),
babl_component ("R"),
babl_component ("G"),
babl_component ("B"),
NULL);
const Babl *rgbD_gamma = babl_format_new (
babl_model ("R'G'B'"),
babl_type ("double"),
babl_component ("R'"),
babl_component ("G'"),
babl_component ("B'"),
NULL);
o (rgbAD_linear, rgbAD_gamma);
o (rgbaD_linear, rgbAD_gamma);
o (rgbaD_linear, rgbaD_gamma);
o (rgbaD_gamma, rgbaD_linear);
o (rgbD_linear, rgbD_gamma);
o (rgbD_gamma, rgbD_linear);
o (rgbaD_linear, rgbD_linear);
o (rgbaD_gamma, rgbD_gamma);
o (rgbD_linear, rgbaD_linear);
o (rgbD_gamma, rgbaD_gamma);
o (rgbaD_linear, rgbD_linear);
o (rgbaD_gamma, rgbD_gamma);
}
return 0;
}