📄 jas_cm.c
字号:
} return 0;}static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut){ lut->data = 0; lut->size = 0;}static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *lut){ if (lut->data) { jas_free(lut->data); lut->data = 0; } lut->size = 0;}static double gammafn(double x, double gamma){ if (x == 0.0) return 0.0; return pow(x, gamma);}static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, jas_icccurv_t *curv){ jas_cmreal_t gamma; int i; gamma = 0; jas_cmshapmatlut_cleanup(lut); if (curv->numents == 0) { lut->size = 2; if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) goto error; lut->data[0] = 0.0; lut->data[1] = 1.0; } else if (curv->numents == 1) { lut->size = 256; if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) goto error; gamma = curv->ents[0] / 256.0; for (i = 0; i < lut->size; ++i) { lut->data[i] = gammafn(i / (double) (lut->size - 1), gamma); } } else { lut->size = curv->numents; if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) goto error; for (i = 0; i < lut->size; ++i) { lut->data[i] = curv->ents[i] / 65535.0; } } return 0;error: return -1;}static jas_cmreal_t jas_cmshapmatlut_lookup(jas_cmshapmatlut_t *lut, jas_cmreal_t x){ jas_cmreal_t t; int lo; int hi; t = x * (lut->size - 1); lo = floor(t); if (lo < 0) return lut->data[0]; hi = ceil(t); if (hi >= lut->size) return lut->data[lut->size - 1]; return lut->data[lo] + (t - lo) * (lut->data[hi] - lut->data[lo]);}static int jas_cmshapmatlut_invert(jas_cmshapmatlut_t *invlut, jas_cmshapmatlut_t *lut, int n){ int i; int j; int k; jas_cmreal_t ax; jas_cmreal_t ay; jas_cmreal_t bx; jas_cmreal_t by; jas_cmreal_t sx; jas_cmreal_t sy; assert(n >= 2); if (invlut->data) { jas_free(invlut->data); invlut->data = 0; } /* The sample values should be nondecreasing. */ for (i = 1; i < lut->size; ++i) { if (lut->data[i - 1] > lut->data[i]) { assert(0); return -1; } } if (!(invlut->data = jas_malloc(n * sizeof(jas_cmreal_t)))) return -1; invlut->size = n; for (i = 0; i < invlut->size; ++i) { sy = ((double) i) / (invlut->size - 1); sx = 1.0; for (j = 0; j < lut->size; ++j) { ay = lut->data[j]; if (sy == ay) { for (k = j + 1; k < lut->size; ++k) { by = lut->data[k]; if (by != sy) break;#if 0assert(0);#endif } if (k < lut->size) { --k; ax = ((double) j) / (lut->size - 1); bx = ((double) k) / (lut->size - 1); sx = (ax + bx) / 2.0; } break; } if (j < lut->size - 1) { by = lut->data[j + 1]; if (sy > ay && sy < by) { ax = ((double) j) / (lut->size - 1); bx = ((double) j + 1) / (lut->size - 1); sx = ax + (sy - ay) / (by - ay) * (bx - ax); break; } } } invlut->data[i] = sx; }#if 0for (i=0;i<lut->size;++i) jas_eprintf("lut[%d]=%f ", i, lut->data[i]);for (i=0;i<invlut->size;++i) jas_eprintf("invlut[%d]=%f ", i, invlut->data[i]);#endif return 0;}static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]){ jas_cmreal_t d; d = in[0][0] * (in[1][1] * in[2][2] - in[1][2] * in[2][1]) - in[0][1] * (in[1][0] * in[2][2] - in[1][2] * in[2][0]) + in[0][2] * (in[1][0] * in[2][1] - in[1][1] * in[2][0]);#if 0jas_eprintf("delta=%f\n", d);#endif if (JAS_ABS(d) < 1e-6) return -1; out[0][0] = (in[1][1] * in[2][2] - in[1][2] * in[2][1]) / d; out[1][0] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) / d; out[2][0] = (in[1][0] * in[2][1] - in[1][1] * in[2][0]) / d; out[0][1] = -(in[0][1] * in[2][2] - in[0][2] * in[2][1]) / d; out[1][1] = (in[0][0] * in[2][2] - in[0][2] * in[2][0]) / d; out[2][1] = -(in[0][0] * in[2][1] - in[0][1] * in[2][0]) / d; out[0][2] = (in[0][1] * in[1][2] - in[0][2] * in[1][1]) / d; out[1][2] = -(in[0][0] * in[1][2] - in[1][0] * in[0][2]) / d; out[2][2] = (in[0][0] * in[1][1] - in[0][1] * in[1][0]) / d; out[0][3] = -in[0][3]; out[1][3] = -in[1][3]; out[2][3] = -in[2][3];#if 0jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",in[0][0], in[0][1], in[0][2], in[0][3],in[1][0], in[1][1], in[1][2], in[1][3],in[2][0], in[2][1], in[2][2], in[2][3]);jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",out[0][0], out[0][1], out[0][2], out[0][3],out[1][0], out[1][1], out[1][2], out[1][3],out[2][0], out[2][1], out[2][2], out[2][3]);#endif return 0;}/******************************************************************************\*\******************************************************************************/static int icctoclrspc(int iccclrspc, int refflag){ if (refflag) { switch (iccclrspc) { case JAS_ICC_COLORSPC_XYZ: return JAS_CLRSPC_CIEXYZ; case JAS_ICC_COLORSPC_LAB: return JAS_CLRSPC_CIELAB; default: abort(); break; } } else { switch (iccclrspc) { case JAS_ICC_COLORSPC_YCBCR: return JAS_CLRSPC_GENYCBCR; case JAS_ICC_COLORSPC_RGB: return JAS_CLRSPC_GENRGB; case JAS_ICC_COLORSPC_GRAY: return JAS_CLRSPC_GENGRAY; default: abort(); break; } }}static int mono(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq){ jas_iccattrval_t *graytrc; jas_cmshapmat_t *shapmat; jas_cmpxform_t *pxform; jas_cmpxformseq_t *pxformseq; jas_cmshapmatlut_t lut; jas_cmshapmatlut_init(&lut); if (!(graytrc = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRYTRC)) || graytrc->type != JAS_ICC_TYPE_CURV) goto error; if (!(pxform = jas_cmpxform_createshapmat())) goto error; shapmat = &pxform->data.shapmat; if (!(pxformseq = jas_cmpxformseq_create())) goto error; if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) goto error; pxform->numinchans = 1; pxform->numoutchans = 3; shapmat->mono = 1; shapmat->useluts = 1; shapmat->usemat = 1; if (!op) { shapmat->order = 0; shapmat->mat[0][0] = 0.9642; shapmat->mat[1][0] = 1.0; shapmat->mat[2][0] = 0.8249; if (jas_cmshapmatlut_set(&shapmat->luts[0], &graytrc->data.curv)) goto error; } else { shapmat->order = 1; shapmat->mat[0][0] = 1.0 / 0.9642; shapmat->mat[1][0] = 1.0; shapmat->mat[2][0] = 1.0 / 0.8249; jas_cmshapmatlut_init(&lut); if (jas_cmshapmatlut_set(&lut, &graytrc->data.curv)) goto error; if (jas_cmshapmatlut_invert(&shapmat->luts[0], &lut, lut.size)) goto error; jas_cmshapmatlut_cleanup(&lut); } jas_iccattrval_destroy(graytrc); jas_cmpxform_destroy(pxform); *retpxformseq = pxformseq; return 0;error: return -1;}static int triclr(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq){ int i; jas_iccattrval_t *trcs[3]; jas_iccattrval_t *cols[3]; jas_cmshapmat_t *shapmat; jas_cmpxform_t *pxform; jas_cmpxformseq_t *pxformseq; jas_cmreal_t mat[3][4]; jas_cmshapmatlut_t lut; pxform = 0; pxformseq = 0; for (i = 0; i < 3; ++i) { trcs[i] = 0; cols[i] = 0; } jas_cmshapmatlut_init(&lut); if (!(trcs[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDTRC)) || !(trcs[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNTRC)) || !(trcs[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUTRC)) || !(cols[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDMATCOL)) || !(cols[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNMATCOL)) || !(cols[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUMATCOL))) goto error; for (i = 0; i < 3; ++i) { if (trcs[i]->type != JAS_ICC_TYPE_CURV || cols[i]->type != JAS_ICC_TYPE_XYZ) goto error; } if (!(pxform = jas_cmpxform_createshapmat())) goto error; pxform->numinchans = 3; pxform->numoutchans = 3; shapmat = &pxform->data.shapmat; if (!(pxformseq = jas_cmpxformseq_create())) goto error; if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) goto error; shapmat->mono = 0; shapmat->useluts = 1; shapmat->usemat = 1; if (!op) { shapmat->order = 0; for (i = 0; i < 3; ++i) { shapmat->mat[0][i] = cols[i]->data.xyz.x / 65536.0; shapmat->mat[1][i] = cols[i]->data.xyz.y / 65536.0; shapmat->mat[2][i] = cols[i]->data.xyz.z / 65536.0; } for (i = 0; i < 3; ++i) shapmat->mat[i][3] = 0.0; for (i = 0; i < 3; ++i) { if (jas_cmshapmatlut_set(&shapmat->luts[i], &trcs[i]->data.curv)) goto error; } } else { shapmat->order = 1; for (i = 0; i < 3; ++i) { mat[0][i] = cols[i]->data.xyz.x / 65536.0; mat[1][i] = cols[i]->data.xyz.y / 65536.0; mat[2][i] = cols[i]->data.xyz.z / 65536.0; } for (i = 0; i < 3; ++i) mat[i][3] = 0.0; if (jas_cmshapmat_invmat(shapmat->mat, mat)) goto error; for (i = 0; i < 3; ++i) { jas_cmshapmatlut_init(&lut); if (jas_cmshapmatlut_set(&lut, &trcs[i]->data.curv)) goto error; if (jas_cmshapmatlut_invert(&shapmat->luts[i], &lut, lut.size)) goto error; jas_cmshapmatlut_cleanup(&lut); } } for (i = 0; i < 3; ++i) { jas_iccattrval_destroy(trcs[i]); jas_iccattrval_destroy(cols[i]); } jas_cmpxform_destroy(pxform); *retpxformseq = pxformseq; return 0;error: for (i = 0; i < 3; ++i) { if (trcs[i]) { jas_iccattrval_destroy(trcs[i]); } if (cols[i]) { jas_iccattrval_destroy(cols[i]); } } if (pxformseq) { jas_cmpxformseq_destroy(pxformseq); } if (pxform) { jas_cmpxform_destroy(pxform); } return -1;}static int jas_cmgetint(long **bufptr, int sgnd, int prec, long *val){ long v; int m; v = **bufptr; if (sgnd) { m = (1 << (prec - 1)); if (v < -m || v >= m) return -1; } else { if (v < 0 || v >= (1 << prec)) return -1; } ++(*bufptr); *val = v; return 0;}static int jas_cmputint(long **bufptr, int sgnd, int prec, long val){ int m; if (sgnd) { m = (1 << (prec - 1)); if (val < -m || val >= m) return -1; } else { if (val < 0 || val >= (1 << prec)) return -1; } **bufptr = val; ++(*bufptr); return 0;}int jas_clrspc_numchans(int clrspc){ switch (jas_clrspc_fam(clrspc)) { case JAS_CLRSPC_FAM_XYZ: case JAS_CLRSPC_FAM_LAB: case JAS_CLRSPC_FAM_RGB: case JAS_CLRSPC_FAM_YCBCR: return 3; break; case JAS_CLRSPC_FAM_GRAY: return 1; break; default: abort(); break; }}jas_iccprof_t *jas_iccprof_createfromcmprof(jas_cmprof_t *prof){ return jas_iccprof_copy(prof->iccprof);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -