266 lines
5.4 KiB
C
266 lines
5.4 KiB
C
/*
|
|
* Copyright (C) 2000 Carsten Haitzler, Geoff Harrison and various contributors
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "E.h"
|
|
|
|
void
|
|
CreateCurve(ModCurve * c)
|
|
{
|
|
int i, j, cx, v1, v2, val, dist;
|
|
|
|
EDBUG(6, "CreateCurve");
|
|
|
|
if (!c)
|
|
EDBUG_RETURN_;
|
|
|
|
if (c->num == 0)
|
|
{
|
|
for (i = 0; i < 256; i++)
|
|
c->map[i] = i;
|
|
EDBUG_RETURN_;
|
|
}
|
|
|
|
cx = 0;
|
|
c->map[cx++] = c->py[0];
|
|
|
|
for (i = 1; i < c->num; i++)
|
|
{
|
|
v1 = c->py[i - 1];
|
|
v2 = c->py[i];
|
|
dist = c->px[i] - c->px[i - 1];
|
|
if (dist < 2)
|
|
{
|
|
c->map[cx++] = v2;
|
|
}
|
|
else
|
|
{
|
|
for (j = 0; j < dist; j++)
|
|
{
|
|
val = ((v2 * j) + (v1 * (dist - j - 1))) / (dist - 1);
|
|
c->map[cx++] = (unsigned char)val;
|
|
}
|
|
}
|
|
}
|
|
|
|
EDBUG_RETURN_;
|
|
|
|
}
|
|
|
|
void
|
|
FreeModCurve(ModCurve * c)
|
|
{
|
|
|
|
EDBUG(6, "FreeModCurve");
|
|
|
|
if (!c)
|
|
EDBUG_RETURN_;
|
|
|
|
Efree(c->px);
|
|
Efree(c->py);
|
|
|
|
EDBUG_RETURN_;
|
|
|
|
}
|
|
|
|
void
|
|
FreeCMClass(ColorModifierClass * cm)
|
|
{
|
|
|
|
EDBUG(5, "FreeCmClass");
|
|
|
|
if (!cm)
|
|
EDBUG_RETURN_;
|
|
|
|
if (cm->ref_count > 0)
|
|
{
|
|
char stuff[255];
|
|
|
|
Esnprintf(stuff, sizeof(stuff), _("%u references remain\n"),
|
|
cm->ref_count);
|
|
DIALOG_OK(_("ColorModClass Error!"), stuff);
|
|
|
|
EDBUG_RETURN_;
|
|
|
|
}
|
|
|
|
while (RemoveItemByPtr(cm, LIST_TYPE_COLORMODIFIER));
|
|
|
|
Efree(cm->name);
|
|
FreeModCurve(&(cm->red));
|
|
FreeModCurve(&(cm->green));
|
|
FreeModCurve(&(cm->blue));
|
|
|
|
EDBUG_RETURN_;
|
|
|
|
}
|
|
|
|
ColorModifierClass *
|
|
CreateCMClass(char *name, int rnum, unsigned char *rpx,
|
|
unsigned char *rpy, int gnum,
|
|
unsigned char *gpx, unsigned char *gpy,
|
|
int bnum, unsigned char *bpx, unsigned char *bpy)
|
|
{
|
|
ColorModifierClass *cm;
|
|
|
|
EDBUG(5, "CreateCMCLass");
|
|
|
|
cm = Emalloc(sizeof(ColorModifierClass));
|
|
if (!cm)
|
|
EDBUG_RETURN(NULL);
|
|
|
|
cm->name = duplicate(name);
|
|
cm->red.px = NULL;
|
|
cm->red.py = NULL;
|
|
cm->green.px = NULL;
|
|
cm->green.py = NULL;
|
|
cm->blue.px = NULL;
|
|
cm->blue.py = NULL;
|
|
cm->ref_count = 0;
|
|
|
|
if (rnum < 2)
|
|
{
|
|
cm->red.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->red.num = rnum;
|
|
cm->red.px = Emalloc(rnum);
|
|
memcpy(cm->red.px, rpx, rnum);
|
|
cm->red.py = Emalloc(rnum);
|
|
memcpy(cm->red.py, rpy, rnum);
|
|
}
|
|
|
|
if (gnum < 2)
|
|
{
|
|
cm->green.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->green.num = gnum;
|
|
cm->green.px = Emalloc(gnum);
|
|
memcpy(cm->green.px, gpx, gnum);
|
|
cm->green.py = Emalloc(gnum);
|
|
memcpy(cm->green.py, gpy, gnum);
|
|
}
|
|
|
|
if (bnum < 2)
|
|
{
|
|
cm->blue.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->blue.num = bnum;
|
|
cm->blue.px = Emalloc(bnum);
|
|
memcpy(cm->blue.px, bpx, bnum);
|
|
cm->blue.py = Emalloc(bnum);
|
|
memcpy(cm->blue.py, bpy, bnum);
|
|
}
|
|
|
|
CreateCurve(&(cm->red));
|
|
CreateCurve(&(cm->green));
|
|
CreateCurve(&(cm->blue));
|
|
|
|
EDBUG_RETURN(cm);
|
|
|
|
}
|
|
|
|
void
|
|
ModifyCMClass(char *name, int rnum, unsigned char *rpx, unsigned char *rpy,
|
|
int gnum, unsigned char *gpx, unsigned char *gpy, int bnum,
|
|
unsigned char *bpx, unsigned char *bpy)
|
|
{
|
|
ColorModifierClass *cm;
|
|
|
|
EDBUG(5, "ModifyCMCLass");
|
|
cm =
|
|
(ColorModifierClass *) FindItem(name, 0, LIST_FINDBY_NAME,
|
|
LIST_TYPE_COLORMODIFIER);
|
|
if (!cm)
|
|
EDBUG_RETURN_;
|
|
|
|
if (cm->red.px)
|
|
Efree(cm->red.px);
|
|
if (cm->red.py)
|
|
Efree(cm->red.py);
|
|
if (cm->green.px)
|
|
Efree(cm->green.px);
|
|
if (cm->green.py)
|
|
Efree(cm->green.py);
|
|
if (cm->blue.px)
|
|
Efree(cm->blue.px);
|
|
if (cm->blue.py)
|
|
Efree(cm->blue.py);
|
|
|
|
cm->red.px = NULL;
|
|
cm->red.py = NULL;
|
|
cm->green.px = NULL;
|
|
cm->green.py = NULL;
|
|
cm->blue.px = NULL;
|
|
cm->blue.py = NULL;
|
|
|
|
if (rnum < 2)
|
|
{
|
|
cm->red.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->red.num = rnum;
|
|
cm->red.px = Emalloc(rnum);
|
|
memcpy(cm->red.px, rpx, rnum);
|
|
cm->red.py = Emalloc(rnum);
|
|
memcpy(cm->red.py, rpy, rnum);
|
|
}
|
|
|
|
if (gnum < 2)
|
|
{
|
|
cm->green.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->green.num = gnum;
|
|
cm->green.px = Emalloc(gnum);
|
|
memcpy(cm->green.px, gpx, gnum);
|
|
cm->green.py = Emalloc(gnum);
|
|
memcpy(cm->green.py, gpy, gnum);
|
|
}
|
|
|
|
if (bnum < 2)
|
|
{
|
|
cm->blue.num = 0;
|
|
}
|
|
else
|
|
{
|
|
cm->blue.num = bnum;
|
|
cm->blue.px = Emalloc(bnum);
|
|
memcpy(cm->blue.px, bpx, bnum);
|
|
cm->blue.py = Emalloc(bnum);
|
|
memcpy(cm->blue.py, bpy, bnum);
|
|
}
|
|
|
|
CreateCurve(&(cm->red));
|
|
CreateCurve(&(cm->green));
|
|
CreateCurve(&(cm->blue));
|
|
|
|
EDBUG_RETURN_;
|
|
|
|
}
|