|
Packit Service |
2781ba |
/* This file is part of GEGL
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* GEGL is free software; you can redistribute it and/or
|
|
Packit Service |
2781ba |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
2781ba |
* version 3 of the License, or (at your option) any later version.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* GEGL is distributed in the hope that it will be useful,
|
|
Packit Service |
2781ba |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
2781ba |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
2781ba |
* Lesser General Public License for more details.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* Copyright 2009 Øyvind Kolås.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "config.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <glib-object.h>
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "gegl.h"
|
|
Packit Service |
2781ba |
#include "gegl-lookup.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglLookup *
|
|
Packit Service |
2781ba |
gegl_lookup_new_full (GeglLookupFunction function,
|
|
Packit Service |
2781ba |
gpointer data,
|
|
Packit Service |
2781ba |
gfloat start,
|
|
Packit Service |
2781ba |
gfloat end,
|
|
Packit Service |
2781ba |
gfloat precision)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GeglLookup *lookup;
|
|
Packit Service |
2781ba |
union
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
float f;
|
|
Packit Service |
2781ba |
guint32 i;
|
|
Packit Service |
2781ba |
} u;
|
|
Packit Service |
2781ba |
gint positive_min, positive_max, negative_min, negative_max;
|
|
Packit Service |
2781ba |
gint shift;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* normalize input parameters */
|
|
Packit Service |
2781ba |
if (start > end)
|
|
Packit Service |
2781ba |
{ /* swap */
|
|
Packit Service |
2781ba |
u.f = start;
|
|
Packit Service |
2781ba |
start = end;
|
|
Packit Service |
2781ba |
end = u.f;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (precision <= 0.000005) shift = 0; /* checked for later */
|
|
Packit Service |
2781ba |
else if (precision <= 0.000010) shift = 8;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000020) shift = 9;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000040) shift = 10;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000081) shift = 11;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000161) shift = 12;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000324) shift = 14;
|
|
Packit Service |
2781ba |
else if (precision <= 0.000649) shift = 15;
|
|
Packit Service |
2781ba |
else shift = 16; /* a bit better than 8bit sRGB quality */
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* Adjust slightly away from 0.0, saving many entries close to 0, this
|
|
Packit Service |
2781ba |
* causes lookups very close to zero to be passed directly to the
|
|
Packit Service |
2781ba |
* function instead.
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
if (start == 0.0)
|
|
Packit Service |
2781ba |
start = precision;
|
|
Packit Service |
2781ba |
if (end == 0.0)
|
|
Packit Service |
2781ba |
end = -precision;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
/* Compute start and */
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (start < 0.0 || end < 0.0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (end < 0.0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
u.f = start;
|
|
Packit Service |
2781ba |
positive_max = u.i >> shift;
|
|
Packit Service |
2781ba |
u.f = end;
|
|
Packit Service |
2781ba |
positive_min = u.i >> shift;
|
|
Packit Service |
2781ba |
negative_min = positive_max;
|
|
Packit Service |
2781ba |
negative_max = positive_max;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
u.f = 0 - precision;
|
|
Packit Service |
2781ba |
positive_min = u.i >> shift;
|
|
Packit Service |
2781ba |
u.f = start;
|
|
Packit Service |
2781ba |
positive_max = u.i >> shift;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
u.f = 0 + precision;
|
|
Packit Service |
2781ba |
negative_min = u.i >> shift;
|
|
Packit Service |
2781ba |
u.f = end;
|
|
Packit Service |
2781ba |
negative_max = u.i >> shift;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
u.f = start;
|
|
Packit Service |
2781ba |
positive_min = u.i >> shift;
|
|
Packit Service |
2781ba |
u.f = end;
|
|
Packit Service |
2781ba |
positive_max = u.i >> shift;
|
|
Packit Service |
2781ba |
negative_min = positive_max;
|
|
Packit Service |
2781ba |
negative_max = positive_max;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (shift == 0) /* short circuit, do not use ranges */
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
positive_min = positive_max = negative_min = negative_max = 0;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if ((positive_max-positive_min) + (negative_max-negative_min) > GEGL_LOOKUP_MAX_ENTRIES)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
/* Reduce the size of the cache tables to fit within the bittable
|
|
Packit Service |
2781ba |
* budget (the maximum allocation is around 2.18mb of memory
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gint diff = (positive_max-positive_min) + (negative_max-negative_min) - GEGL_LOOKUP_MAX_ENTRIES;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (negative_max - negative_min > 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (negative_max - negative_min >= diff)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
negative_max -= diff;
|
|
Packit Service |
2781ba |
diff = 0;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
diff -= negative_max - negative_min;
|
|
Packit Service |
2781ba |
negative_max = negative_min;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
if (diff)
|
|
Packit Service |
2781ba |
positive_max-=diff;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
lookup = g_malloc0 (sizeof (GeglLookup) + sizeof (gfloat) *
|
|
Packit Service |
2781ba |
((positive_max-positive_min)+
|
|
Packit Service |
2781ba |
(negative_max-negative_min)));
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
lookup->positive_min = positive_min;
|
|
Packit Service |
2781ba |
lookup->positive_max = positive_max;
|
|
Packit Service |
2781ba |
lookup->negative_min = negative_min;
|
|
Packit Service |
2781ba |
lookup->negative_max = negative_max;
|
|
Packit Service |
2781ba |
lookup->shift = shift;
|
|
Packit Service |
2781ba |
lookup->function = function;
|
|
Packit Service |
2781ba |
lookup->data = data;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return lookup;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
GeglLookup *
|
|
Packit Service |
2781ba |
gegl_lookup_new (GeglLookupFunction function,
|
|
Packit Service |
2781ba |
gpointer data)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return gegl_lookup_new_full (function, data, 0, 1.0, 0.000010);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
gegl_lookup_free (GeglLookup *lookup)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_free (lookup);
|
|
Packit Service |
2781ba |
}
|