[gs-cvs] rev 9790 - in branches/icc_work: base psi
mvrhel at ghostscript.com
mvrhel at ghostscript.com
Wed Jun 10 21:47:15 PDT 2009
Author: mvrhel
Date: 2009-06-10 21:47:15 -0700 (Wed, 10 Jun 2009)
New Revision: 9790
Modified:
branches/icc_work/base/gscie.c
branches/icc_work/base/gscie.h
branches/icc_work/base/gsicc_create.c
branches/icc_work/psi/zcie.c
Log:
Code for creating ICC profile from simple CIEA based PS type where the decode A, diagonal matrix A, decode lmn and matrixLMN are identity.
Modified: branches/icc_work/base/gscie.c
===================================================================
--- branches/icc_work/base/gscie.c 2009-06-11 02:40:18 UTC (rev 9789)
+++ branches/icc_work/base/gscie.c 2009-06-11 04:47:15 UTC (rev 9790)
@@ -151,7 +151,7 @@
/* Default transformation procedures. */
-static float
+float
a_identity(floatp in, const gs_cie_a * pcie)
{
return in;
Modified: branches/icc_work/base/gscie.h
===================================================================
--- branches/icc_work/base/gscie.h 2009-06-11 02:40:18 UTC (rev 9789)
+++ branches/icc_work/base/gscie.h 2009-06-11 04:47:15 UTC (rev 9790)
@@ -845,5 +845,6 @@
float common_identity(floatp in, const gs_cie_common * pcie);
float abc_identity(floatp in, const gs_cie_abc * pcie);
+float a_identity(floatp in, const gs_cie_a * pcie);
#endif /* gscie_INCLUDED */
Modified: branches/icc_work/base/gsicc_create.c
===================================================================
--- branches/icc_work/base/gsicc_create.c 2009-06-11 02:40:18 UTC (rev 9789)
+++ branches/icc_work/base/gsicc_create.c 2009-06-11 04:47:15 UTC (rev 9790)
@@ -125,6 +125,7 @@
#include "gscspace.h"
#include "gscie.h"
#include "gsicc_create.h"
+#include "gxarith.h"
#define SAVEICCPROFILE 1
#define HEADER_SIZE 128
@@ -163,6 +164,16 @@
}
+
+/* For some weird reason I cant link to the one in gscie.c */
+static void
+gsicc_matrix_init(register gs_matrix3 * mat)
+{
+ mat->is_identity =
+ mat->cu.u == 1.0 && is_fzero2(mat->cu.v, mat->cu.w) &&
+ mat->cv.v == 1.0 && is_fzero2(mat->cv.u, mat->cv.w) &&
+ mat->cw.w == 1.0 && is_fzero2(mat->cw.u, mat->cw.v);
+}
/* Debug dump of internally created ICC profile for testing */
static void
@@ -547,6 +558,9 @@
icTagSignature TRC_Tags[3] = {icSigRedTRCTag, icSigGreenTRCTag, icSigBlueTRCTag};
int trc_tag_size;
+ gsicc_matrix_init(&(pcie->common.MatrixLMN)); /* Need this set now */
+ gsicc_matrix_init(&(pcie->MatrixABC)); /* Need this set now */
+
/* Fill in the common stuff */
setheader_common(header);
@@ -758,19 +772,142 @@
}
+/* CIEA PS profiles can result in a surprisingly complex ICC profile.
+ The Decode A and Matrix A (which
+ is diagonal) are optional. The Decode LMN and MatrixLMN are
+ also optional. If the Matrix LMN is present, this will map the
+ gray value to CIEXYZ. In any of those are present, we will need
+ to do an MLUT. If all are absent, we end up doing a linear
+ mapping between the black point and the white point. A very simple
+ gray input profile with a linear TRC curve */
+
void
gsicc_create_froma(gs_cie_a *pcie, unsigned char *buffer, gs_memory_t *memory)
{
icProfile iccprofile;
icHeader *header = &(iccprofile.header);
+ int profile_size,k;
+ int num_tags;
+ gsicc_tag *tag_list;
+ int tag_offset = 0;
+ unsigned char *curr_ptr;
+ int last_tag;
+ icS15Fixed16Number temp_XYZ[3];
+ int tag_location;
+ int trc_tag_size;
+ gsicc_matrix_init(&(pcie->common.MatrixLMN)); /* Need this set now */
+
+ /* Fill in the common stuff */
+
setheader_common(header);
+
+ /* We will use an input type class
+ which keeps us from having to
+ create an inverse. */
+
+ header->deviceClass = icSigInputClass;
+ header->colorSpace = icSigGrayData;
+ header->pcs = icSigXYZData; /* If MLUT do we want CIELAB? */
+
+ profile_size = HEADER_SIZE;
+
+ /* Check if we have no LMN or A methods. A simple profile */
+
+ if(pcie->MatrixA.u == 1.0 && pcie->MatrixA.v == 1.0 && pcie->MatrixA.w == 1.0 && pcie->DecodeA == a_identity
+ && pcie->common.MatrixLMN.is_identity && pcie->common.DecodeLMN.procs[0] == common_identity
+ && pcie->common.DecodeLMN.procs[1] == common_identity && pcie->common.DecodeLMN.procs[2] == common_identity){
+
+ num_tags = 5; /* common (2) + grayTRC,bkpt,wtpt */
+ tag_list = (gsicc_tag*) gs_alloc_bytes(memory,sizeof(gsicc_tag)*num_tags,"gsicc_create_froma");
+
+ /* Let us precompute the sizes of everything and all our offsets */
+
+ profile_size += TAG_SIZE*num_tags;
+ profile_size += 4; /* number of tags.... */
+
+ last_tag = -1;
+ init_common_tags(tag_list, num_tags, &last_tag);
+
+ init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE);
+ init_tag(tag_list, &last_tag, icSigMediaBlackPointTag, XYZPT_SIZE);
+
+ trc_tag_size = 4;
+
+ init_tag(tag_list, &last_tag, icSigGrayTRCTag, trc_tag_size);
+
+ for(k = 0; k < num_tags; k++){
+
+ profile_size += tag_list[k].size;
+
+ }
+
+ /* Now we can go ahead and fill our buffer with the data */
+
+ buffer = gs_alloc_bytes(memory,profile_size,"gsicc_create_fromabc");
+ curr_ptr = buffer;
+
+ /* The header */
+
+ header->size = profile_size;
+ copy_header(curr_ptr,header);
+ curr_ptr += HEADER_SIZE;
+
+ /* Tag table */
+
+ copy_tagtable(curr_ptr,tag_list,num_tags);
+ curr_ptr += TAG_SIZE*num_tags;
+ curr_ptr += 4;
+
+ /* Now the data. Must be in same order as we created the tag table */
+
+ /* First the common tags */
+
+ add_common_tag_data(curr_ptr, tag_list);
+
+ for (k = 0; k< NUMBER_COMMON_TAGS; k++)
+ {
+ curr_ptr += tag_list[k].size;
+ }
+
+ tag_location = NUMBER_COMMON_TAGS;
+
+ /* Need to adjust for the D65/D50 issue */
+ get_XYZ(temp_XYZ,pcie->common.points.WhitePoint);
+ add_xyzdata(curr_ptr,temp_XYZ);
+ curr_ptr += tag_list[tag_location].size;
+ tag_location++;
+
+ get_XYZ(temp_XYZ,pcie->common.points.BlackPoint);
+ add_xyzdata(curr_ptr,temp_XYZ);
+ curr_ptr += tag_list[tag_location].size;
+
+ write_bigendian_4bytes(curr_ptr,icSigCurveType);
+ curr_ptr+=4;
+ memset(curr_ptr,0,8); /* reserved + number points */
+ curr_ptr+=8;
+
+
+ } else {
+
+ /* We will need to create a small 2x2 MLUT */
+
+
+
+
+ }
+#if SAVEICCPROFILE
+ /* Dump the buffer to a file for testing if its a valid ICC profile */
+ save_profile(buffer,"froma",profile_size);
+#endif
+
+
}
Modified: branches/icc_work/psi/zcie.c
===================================================================
--- branches/icc_work/psi/zcie.c 2009-06-11 02:40:18 UTC (rev 9789)
+++ branches/icc_work/psi/zcie.c 2009-06-11 04:47:15 UTC (rev 9790)
@@ -443,7 +443,6 @@
will have all the data that we will need like it is here
in pcie. */
-
gsicc_create_fromabc(pcie, NULL, imemory);
@@ -490,10 +489,23 @@
if (code < 0)
return code;
pcie = pcs->params.a;
- if ((code = dict_floats_param(imemory, CIEdict, "RangeA", 2, (float *)&pcie->RangeA, (const float *)&RangeA_default)) < 0 ||
- (code = dict_floats_param(imemory, CIEdict, "MatrixA", 3, (float *)&pcie->MatrixA, (const float *)&MatrixA_default)) < 0 ||
- (code = cie_lmnp_param(imemory, CIEdict, &pcie->common, &procs)) < 0 ||
- (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
+
+ code = dict_floats_param(imemory, CIEdict, "RangeA", 2, (float *)&pcie->RangeA, (const float *)&RangeA_default);
+ if (code < 0)
+ return code;
+ code = dict_floats_param(imemory, CIEdict, "MatrixA", 3, (float *)&pcie->MatrixA, (const float *)&MatrixA_default);
+ if (code < 0)
+ return code;
+ code = cie_lmnp_param(imemory, CIEdict, &pcie->common, &procs);
+ if (code < 0)
+ return code;
+
+ /* Pulled the above out of the if below to make some ICC conversion testing easier */
+
+ gsicc_create_froma(pcie, NULL, imemory);
+
+
+ if ((code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
(code = cie_cache_push_finish(i_ctx_p, cie_a_finish, imem, pcie)) < 0 ||
(code = cie_prepare_cache(i_ctx_p, &pcie->RangeA, &procs.Decode.A, &pcie->caches.DecodeA.floats, pcie, imem, "Decode.A")) < 0 ||
(code = cache_common(i_ctx_p, &pcie->common, &procs, pcie, imem)) < 0
More information about the gs-cvs
mailing list