[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