home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Der Mediaplex Sampler - Die 6 von Plex
/
6_v_plex.zip
/
6_v_plex
/
DISK5
/
DOS_14
/
GS252DVX.ZIP
/
GSCIE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-21
|
8KB
|
244 lines
/* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
Distributed by Free Software Foundation, Inc.
This file is part of Ghostscript.
Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the Ghostscript General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License. A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies. */
/* gscie.c */
/* CIE color algorithms for Ghostscript */
#include "std.h"
#include "gscspace.h"
#include "gscie.h"
/* Default values for components. */
private float
fp_identity(floatp value)
{ return (float)value;
}
const gs_range3 Range3_default = { {0,1}, {0,1}, {0,1} };
const gs_float_proc3 Decode3_default = { fp_identity, fp_identity, fp_identity };
const gs_matrix3 Matrix3_default = { {1,0,0}, {0,1,0}, {0,0,1} };
const gs_range RangeA_default = {0,1};
const gs_float_proc DecodeA_default = fp_identity;
const gs_vector3 MatrixA_default = { 1, 1, 1 };
const gs_vector3 BlackPoint_default = { 0, 0, 0 };
/* Apply procedures to a vector. */
private void
cie_apply3(const gs_vector3 *in, const gs_float_proc3 *procs, gs_vector3 *out)
{ out->u = (*procs->u)(in->u);
out->v = (*procs->v)(in->v);
out->w = (*procs->w)(in->w);
}
/* Multiply a vector by a matrix. */
private void
cie_mult3(const gs_vector3 *in, register const gs_matrix3 *mat, gs_vector3 *out)
{ float u = in->u, v = in->v, w = in->w;
out->u = (u * mat->cu.u) + (v * mat->cu.v) + (w * mat->cu.w);
out->v = (u * mat->cv.u) + (v * mat->cv.v) + (w * mat->cv.w);
out->w = (u * mat->cw.u) + (v * mat->cw.v) + (w * mat->cw.w);
}
/* Invert a matrix. */
private void
cie_invert3(register const gs_matrix3 *in, register gs_matrix3 *out)
{ /* This is a brute force algorithm; maybe there are better. */
/* We label the array elements */
/* [ A B C ] */
/* [ D E F ] */
/* [ G H I ] */
#define A cu.u
#define B cv.u
#define C cw.u
#define D cu.v
#define E cv.v
#define F cw.v
#define G cu.w
#define H cv.w
#define I cw.w
double AE = in->A * in->E, AF = in->A * in->F,
AH = in->A * in->H, AI = in->A * in->I;
double BD = in->B * in->D, BF = in->B * in->F,
BG = in->B * in->G, BI = in->B * in->I;
double CD = in->C * in->D, CE = in->C * in->E,
CG = in->C * in->G, CH = in->C * in->H;
double DH = in->D * in->H, DI = in->D * in->I;
double EG = in->E * in->G, EI = in->E * in->I;
double FG = in->F * in->G, FH = in->F * in->H;
double coA = EI - FH, coB = FG - DI, coC = DH - EG;
double det = in->A * coA + in->B * coB + in->C * coC;
out->A = coA / det;
out->D = coB / det;
out->G = coC / det;
out->B = (CH - BI) / det;
out->E = (AI - CG) / det;
out->H = (BG - AH) / det;
out->C = (BF - CE) / det;
out->F = (CD - AF) / det;
out->I = (AE - BD) / det;
#undef A
#undef B
#undef C
#undef D
#undef E
#undef F
#undef G
#undef H
#undef I
}
/* Force values within bounds. */
#define restrict(v, r)\
((v) < (r).rmin ? (r).rmin : (v) > (r).rmax ? (r).rmax : (v))
private void
cie_restrict3(const gs_vector3 *in, const gs_range3 *range, gs_vector3 *out)
{ float temp;
temp = in->u; out->u = restrict(temp, range->u);
temp = in->v; out->v = restrict(temp, range->v);
temp = in->w; out->w = restrict(temp, range->w);
}
/* Decode ABC values to XYZ. */
int
gs_cie_abc_decode1(const gs_vector3 *pabc, gs_vector3 *ptabc, const gs_cie_abc *pcie)
{ cie_restrict3(pabc, &pcie->RangeABC, ptabc);
return 0;
}
/*
* Client:
cie_apply3(ptabc, &pcie->DecodeABC, ptabc);
*/
int
gs_cie_abc_decode2(const gs_vector3 *ptabc, gs_vector3 *ptlmn, const gs_cie_abc *pcie)
{ cie_mult3(ptabc, &pcie->MatrixABC, ptlmn);
cie_restrict3(ptlmn, &pcie->common.RangeLMN, ptlmn);
return 0;
}
/*
* Client:
cie_apply3(ptlmn, &pcie->common.DecodeLMN, ptlmn);
*/
int
gs_cie_abc_decode3(const gs_vector3 *ptlmn, gs_vector3 *pxyz, const gs_cie_abc *pcie)
{ cie_mult3(ptlmn, &pcie->common.MatrixLMN, pxyz);
return 0;
}
/* Decode an A value to XYZ. */
int
gs_cie_a_decode1(floatp va, float *pta, const gs_cie_a *pcie)
{ *pta = restrict(va, pcie->RangeA);
return 0;
}
/*
* Client:
ta = (*pcie->DecodeA)(*pta);
*/
int
gs_cie_a_decode2(floatp ta, gs_vector3 *ptlmn, const gs_cie_a *pcie)
{ gs_vector3 lmn;
lmn.u = ta * pcie->MatrixA.u;
lmn.v = ta * pcie->MatrixA.v;
lmn.w = ta * pcie->MatrixA.w;
cie_restrict3(&lmn, &pcie->common.RangeLMN, ptlmn);
return 0;
}
/*
* Client:
cie_apply3(ptlmn, &pcie->common.DecodeLMN, ptlmn);
*/
/* gs_cie_a_decode3 is the same as gs_cie_abc_decode3. */
/* Initialize the computed fields of a CIE color rendering structure. */
int
gs_cie_render_init(gs_cie_render *pcie)
{ cie_invert3(&pcie->MatrixPQR, &pcie->MatrixPQR_inverse);
cie_mult3(&pcie->points.WhitePoint, &pcie->MatrixPQR, &pcie->wdpqr);
cie_mult3(&pcie->points.BlackPoint, &pcie->MatrixPQR, &pcie->bdpqr);
return 0;
}
/* Render CIE colors */
int
gs_cie_render_colors1(const gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ptpqr, gs_cie_wb *points, const gs_cie_render *pcie)
{ cie_mult3(pxyz, &pcie->MatrixPQR, ptpqr);
pwbsd->ws.xyz = points->WhitePoint;
cie_mult3(&pwbsd->ws.xyz, &pcie->MatrixPQR, &pwbsd->ws.pqr);
pwbsd->bs.xyz = points->BlackPoint;
cie_mult3(&pwbsd->bs.xyz, &pcie->MatrixPQR, &pwbsd->bs.pqr);
pwbsd->wd.xyz = pcie->points.WhitePoint;
pwbsd->wd.pqr = pcie->wdpqr;
pwbsd->bd.xyz = pcie->points.BlackPoint;
pwbsd->bd.pqr = pcie->bdpqr;
return 0;
}
/*
* Client:
ptpqr->u = (*pcie->TransformPQR.u)(pwbsd, ptpqr->u);
ptpqr->v = (*pcie->TransformPQR.v)(pwbsd, ptpqr->v);
ptpqr->w = (*pcie->TransformPQR.w)(pwbsd, ptpqr->w);
*/
int
gs_cie_render_colors2(const gs_vector3 *ptpqr, gs_vector3 *ptlmn, const gs_cie_render *pcie)
{ gs_vector3 xyzd;
cie_mult3(ptpqr, &pcie->MatrixPQR_inverse, &xyzd);
cie_mult3(&xyzd, &pcie->MatrixLMN, ptlmn);
return 0;
}
/*
/* Client:
cie_apply3(ptlmn, &pcie->EncodeLMN, ptlmn);
*/
int
gs_cir_render_colors3(const gs_vector3 *ptlmn, gs_vector3 *ptabc, const gs_cie_render *pcie)
{ gs_vector3 lmn;
cie_restrict3(ptlmn, &pcie->RangeLMN, &lmn);
cie_mult3(&lmn, &pcie->MatrixABC, ptabc);
return 0;
}
/*
* Client:
cie_apply3(ptabc, &pcie->EncodeABC, ptabc);
*/
int
gs_cie_render_colors4(const gs_vector3 *ptabc, float *colors, const gs_cie_render *pcie)
{ gs_vector3 abc;
cie_restrict3(ptabc, &pcie->RangeABC, &abc);
if ( pcie->RenderTable.table == 0 )
{ /* No further transformation */
colors[0] = abc.u;
colors[1] = abc.v;
colors[2] = abc.w;
}
else
{ /* Use the RenderTable. */
int m = pcie->RenderTable.m;
#define ri(s,n)\
(int)((abc.s - pcie->RangeABC.s.rmin) * (pcie->RenderTable.n - 1) /\
(pcie->RangeABC.s.rmax - pcie->RangeABC.s.rmin) + 0.5)
int ia = ri(u, NA);
int ib = ri(v, NB);
int ic = ri(w, NC);
int j;
byte *pdc = pcie->RenderTable.table[ia] +
m * (ib * pcie->RenderTable.NC + ic);
for ( j = 0; j < m; j++ )
colors[j] = (*pcie->RenderTable.T[j])(pdc[j] / 255.0);
}
return 0;
}