📄 jas_cm.c
字号:
goto error;
if (altoutpxformseq) {
if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) ||
jas_cmpxformseq_append(xform->pxformseq, altoutpxformseq))
goto error;
} else {
if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq))
goto error;
}
if (jas_cmpxformseq_appendcnvt(xform->pxformseq,
outprof->refclrspc, inprof->refclrspc) ||
jas_cmpxformseq_append(xform->pxformseq, prfpxformseq))
goto error;
xform->numinchans = jas_clrspc_numchans(inprof->clrspc);
xform->numoutchans = jas_clrspc_numchans(prfprof->clrspc);
break;
case JAS_CMXFORM_OP_GAMUT:
inpxformseq = fwdpxformseq(inprof, intent);
outpxformseq = gampxformseq(outprof);
if (!inpxformseq || !outpxformseq)
goto error;
if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||
jas_cmpxformseq_appendcnvt(xform->pxformseq,
inprof->refclrspc, outprof->refclrspc) ||
jas_cmpxformseq_append(xform->pxformseq, outpxformseq))
goto error;
xform->numinchans = jas_clrspc_numchans(inprof->clrspc);
xform->numoutchans = 1;
break;
}
return xform;
error:
return 0;
}
#define APPLYBUFSIZ 2048
int jas_cmxform_apply(jas_cmxform_t *xform, jas_cmpixmap_t *in, jas_cmpixmap_t *out)
{
jas_cmcmptfmt_t *fmt;
jas_cmreal_t buf[2][APPLYBUFSIZ];
jas_cmpxformseq_t *pxformseq;
int i;
int j;
int width;
int height;
int total;
int n;
jas_cmreal_t *inbuf;
jas_cmreal_t *outbuf;
jas_cmpxform_t *pxform;
long *dataptr;
int maxchans;
int bufmax;
int m;
int bias;
jas_cmreal_t scale;
long v;
jas_cmreal_t *bufptr;
if (xform->numinchans > in->numcmpts || xform->numoutchans > out->numcmpts)
goto error;
fmt = &in->cmptfmts[0];
width = fmt->width;
height = fmt->height;
for (i = 1; i < xform->numinchans; ++i) {
fmt = &in->cmptfmts[i];
if (fmt->width != width || fmt->height != height) {
goto error;
}
}
for (i = 0; i < xform->numoutchans; ++i) {
fmt = &out->cmptfmts[i];
if (fmt->width != width || fmt->height != height) {
goto error;
}
}
maxchans = 0;
pxformseq = xform->pxformseq;
for (i = 0; i < pxformseq->numpxforms; ++i) {
pxform = pxformseq->pxforms[i];
if (pxform->numinchans > maxchans) {
maxchans = pxform->numinchans;
}
if (pxform->numoutchans > maxchans) {
maxchans = pxform->numoutchans;
}
}
bufmax = APPLYBUFSIZ / maxchans;
assert(bufmax > 0);
total = width * height;
n = 0;
while (n < total) {
inbuf = &buf[0][0];
m = JAS_MIN(total - n, bufmax);
for (i = 0; i < xform->numinchans; ++i) {
fmt = &in->cmptfmts[i];
scale = (double)((1 << fmt->prec) - 1);
bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0;
dataptr = &fmt->buf[n];
bufptr = &inbuf[i];
for (j = 0; j < m; ++j) {
if (jas_cmgetint(&dataptr, fmt->sgnd, fmt->prec, &v))
goto error;
*bufptr = (v - bias) / scale;
bufptr += xform->numinchans;
}
}
inbuf = &buf[0][0];
outbuf = inbuf;
for (i = 0; i < pxformseq->numpxforms; ++i) {
pxform = pxformseq->pxforms[i];
if (pxform->numoutchans > pxform->numinchans) {
outbuf = (inbuf == &buf[0][0]) ? &buf[1][0] : &buf[0][0];
} else {
outbuf = inbuf;
}
if ((*pxform->ops->apply)(pxform, inbuf, outbuf, m))
goto error;
inbuf = outbuf;
}
for (i = 0; i < xform->numoutchans; ++i) {
fmt = &out->cmptfmts[i];
scale = (double)((1 << fmt->prec) - 1);
bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0;
bufptr = &outbuf[i];
dataptr = &fmt->buf[n];
for (j = 0; j < m; ++j) {
v = (*bufptr) * scale + bias;
bufptr += xform->numoutchans;
if (jas_cmputint(&dataptr, fmt->sgnd, fmt->prec, v))
goto error;
}
}
n += m;
}
return 0;
error:
return -1;
}
void jas_cmxform_destroy(jas_cmxform_t *xform)
{
if (xform->pxformseq)
jas_cmpxformseq_destroy(xform->pxformseq);
jas_free(xform);
}
/******************************************************************************\
* Primitive transform sequence class.
\******************************************************************************/
static jas_cmpxformseq_t *jas_cmpxformseq_create()
{
jas_cmpxformseq_t *pxformseq;
pxformseq = 0;
if (!(pxformseq = jas_malloc(sizeof(jas_cmpxformseq_t))))
goto error;
pxformseq->pxforms = 0;
pxformseq->numpxforms = 0;
pxformseq->maxpxforms = 0;
if (jas_cmpxformseq_resize(pxformseq, 16))
goto error;
return pxformseq;
error:
if (pxformseq)
jas_cmpxformseq_destroy(pxformseq);
return 0;
}
static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq)
{
jas_cmpxformseq_t *newpxformseq;
if (!(newpxformseq = jas_cmpxformseq_create()))
goto error;
if (jas_cmpxformseq_append(newpxformseq, pxformseq))
goto error;
return newpxformseq;
error:
return 0;
}
static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq)
{
while (pxformseq->numpxforms > 0)
jas_cmpxformseq_delete(pxformseq, pxformseq->numpxforms - 1);
if (pxformseq->pxforms)
jas_free(pxformseq->pxforms);
jas_free(pxformseq);
}
static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, int i)
{
assert(i >= 0 && i < pxformseq->numpxforms);
if (i != pxformseq->numpxforms - 1)
abort();
jas_cmpxform_destroy(pxformseq->pxforms[i]);
pxformseq->pxforms[i] = 0;
--pxformseq->numpxforms;
return 0;
}
static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq,
int dstclrspc, int srcclrspc)
{
if (dstclrspc == srcclrspc)
return 0;
abort();
/* Avoid compiler warnings about unused parameters. */
pxformseq = 0;
return -1;
}
static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq,
int i, jas_cmpxform_t *pxform)
{
jas_cmpxform_t *tmppxform;
int n;
if (i < 0)
i = pxformseq->numpxforms;
assert(i >= 0 && i <= pxformseq->numpxforms);
if (pxformseq->numpxforms >= pxformseq->maxpxforms) {
if (jas_cmpxformseq_resize(pxformseq, pxformseq->numpxforms +
16))
goto error;
}
assert(pxformseq->numpxforms < pxformseq->maxpxforms);
if (!(tmppxform = jas_cmpxform_copy(pxform)))
goto error;
n = pxformseq->numpxforms - i;
if (n > 0) {
memmove(&pxformseq->pxforms[i + 1], &pxformseq->pxforms[i],
n * sizeof(jas_cmpxform_t *));
}
pxformseq->pxforms[i] = tmppxform;
++pxformseq->numpxforms;
return 0;
error:
return -1;
}
static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq,
jas_cmpxformseq_t *othpxformseq)
{
int n;
int i;
jas_cmpxform_t *pxform;
jas_cmpxform_t *othpxform;
n = pxformseq->numpxforms + othpxformseq->numpxforms;
if (n > pxformseq->maxpxforms) {
if (jas_cmpxformseq_resize(pxformseq, n))
goto error;
}
for (i = 0; i < othpxformseq->numpxforms; ++i) {
othpxform = othpxformseq->pxforms[i];
if (!(pxform = jas_cmpxform_copy(othpxform)))
goto error;
pxformseq->pxforms[pxformseq->numpxforms] = pxform;
++pxformseq->numpxforms;
}
return 0;
error:
return -1;
}
static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, int n)
{
jas_cmpxform_t **p;
assert(n >= pxformseq->numpxforms);
p = (!pxformseq->pxforms) ? jas_malloc(n * sizeof(jas_cmpxform_t *)) :
jas_realloc(pxformseq->pxforms, n * sizeof(jas_cmpxform_t *));
if (!p) {
return -1;
}
pxformseq->pxforms = p;
pxformseq->maxpxforms = n;
return 0;
}
/******************************************************************************\
* Primitive transform class.
\******************************************************************************/
static jas_cmpxform_t *jas_cmpxform_create0()
{
jas_cmpxform_t *pxform;
if (!(pxform = jas_malloc(sizeof(jas_cmpxform_t))))
return 0;
memset(pxform, 0, sizeof(jas_cmpxform_t));
pxform->refcnt = 0;
pxform->ops = 0;
return pxform;
}
static void jas_cmpxform_destroy(jas_cmpxform_t *pxform)
{
if (--pxform->refcnt <= 0) {
(*pxform->ops->destroy)(pxform);
jas_free(pxform);
}
}
static jas_cmpxform_t *jas_cmpxform_copy(jas_cmpxform_t *pxform)
{
++pxform->refcnt;
return pxform;
}
/******************************************************************************\
* Shaper matrix class.
\******************************************************************************/
static jas_cmpxform_t *jas_cmpxform_createshapmat()
{
int i;
int j;
jas_cmpxform_t *pxform;
jas_cmshapmat_t *shapmat;
if (!(pxform = jas_cmpxform_create0()))
return 0;
pxform->ops = &shapmat_ops;
shapmat = &pxform->data.shapmat;
shapmat->mono = 0;
shapmat->order = 0;
shapmat->useluts = 0;
shapmat->usemat = 0;
for (i = 0; i < 3; ++i)
jas_cmshapmatlut_init(&shapmat->luts[i]);
for (i = 0; i < 3; ++i) {
for (j = 0; j < 4; ++j)
shapmat->mat[i][j] = 0.0;
}
++pxform->refcnt;
return pxform;
}
static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform)
{
jas_cmshapmat_t *shapmat = &pxform->data.shapmat;
int i;
for (i = 0; i < 3; ++i)
jas_cmshapmatlut_cleanup(&shapmat->luts[i]);
}
static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in,
jas_cmreal_t *out, int cnt)
{
jas_cmshapmat_t *shapmat = &pxform->data.shapmat;
jas_cmreal_t *src;
jas_cmreal_t *dst;
jas_cmreal_t a0;
jas_cmreal_t a1;
jas_cmreal_t a2;
jas_cmreal_t b0;
jas_cmreal_t b1;
jas_cmreal_t b2;
src = in;
dst = out;
if (!shapmat->mono) {
while (--cnt >= 0) {
a0 = *src++;
a1 = *src++;
a2 = *src++;
if (!shapmat->order && shapmat->useluts) {
a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1);
a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2);
}
if (shapmat->usemat) {
b0 = shapmat->mat[0][0] * a0
+ shapmat->mat[0][1] * a1
+ shapmat->mat[0][2] * a2
+ shapmat->mat[0][3];
b1 = shapmat->mat[1][0] * a0
+ shapmat->mat[1][1] * a1
+ shapmat->mat[1][2] * a2
+ shapmat->mat[1][3];
b2 = shapmat->mat[2][0] * a0
+ shapmat->mat[2][1] * a1
+ shapmat->mat[2][2] * a2
+ shapmat->mat[2][3];
a0 = b0;
a1 = b1;
a2 = b2;
}
if (shapmat->order && shapmat->useluts) {
a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1);
a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2);
}
*dst++ = a0;
*dst++ = a1;
*dst++ = a2;
}
} else {
if (!shapmat->order) {
while (--cnt >= 0) {
a0 = *src++;
if (shapmat->useluts)
a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
a2 = a0 * shapmat->mat[2][0];
a1 = a0 * shapmat->mat[1][0];
a0 = a0 * shapmat->mat[0][0];
*dst++ = a0;
*dst++ = a1;
*dst++ = a2;
}
} else {
assert(0);
while (--cnt >= 0) {
a0 = *src++;
src++;
src++;
a0 = a0 * shapmat->mat[0][0];
if (shapmat->useluts)
a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
*dst++ = a0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -