xref: /AOO41X/main/icc/source/create_sRGB_profile/create_sRGB_profile.cpp (revision 7b400455c6038e4083b29c29e4e41ac3981ea845)
1cdf0e10cSrcweir /*************************************************************************
2cdf0e10cSrcweir  *
31584ef18SPedro Giffuni  *  Apache OpenOffice - a multi-platform office productivity suite
4cdf0e10cSrcweir  *
5cdf0e10cSrcweir 
6cdf0e10cSrcweir   Derived by beppec56@openoffice.org from various examples
7cdf0e10cSrcweir   in SampleICC library, the original copyright retained.
8cdf0e10cSrcweir 
9cdf0e10cSrcweir   Copyright:  � see below
10cdf0e10cSrcweir */
11cdf0e10cSrcweir 
12cdf0e10cSrcweir /*
13cdf0e10cSrcweir  * The ICC Software License, Version 0.1
14cdf0e10cSrcweir  *
15cdf0e10cSrcweir  *
16cdf0e10cSrcweir  * Copyright (c) 2003-2006 The International Color Consortium. All rights
17cdf0e10cSrcweir  * reserved.
18cdf0e10cSrcweir  *
19cdf0e10cSrcweir  * Redistribution and use in source and binary forms, with or without
20cdf0e10cSrcweir  * modification, are permitted provided that the following conditions
21cdf0e10cSrcweir  * are met:
22cdf0e10cSrcweir  *
23cdf0e10cSrcweir  * 1. Redistributions of source code must retain the above copyright
24cdf0e10cSrcweir  *    notice, this list of conditions and the following disclaimer.
25cdf0e10cSrcweir  *
26cdf0e10cSrcweir  * 2. Redistributions in binary form must reproduce the above copyright
27cdf0e10cSrcweir  *    notice, this list of conditions and the following disclaimer in
28cdf0e10cSrcweir  *    the documentation and/or other materials provided with the
29cdf0e10cSrcweir  *    distribution.
30cdf0e10cSrcweir  *
31cdf0e10cSrcweir  * 3. The end-user documentation included with the redistribution,
32cdf0e10cSrcweir  *    if any, must include the following acknowledgment:
33cdf0e10cSrcweir  *       "This product includes software developed by the
34cdf0e10cSrcweir  *        The International Color Consortium (www.color.org)"
35cdf0e10cSrcweir  *    Alternately, this acknowledgment may appear in the software itself,
36cdf0e10cSrcweir  *    if and wherever such third-party acknowledgments normally appear.
37cdf0e10cSrcweir  *
38cdf0e10cSrcweir  * 4. The names "ICC" and "The International Color Consortium" must
39cdf0e10cSrcweir  *    not be used to imply that the ICC organization endorses or
40cdf0e10cSrcweir  *    promotes products derived from this software without prior
41cdf0e10cSrcweir  *    written permission. For written permission, please see
42cdf0e10cSrcweir  *    <http://www.color.org/>.
43cdf0e10cSrcweir  *
44cdf0e10cSrcweir  *
45cdf0e10cSrcweir  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46cdf0e10cSrcweir  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47cdf0e10cSrcweir  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48cdf0e10cSrcweir  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
49cdf0e10cSrcweir  * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50cdf0e10cSrcweir  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51cdf0e10cSrcweir  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52cdf0e10cSrcweir  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53cdf0e10cSrcweir  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54cdf0e10cSrcweir  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55cdf0e10cSrcweir  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56cdf0e10cSrcweir  * SUCH DAMAGE.
57cdf0e10cSrcweir  * ====================================================================
58cdf0e10cSrcweir  *
59cdf0e10cSrcweir  * This software consists of voluntary contributions made by many
60cdf0e10cSrcweir  * individuals on behalf of the The International Color Consortium.
61cdf0e10cSrcweir  *
62cdf0e10cSrcweir  *
63cdf0e10cSrcweir  * Membership in the ICC is encouraged when this software is used for
64cdf0e10cSrcweir  * commercial purposes.
65cdf0e10cSrcweir  *
66cdf0e10cSrcweir  *
67cdf0e10cSrcweir  * For more information on The International Color Consortium, please
68cdf0e10cSrcweir  * see <http://www.color.org/>.
69cdf0e10cSrcweir  *
70cdf0e10cSrcweir  *
71cdf0e10cSrcweir  */
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #include <math.h>
74cdf0e10cSrcweir #include <iostream>
75cdf0e10cSrcweir #include <fstream>
76cdf0e10cSrcweir using namespace std;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir #include "IccUtil.h"
79cdf0e10cSrcweir #include "IccProfile.h"
80cdf0e10cSrcweir 
81cdf0e10cSrcweir #include "Vetters.h"
82cdf0e10cSrcweir #include "CAT.h"
83cdf0e10cSrcweir #include "CLUT.h"
84cdf0e10cSrcweir 
85cdf0e10cSrcweir const char * const icc_file_name = "sRGB-IEC61966-2.1.icc";
86cdf0e10cSrcweir const char * const hxx_file_name = "sRGB-IEC61966-2.1.hxx";
87cdf0e10cSrcweir const char * const this_file_name_and_location =" * icc/source/create_sRGB_profile/create_sRGB_profile.cpp";
88cdf0e10cSrcweir 
89cdf0e10cSrcweir const char* const description = "sRGB IEC61966-2.1";
90cdf0e10cSrcweir //const char* const devicemanufact = "IEC http://www.iec.ch"; not used, device manufactured by OOo seems funny...
91cdf0e10cSrcweir const char* const devicemodel = "IEC 61966-2.1 Default RGB colour space - sRGB";
92*7b400455SPedro Giffuni const char* const copyright = "Licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the License.";
93cdf0e10cSrcweir 
94cdf0e10cSrcweir // the creation date is fixed, corresponds to the last time this file has been changed
95cdf0e10cSrcweir // NOTE: change this date values whenever the data inside the profile are changed.
96ed545546SPedro Giffuni const int  data_last_changed_year =     2011;
97ed545546SPedro Giffuni const int  data_last_changed_month =    10;
98ed545546SPedro Giffuni const int  data_last_day =              16;
99cdf0e10cSrcweir const int  data_last_changed_hour =     18;
100ed545546SPedro Giffuni const int  data_last_changed_minute =   55;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir // the following string array it's the standard OOo header format
103cdf0e10cSrcweir const char * const TheHeader1[] =
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     "/*************************************************************************",
106cdf0e10cSrcweir     " *",
1071584ef18SPedro Giffuni     " *  Apache OpenOffice - a multi-platform office productivity suite",
108cdf0e10cSrcweir     " *",
109cdf0e10cSrcweir     " *  sRGB-IEC61966-2.1.hxx",
110cdf0e10cSrcweir     " *",
111cdf0e10cSrcweir     " *  creator: create_sRGB_profile",
112cdf0e10cSrcweir     NULL
113cdf0e10cSrcweir };
114cdf0e10cSrcweir 
115cdf0e10cSrcweir const char * const TheHeader2[] =
116cdf0e10cSrcweir {
117cdf0e10cSrcweir     " *",
1181584ef18SPedro Giffuni     " * Copyright 2012, 2011 Apache OpenOffice.",
119cdf0e10cSrcweir     " *",
12043d0bd0fSPedro Giffuni     " * Licensed under the Apache License, Version 2.0 (the \"License\");",
12143d0bd0fSPedro Giffuni     " * you may not use this file except in compliance with the License.",
12243d0bd0fSPedro Giffuni     " * You may obtain a copy of the License at",
123cdf0e10cSrcweir     " *",
12443d0bd0fSPedro Giffuni     " *     http://www.apache.org/licenses/LICENSE-2.0",
125cdf0e10cSrcweir     " *",
12643d0bd0fSPedro Giffuni     " * Unless required by applicable law or agreed to in writing, software",
12743d0bd0fSPedro Giffuni     " * distributed under the License is distributed on an \"AS IS\" BASIS,",
12843d0bd0fSPedro Giffuni     " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
12943d0bd0fSPedro Giffuni     " * See the License for the specific language governing permissions and",
13043d0bd0fSPedro Giffuni     " * limitations under the License.",
131cdf0e10cSrcweir     " *",
132cdf0e10cSrcweir     " ************************************************************************/",
133cdf0e10cSrcweir     "",
134cdf0e10cSrcweir     "#ifndef INCLUDED_ICC_SRGB_IEC61966_2_1_H",
135cdf0e10cSrcweir     "#define INCLUDED_ICC_SRGB_IEC61966_2_1_H",
136cdf0e10cSrcweir     "",
137cdf0e10cSrcweir     "/***********************************************************************",
138cdf0e10cSrcweir     " * NOTE:",
139cdf0e10cSrcweir     " * this file is automatically generated by running the program",
140cdf0e10cSrcweir     " * obtained building:",
141cdf0e10cSrcweir     this_file_name_and_location,
142cdf0e10cSrcweir     " * contained in module icc",
143cdf0e10cSrcweir     " * modify that program if you need to change something.",
144cdf0e10cSrcweir     " ***********************************************************************/",
145cdf0e10cSrcweir     NULL // last string, a null
146cdf0e10cSrcweir };
147cdf0e10cSrcweir 
148cdf0e10cSrcweir const char * const TheTail[] =
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     "#endif /* INCLUDED_ICC_SRGB_IEC61966_2_1_H */",
151cdf0e10cSrcweir     NULL
152cdf0e10cSrcweir };
153cdf0e10cSrcweir 
computeIEC_RGBtoXYZ(icFloatNumber indata)154cdf0e10cSrcweir icFloatNumber computeIEC_RGBtoXYZ( icFloatNumber indata )
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     double retval = 0.0;
157cdf0e10cSrcweir     if(indata < 0.04045)
158cdf0e10cSrcweir         retval = indata/12.92;
159cdf0e10cSrcweir     else // apply the other conversion
160cdf0e10cSrcweir         retval = pow( (indata + 0.055)/1.055 , 2.4);
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     return retval;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
computeIEC_XYZtoRGB(icFloatNumber indata)165cdf0e10cSrcweir icFloatNumber computeIEC_XYZtoRGB( icFloatNumber indata )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     icFloatNumber retval = 0.0;
168cdf0e10cSrcweir     if(indata < 0.0031308)
169cdf0e10cSrcweir         retval = indata*12.92;
170cdf0e10cSrcweir     else // apply the other conversion
171cdf0e10cSrcweir         retval =  1.055*pow( indata , icFloatNumber(1.0/2.4)) - 0.055;
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     //  cout << retval << endl;
174cdf0e10cSrcweir     return retval;
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
dumpTag(FILE * outfile,CIccProfile * pIcc,icTagSignature sig)177cdf0e10cSrcweir void dumpTag(FILE *outfile, CIccProfile *pIcc, icTagSignature sig)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir     CIccTag *pTag = pIcc->FindTag(sig);
180cdf0e10cSrcweir     char buf[64];
181cdf0e10cSrcweir     CIccInfo Fmt;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     std::string contents;
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     if (pTag)
186cdf0e10cSrcweir     {
187cdf0e10cSrcweir         fprintf(outfile, "\nContents of %s tag (%s)\n", Fmt.GetTagSigName(sig), icGetSig(buf, sig));
188cdf0e10cSrcweir         fprintf(outfile,"Type:   ");
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         if (pTag->IsArrayType())  fprintf(outfile, "Array of ");
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         fprintf(outfile, "%s\n", Fmt.GetTagTypeSigName(pTag->GetType()));
193cdf0e10cSrcweir         pTag->Describe(contents);
194cdf0e10cSrcweir         fwrite(contents.c_str(), contents.length(), 1, outfile);
195cdf0e10cSrcweir     }
196cdf0e10cSrcweir     else
197cdf0e10cSrcweir         fprintf(outfile, "Tag (%s) not found in profile\n", icGetSig(buf, sig));
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
dumpProfile(FILE * outfile,const char * profileName)200cdf0e10cSrcweir void dumpProfile(FILE *outfile, const char * profileName)
201cdf0e10cSrcweir {
202cdf0e10cSrcweir     CIccProfile *pIcc;
203cdf0e10cSrcweir     icValidateStatus nStatus;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     pIcc = OpenIccProfile(profileName);
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     if (!pIcc)
208cdf0e10cSrcweir         printf("Unable to open '%s'\n", profileName);
209cdf0e10cSrcweir     else
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         icHeader *pHdr = &pIcc->m_Header;
212cdf0e10cSrcweir         CIccInfo Fmt;
213cdf0e10cSrcweir         char buf[64];
214cdf0e10cSrcweir 
215cdf0e10cSrcweir         fprintf(outfile,"Profile:          '%s'\n", profileName);
216cdf0e10cSrcweir         if(Fmt.IsProfileIDCalculated(&pHdr->profileID))
217cdf0e10cSrcweir             fprintf(outfile,"Profile ID:        %s\n", Fmt.GetProfileID(&pHdr->profileID));
218cdf0e10cSrcweir         else
219cdf0e10cSrcweir             fprintf(outfile,"Profile ID:       Profile ID not calculated.\n");
220cdf0e10cSrcweir         fprintf(outfile,"Size:             %ld(0x%lx) bytes\n", pHdr->size, pHdr->size);
221cdf0e10cSrcweir 
222cdf0e10cSrcweir         fprintf(outfile,"\nHeader\n");
223cdf0e10cSrcweir         fprintf(outfile,"------\n");
224cdf0e10cSrcweir         fprintf(outfile,"Attributes:       %s\n", Fmt.GetDeviceAttrName(pHdr->attributes));
225cdf0e10cSrcweir         fprintf(outfile,"Cmm:              %s\n", Fmt.GetCmmSigName((icCmmSignature)(pHdr->cmmId)));
226cdf0e10cSrcweir         fprintf(outfile,"Creation Date:    %d/%d/%d  %02u:%02u:%02u\n",
227cdf0e10cSrcweir                 pHdr->date.month, pHdr->date.day, pHdr->date.year,
228cdf0e10cSrcweir                 pHdr->date.hours, pHdr->date.minutes, pHdr->date.seconds);
229cdf0e10cSrcweir         fprintf(outfile,"Creator:          %s\n", icGetSig(buf, pHdr->creator));
230cdf0e10cSrcweir         fprintf(outfile,"Data Color Space: %s\n", Fmt.GetColorSpaceSigName(pHdr->colorSpace));
231cdf0e10cSrcweir         fprintf(outfile,"Flags             %s\n", Fmt.GetProfileFlagsName(pHdr->flags));
232cdf0e10cSrcweir         fprintf(outfile,"PCS Color Space:  %s\n", Fmt.GetColorSpaceSigName(pHdr->pcs));
233cdf0e10cSrcweir         fprintf(outfile,"Platform:         %s\n", Fmt.GetPlatformSigName(pHdr->platform));
234cdf0e10cSrcweir         fprintf(outfile,"Rendering Intent: %s\n", Fmt.GetRenderingIntentName((icRenderingIntent)(pHdr->renderingIntent)));
235cdf0e10cSrcweir         fprintf(outfile,"Type:             %s\n", Fmt.GetProfileClassSigName(pHdr->deviceClass));
236cdf0e10cSrcweir         fprintf(outfile,"Version:          %s\n", Fmt.GetVersionName(pHdr->version));
237cdf0e10cSrcweir         fprintf(outfile,"Illuminant:       X=%.4lf, Y=%.4lf, Z=%.4lf\n",
238cdf0e10cSrcweir                 icFtoD(pHdr->illuminant.X),
239cdf0e10cSrcweir                 icFtoD(pHdr->illuminant.Y),
240cdf0e10cSrcweir                 icFtoD(pHdr->illuminant.Z));
241cdf0e10cSrcweir 
242cdf0e10cSrcweir         fprintf(outfile,"\nProfile Tags\n");
243cdf0e10cSrcweir         fprintf(outfile,"------------\n");
244cdf0e10cSrcweir 
245cdf0e10cSrcweir         fprintf(outfile,"%25s    ID    %8s\t%8s\n", "Tag", "Offset", "Size");
246cdf0e10cSrcweir         fprintf(outfile,"%25s  ------  %8s\t%8s\n", "----", "------", "----");
247cdf0e10cSrcweir 
248cdf0e10cSrcweir         int n;
249cdf0e10cSrcweir         TagEntryList::iterator i;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         for (n=0, i=pIcc->m_Tags->begin(); i!=pIcc->m_Tags->end(); i++, n++)
252cdf0e10cSrcweir         {
253cdf0e10cSrcweir             fprintf(outfile,"%25s  %s  %8ld\t%8ld\n", Fmt.GetTagSigName(i->TagInfo.sig),
254cdf0e10cSrcweir                     icGetSig(buf, i->TagInfo.sig, false),
255cdf0e10cSrcweir                     i->TagInfo.offset, i->TagInfo.size);
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         for (n=0, i=pIcc->m_Tags->begin(); i!=pIcc->m_Tags->end(); i++, n++)
259cdf0e10cSrcweir             dumpTag(outfile, pIcc, i->TagInfo.sig);
260cdf0e10cSrcweir     }
261cdf0e10cSrcweir     delete pIcc;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
main(int argc,char * argv[])264cdf0e10cSrcweir int main(int argc, char* argv[])
265cdf0e10cSrcweir {
266cdf0e10cSrcweir     const char* myName = path_tail(argv[0]);
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     try
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         const char* const out_file_pathname = icc_file_name;
271cdf0e10cSrcweir 
272cdf0e10cSrcweir         CIccProfile profile;
273cdf0e10cSrcweir         profile.InitHeader();
274cdf0e10cSrcweir 
275cdf0e10cSrcweir         profile.m_Header.date.year = data_last_changed_year;
276cdf0e10cSrcweir         profile.m_Header.date.month = data_last_changed_month;
277cdf0e10cSrcweir         profile.m_Header.date.day = data_last_day;
278cdf0e10cSrcweir         profile.m_Header.date.hours = data_last_changed_hour;
279cdf0e10cSrcweir         profile.m_Header.date.minutes = data_last_changed_minute;
280cdf0e10cSrcweir         profile.m_Header.date.seconds = 0;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         profile.m_Header.deviceClass = icSigDisplayClass;
283cdf0e10cSrcweir         profile.m_Header.colorSpace = icSigRgbData;
284cdf0e10cSrcweir         profile.m_Header.pcs = icSigXYZData;
285cdf0e10cSrcweir         profile.m_Header.platform = icSigUnkownPlatform;
286cdf0e10cSrcweir         profile.m_Header.attributes = static_cast<icUInt64Number>(icReflective);
287cdf0e10cSrcweir         profile.m_Header.renderingIntent = icPerceptual;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         profile.m_Header.cmmId = 0x6E6F6E65; /* 'none' */
290cdf0e10cSrcweir         profile.m_Header.model = 0x73524742;//sRGB
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         profile.m_Header.version=icVersionNumberV2_1;
293cdf0e10cSrcweir 
294cdf0e10cSrcweir         // Required tags for a three-component matrix-based display profile, as laid
295cdf0e10cSrcweir         // out by specification ICC.1:1998-09 (clause 6.3)  are:
296cdf0e10cSrcweir         //
297cdf0e10cSrcweir         //   copyrightTag
298cdf0e10cSrcweir         //   profileDescriptionTag
299cdf0e10cSrcweir         //   redMatrixColumnTag
300cdf0e10cSrcweir         //   greenMatrixColumnTag
301cdf0e10cSrcweir         //   blueMatrixColumnTag
302cdf0e10cSrcweir         //   redTRCTag
303cdf0e10cSrcweir         //   greenTRCTag
304cdf0e10cSrcweir         //   blueTRCTag
305cdf0e10cSrcweir         //   mediaWhitePointTag
306cdf0e10cSrcweir 
307cdf0e10cSrcweir         // the other tags:
308cdf0e10cSrcweir         //
309cdf0e10cSrcweir         // technologyTag
310cdf0e10cSrcweir         // deviceModelTag
311cdf0e10cSrcweir         // deviceMfgDescTag
312cdf0e10cSrcweir         // mediaBlackPointTag
313cdf0e10cSrcweir         // viewingCondDescTag
314cdf0e10cSrcweir         // viewingConditionsTag
315cdf0e10cSrcweir         // luminanceTag
316cdf0e10cSrcweir         // measurementTag
317cdf0e10cSrcweir         //
318cdf0e10cSrcweir         // are optionals, added for completeness
319cdf0e10cSrcweir 
320cdf0e10cSrcweir         // the element below are sorted in the same order as
321cdf0e10cSrcweir         // the list above, but the LUT table,
322cdf0e10cSrcweir         // embedded at the end of the profile
323cdf0e10cSrcweir 
324cdf0e10cSrcweir         // copyrightTag
325cdf0e10cSrcweir         CIccTagText* copyrightTag = new CIccTagText;
326cdf0e10cSrcweir         copyrightTag->SetText(copyright);
327cdf0e10cSrcweir         profile.AttachTag(icSigCopyrightTag, copyrightTag);
328cdf0e10cSrcweir 
329cdf0e10cSrcweir         // profileDescriptionTag
330cdf0e10cSrcweir         CIccTagTextDescription* descriptionTag = new CIccTagTextDescription;
331cdf0e10cSrcweir         descriptionTag->SetText(description);
332cdf0e10cSrcweir         profile.AttachTag(icSigProfileDescriptionTag, descriptionTag);
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         CIccTagXYZ* redMatrixColumnTag = new CIccTagXYZ;
335cdf0e10cSrcweir         //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
336cdf0e10cSrcweir         //should be: 0.4361, 0.2225, 0.0139 according to application notes,
337cdf0e10cSrcweir         // the 'X' value below is the one commonly in use on a very
338cdf0e10cSrcweir         // diffused sRGB profile
339cdf0e10cSrcweir         (*redMatrixColumnTag)[0].X = icDtoF(0.4361);
340cdf0e10cSrcweir         (*redMatrixColumnTag)[0].Y = icDtoF(0.2225);
341cdf0e10cSrcweir         (*redMatrixColumnTag)[0].Z = icDtoF(0.0139);
342cdf0e10cSrcweir         profile.AttachTag(icSigRedMatrixColumnTag, redMatrixColumnTag);
343cdf0e10cSrcweir 
344cdf0e10cSrcweir         CIccTagXYZ* greenMatrixColumnTag = new CIccTagXYZ;
345cdf0e10cSrcweir         //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
346cdf0e10cSrcweir         (*greenMatrixColumnTag)[0].X = icDtoF(0.3851);
347cdf0e10cSrcweir         (*greenMatrixColumnTag)[0].Y = icDtoF(0.7169);
348cdf0e10cSrcweir         (*greenMatrixColumnTag)[0].Z = icDtoF(0.0971);
349cdf0e10cSrcweir         profile.AttachTag(icSigGreenMatrixColumnTag, greenMatrixColumnTag);
350cdf0e10cSrcweir 
351cdf0e10cSrcweir         CIccTagXYZ* blueMatrixColumnTag = new CIccTagXYZ;
352cdf0e10cSrcweir         //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
353cdf0e10cSrcweir         //should be: 0.1431, 0.0606, 0.7139 according to application notes,
354cdf0e10cSrcweir         // the 'Z' value below is the one commonly in use on a very
355cdf0e10cSrcweir         // diffused sRGB profile
356cdf0e10cSrcweir         (*blueMatrixColumnTag)[0].X = icDtoF(0.1431);
357cdf0e10cSrcweir         (*blueMatrixColumnTag)[0].Y = icDtoF(0.0606);
358cdf0e10cSrcweir         (*blueMatrixColumnTag)[0].Z = icDtoF(0.7141);
359cdf0e10cSrcweir         profile.AttachTag(icSigBlueMatrixColumnTag, blueMatrixColumnTag);
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         // mediaWhitePointTag
362cdf0e10cSrcweir         CIccTagXYZ* whitePointTag = new CIccTagXYZ;
363cdf0e10cSrcweir         (*whitePointTag)[0].X = icDtoF(0.9505);
364cdf0e10cSrcweir         (*whitePointTag)[0].Y = icDtoF(1.0);
365cdf0e10cSrcweir         (*whitePointTag)[0].Z = icDtoF(1.0891);
366cdf0e10cSrcweir         profile.AttachTag(icSigMediaWhitePointTag, whitePointTag);
367cdf0e10cSrcweir 
368cdf0e10cSrcweir         //device signature (technologytag)
369cdf0e10cSrcweir         CIccTagSignature* deviceSign = new CIccTagSignature;
370cdf0e10cSrcweir         deviceSign->SetValue( icSigCRTDisplay );
371cdf0e10cSrcweir         profile.AttachTag( icSigTechnologyTag, deviceSign );
372cdf0e10cSrcweir 
373cdf0e10cSrcweir         //device model tag
374cdf0e10cSrcweir         CIccTagTextDescription* deviceModelTag = new CIccTagTextDescription;
375cdf0e10cSrcweir         deviceModelTag->SetText("IEC 61966-2.1 Default RGB colour space - sRGB");
376cdf0e10cSrcweir         profile.AttachTag( icSigDeviceModelDescTag, deviceModelTag);
377cdf0e10cSrcweir 
378cdf0e10cSrcweir         // deviceMfgDescTag
379cdf0e10cSrcweir         CIccTagTextDescription* deviceMfgTag = new CIccTagTextDescription;
380cdf0e10cSrcweir         deviceMfgTag->SetText("IEC http://www.iec.ch");
381cdf0e10cSrcweir         profile.AttachTag( icSigDeviceMfgDescTag, deviceMfgTag);
382cdf0e10cSrcweir 
383cdf0e10cSrcweir         // mediaBlackPointTag
384cdf0e10cSrcweir         CIccTagXYZ* blackPointTag = new CIccTagXYZ;
385cdf0e10cSrcweir         (*blackPointTag)[0].X =
386cdf0e10cSrcweir         (*blackPointTag)[0].Y =
387cdf0e10cSrcweir         (*blackPointTag)[0].Z = icDtoF(0.0);
388cdf0e10cSrcweir         profile.AttachTag(icSigMediaBlackPointTag, blackPointTag);
389cdf0e10cSrcweir 
390cdf0e10cSrcweir         // viewingCondDescTag
391cdf0e10cSrcweir         CIccTagTextDescription* viewingCondDescTag = new CIccTagTextDescription;
392cdf0e10cSrcweir         viewingCondDescTag->SetText("Reference viewing condition according to IEC 61966-2.1");
393cdf0e10cSrcweir         profile.AttachTag( icSigViewingCondDescTag, viewingCondDescTag );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         // viewingConditionsTag
396cdf0e10cSrcweir         CIccTagViewingConditions* viewingConditionsTag = new  CIccTagViewingConditions;
397cdf0e10cSrcweir         // Illuminant tristimulus value
398cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZIllum.X = icDtoF(19.6445);
399cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZIllum.Y = icDtoF(20.3718);
400cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZIllum.Z = icDtoF(16.8089);
401cdf0e10cSrcweir         // surround tristimulus value
402cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZSurround.X = icDtoF(3.9289);
403cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZSurround.Y = icDtoF(4.0744);
404cdf0e10cSrcweir         (*viewingConditionsTag).m_XYZSurround.Z = icDtoF(3.3618);
405cdf0e10cSrcweir         (*viewingConditionsTag).m_illumType = icIlluminantD50;
406cdf0e10cSrcweir         profile.AttachTag( icSigViewingConditionsType, viewingConditionsTag );
407cdf0e10cSrcweir 
408cdf0e10cSrcweir         // luminanceTag
409cdf0e10cSrcweir         CIccTagXYZ* luminanceTag = new CIccTagXYZ;
410cdf0e10cSrcweir         (*luminanceTag)[0].X = icDtoF(76.0365);
411cdf0e10cSrcweir         (*luminanceTag)[0].Y = icDtoF(80.0);
412cdf0e10cSrcweir         (*luminanceTag)[0].Z = icDtoF(87.1246);
413cdf0e10cSrcweir         profile.AttachTag(icSigLuminanceTag, luminanceTag);
414cdf0e10cSrcweir 
415cdf0e10cSrcweir         // measurementTag
416cdf0e10cSrcweir         CIccTagMeasurement* measurementTag = new  CIccTagMeasurement;
417cdf0e10cSrcweir         (*measurementTag).m_Data.stdObserver = icStdObs1931TwoDegrees;
418cdf0e10cSrcweir         (*measurementTag).m_Data.backing.X =
419cdf0e10cSrcweir         (*measurementTag).m_Data.backing.Y =
420cdf0e10cSrcweir         (*measurementTag).m_Data.backing.Z = icDtoF(0.0);
421cdf0e10cSrcweir         (*measurementTag).m_Data.geometry = icGeometryUnknown;
422cdf0e10cSrcweir         // the flare is 1%, but the library doesn't seem all right with this
423cdf0e10cSrcweir         // see specification ICC.1:1998-09, clause 6.5.8, table 55 fot the right
424cdf0e10cSrcweir         // format of the data value
425cdf0e10cSrcweir         (*measurementTag).m_Data.flare = static_cast< icMeasurementFlare > ( icDtoUF( 0.01 ) );//means 1%
426cdf0e10cSrcweir         (*measurementTag).m_Data.illuminant = icIlluminantD65;
427cdf0e10cSrcweir         profile.AttachTag(icSigMeasurementTag, measurementTag );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir         // compute the LUT curves, they are equal for all three colors
430cdf0e10cSrcweir         // so only one LUT is computed and stored
431cdf0e10cSrcweir         int N = 1024; // number of points in LUTs
432cdf0e10cSrcweir         CIccTagCurve* colorTRCTag = new CIccTagCurve(N);
433cdf0e10cSrcweir         // apply conversion from RGB to XYZ, stepping the RGB value linearly from 0 to 100%
434cdf0e10cSrcweir         // 1024 steps are computed
435cdf0e10cSrcweir         for (int i = 0; i < N; ++i)
436cdf0e10cSrcweir             (*colorTRCTag)[i] = computeIEC_RGBtoXYZ( (icFloatNumber)i/(N-1));
437cdf0e10cSrcweir 
438cdf0e10cSrcweir         profile.AttachTag(icSigRedTRCTag, colorTRCTag);
439cdf0e10cSrcweir         profile.AttachTag(icSigGreenTRCTag, colorTRCTag);
440cdf0e10cSrcweir         profile.AttachTag(icSigBlueTRCTag, colorTRCTag);
441cdf0e10cSrcweir 
442cdf0e10cSrcweir         //Verify things
443cdf0e10cSrcweir         string validationReport;
444cdf0e10cSrcweir         icValidateStatus validationStatus = profile.Validate(validationReport);
445cdf0e10cSrcweir 
446cdf0e10cSrcweir         switch (validationStatus)
447cdf0e10cSrcweir         {
448cdf0e10cSrcweir         case icValidateOK:
449cdf0e10cSrcweir             break;
450cdf0e10cSrcweir 
451cdf0e10cSrcweir         case icValidateWarning:
452cdf0e10cSrcweir             clog << "Profile validation warning" << endl
453cdf0e10cSrcweir                  << validationReport;
454cdf0e10cSrcweir             break;
455cdf0e10cSrcweir 
456cdf0e10cSrcweir         case icValidateNonCompliant:
457cdf0e10cSrcweir             clog << "Profile non compliancy" << endl
458cdf0e10cSrcweir                  << validationReport;
459cdf0e10cSrcweir             break;
460cdf0e10cSrcweir 
461cdf0e10cSrcweir         case icValidateCriticalError:
462cdf0e10cSrcweir         default:
463cdf0e10cSrcweir             clog << "Profile Error" << endl
464cdf0e10cSrcweir                  << validationReport;
465cdf0e10cSrcweir         }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir         // Out it goes
468cdf0e10cSrcweir         CIccFileIO out;
469cdf0e10cSrcweir         out.Open(out_file_pathname, "wb+");
470cdf0e10cSrcweir         profile.Write(&out);
471cdf0e10cSrcweir         out.Close();
472cdf0e10cSrcweir 
473cdf0e10cSrcweir         FILE *headerfile = fopen(hxx_file_name,"w");
474cdf0e10cSrcweir 
475cdf0e10cSrcweir         //print OpenOffice standard file header
476cdf0e10cSrcweir         const char *the_string;
477cdf0e10cSrcweir 
478cdf0e10cSrcweir         int idx = 0;
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         while((the_string = TheHeader1[idx++]) != NULL )
481cdf0e10cSrcweir             fprintf(headerfile,"%s\n",the_string);
482cdf0e10cSrcweir // print the creation date (today)
483cdf0e10cSrcweir // print the date of sRGB ICC profile data
484cdf0e10cSrcweir         fprintf(headerfile," *  the date of last change to sRGB ICC profile data is:\n *  %4d/%02d/%02d - %02d:%02d\n",
485cdf0e10cSrcweir                 data_last_changed_year, data_last_changed_month,
486cdf0e10cSrcweir                 data_last_day, data_last_changed_hour,data_last_changed_minute );
487cdf0e10cSrcweir 
488cdf0e10cSrcweir         idx = 0;
489cdf0e10cSrcweir 
490cdf0e10cSrcweir         while((the_string = TheHeader2[idx++]) != NULL )
491cdf0e10cSrcweir             fprintf(headerfile,"%s\n",the_string);
492cdf0e10cSrcweir 
493cdf0e10cSrcweir         {
494cdf0e10cSrcweir // spit out the data structure (an array of unsigned char)
495cdf0e10cSrcweir             FILE *infile;
496cdf0e10cSrcweir 
497cdf0e10cSrcweir             int achar, number = 1;
498cdf0e10cSrcweir 
499cdf0e10cSrcweir             infile = fopen(out_file_pathname,"rb");
500cdf0e10cSrcweir 
501cdf0e10cSrcweir             fseek(infile,0,SEEK_END);
502cdf0e10cSrcweir             long int thesize= ftell(infile);
503cdf0e10cSrcweir             fseek(infile,0,SEEK_SET);
504cdf0e10cSrcweir 
505cdf0e10cSrcweir             fprintf(headerfile,"\nsal_uInt8 nsRGB_ICC_profile[%d]=\n{\n    ",thesize);
506cdf0e10cSrcweir 
507cdf0e10cSrcweir             do
508cdf0e10cSrcweir             {
509cdf0e10cSrcweir                 achar = fgetc(infile);
510cdf0e10cSrcweir                 if(achar == EOF)
511cdf0e10cSrcweir                     break;
512cdf0e10cSrcweir                 fprintf(headerfile,"0x%02x",achar);
513cdf0e10cSrcweir                 if(number % 12 == 0)
514cdf0e10cSrcweir                     fprintf(headerfile,",\n    ");
515cdf0e10cSrcweir                 else
516cdf0e10cSrcweir                     fprintf(headerfile,", ");
517cdf0e10cSrcweir                 number++;
518cdf0e10cSrcweir             } while(achar != EOF );
519cdf0e10cSrcweir             fprintf(headerfile,"\n};\n\n");
520cdf0e10cSrcweir 
521cdf0e10cSrcweir             fclose(infile);
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir         // append the file contents, in human readable form, as comment in the header
524cdf0e10cSrcweir         // get the functions from iccDump
525cdf0e10cSrcweir 
526cdf0e10cSrcweir         fprintf(headerfile,"/*****************\n\n");
527cdf0e10cSrcweir 
528cdf0e10cSrcweir         fprintf(headerfile,"This ICC profile contains the following data:\n\n");
529cdf0e10cSrcweir 
530cdf0e10cSrcweir         dumpProfile(headerfile, out_file_pathname );
531cdf0e10cSrcweir 
532cdf0e10cSrcweir         fprintf(headerfile,"\n*****************/\n");
533cdf0e10cSrcweir         //now append the tail
534cdf0e10cSrcweir         idx = 0;
535cdf0e10cSrcweir         while((the_string = TheTail[idx++]) != NULL )
536cdf0e10cSrcweir             fprintf(headerfile,"%s\n",the_string);
537cdf0e10cSrcweir 
538cdf0e10cSrcweir         fclose(headerfile);
539cdf0e10cSrcweir 
540cdf0e10cSrcweir         return EXIT_SUCCESS;
541cdf0e10cSrcweir     }
542cdf0e10cSrcweir     catch (const std::exception& e)
543cdf0e10cSrcweir     {
544cdf0e10cSrcweir         cout << myName << ": error: " << e.what() << endl;
545cdf0e10cSrcweir         return EXIT_FAILURE;
546cdf0e10cSrcweir     }
547cdf0e10cSrcweir }
548