summaryrefslogtreecommitdiff
path: root/icc/source/create_sRGB_profile/create_sRGB_profile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'icc/source/create_sRGB_profile/create_sRGB_profile.cpp')
-rw-r--r--icc/source/create_sRGB_profile/create_sRGB_profile.cpp551
1 files changed, 551 insertions, 0 deletions
diff --git a/icc/source/create_sRGB_profile/create_sRGB_profile.cpp b/icc/source/create_sRGB_profile/create_sRGB_profile.cpp
new file mode 100644
index 000000000000..f99c1b1edf43
--- /dev/null
+++ b/icc/source/create_sRGB_profile/create_sRGB_profile.cpp
@@ -0,0 +1,551 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+
+ Derived by beppec56@openoffice.org from various examples
+ in SampleICC library, the original copyright retained.
+
+ Copyright: see below
+*/
+
+/*
+ * The ICC Software License, Version 0.1
+ *
+ *
+ * Copyright (c) 2003-2006 The International Color Consortium. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * The International Color Consortium (www.color.org)"
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "ICC" and "The International Color Consortium" must
+ * not be used to imply that the ICC organization endorses or
+ * promotes products derived from this software without prior
+ * written permission. For written permission, please see
+ * <http://www.color.org/>.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
+ * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the The International Color Consortium.
+ *
+ *
+ * Membership in the ICC is encouraged when this software is used for
+ * commercial purposes.
+ *
+ *
+ * For more information on The International Color Consortium, please
+ * see <http://www.color.org/>.
+ *
+ *
+ */
+
+#include <math.h>
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+#include "IccUtil.h"
+#include "IccProfile.h"
+
+#include "Vetters.h"
+#include "CAT.h"
+#include "CLUT.h"
+
+const char * const icc_file_name = "sRGB-IEC61966-2.1.icc";
+const char * const hxx_file_name = "sRGB-IEC61966-2.1.hxx";
+const char * const this_file_name_and_location =" * icc/source/create_sRGB_profile/create_sRGB_profile.cpp";
+
+const char* const description = "sRGB IEC61966-2.1";
+//const char* const devicemanufact = "IEC http://www.iec.ch"; not used, device manufactured by OOo seems funny...
+const char* const devicemodel = "IEC 61966-2.1 Default RGB colour space - sRGB";
+const char* const copyright = "The Contents of this file are made available subject to the terms of GNU Lesser General Public License version 3";
+
+// the creation date is fixed, corresponds to the last time this file has been changed
+// NOTE: change this date values whenever the data inside the profile are changed.
+const int data_last_changed_year = 2007;
+const int data_last_changed_month = 12;
+const int data_last_day = 12;
+const int data_last_changed_hour = 18;
+const int data_last_changed_minute = 32;
+
+// the following string array it's the standard OOo header format
+const char * const TheHeader1[] =
+{
+ "/*************************************************************************",
+ " *",
+ " * OpenOffice.org - a multi-platform office productivity suite",
+ " *",
+ " * sRGB-IEC61966-2.1.hxx",
+ " *",
+ " * creator: create_sRGB_profile",
+ NULL
+};
+
+const char * const TheHeader2[] =
+{
+ " *",
+ " * This file is part of OpenOffice.org.",
+ " *",
+ " * OpenOffice.org is free software: you can redistribute it and/or modify",
+ " * it under the terms of the GNU Lesser General Public License version 3",
+ " * only, as published by the Free Software Foundation.",
+ " *",
+ " * OpenOffice.org is distributed in the hope that it will be useful,",
+ " * but WITHOUT ANY WARRANTY; without even the implied warranty of",
+ " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
+ " * GNU Lesser General Public License version 3 for more details",
+ " * (a copy is included in the LICENSE file that accompanied this code).",
+ " *",
+ " * You should have received a copy of the GNU Lesser General Public License",
+ " * version 3 along with OpenOffice.org. If not, see",
+ " * <http://www.openoffice.org/license.html>",
+ " * for a copy of the LGPLv3 License.",
+ " *",
+ " ************************************************************************/",
+ "",
+ "#ifndef INCLUDED_ICC_SRGB_IEC61966_2_1_H",
+ "#define INCLUDED_ICC_SRGB_IEC61966_2_1_H",
+ "",
+ "/***********************************************************************",
+ " * NOTE:",
+ " * this file is automatically generated by running the program",
+ " * obtained building:",
+ this_file_name_and_location,
+ " * contained in module icc",
+ " * modify that program if you need to change something.",
+ " ***********************************************************************/",
+ NULL // last string, a null
+};
+
+const char * const TheTail[] =
+{
+ "#endif /* INCLUDED_ICC_SRGB_IEC61966_2_1_H */",
+ NULL
+};
+
+icFloatNumber computeIEC_RGBtoXYZ( icFloatNumber indata )
+{
+ double retval = 0.0;
+ if(indata < 0.04045)
+ retval = indata/12.92;
+ else // apply the other conversion
+ retval = pow( (indata + 0.055)/1.055 , 2.4);
+
+ return retval;
+}
+
+icFloatNumber computeIEC_XYZtoRGB( icFloatNumber indata )
+{
+ icFloatNumber retval = 0.0;
+ if(indata < 0.0031308)
+ retval = indata*12.92;
+ else // apply the other conversion
+ retval = 1.055*pow( indata , icFloatNumber(1.0/2.4)) - 0.055;
+
+ // cout << retval << endl;
+ return retval;
+}
+
+void dumpTag(FILE *outfile, CIccProfile *pIcc, icTagSignature sig)
+{
+ CIccTag *pTag = pIcc->FindTag(sig);
+ char buf[64];
+ CIccInfo Fmt;
+
+ std::string contents;
+
+ if (pTag)
+ {
+ fprintf(outfile, "\nContents of %s tag (%s)\n", Fmt.GetTagSigName(sig), icGetSig(buf, sig));
+ fprintf(outfile,"Type: ");
+
+ if (pTag->IsArrayType()) fprintf(outfile, "Array of ");
+
+ fprintf(outfile, "%s\n", Fmt.GetTagTypeSigName(pTag->GetType()));
+ pTag->Describe(contents);
+ fwrite(contents.c_str(), contents.length(), 1, outfile);
+ }
+ else
+ fprintf(outfile, "Tag (%s) not found in profile\n", icGetSig(buf, sig));
+}
+
+void dumpProfile(FILE *outfile, const char * profileName)
+{
+ CIccProfile *pIcc;
+ std::string sReport;
+ icValidateStatus nStatus;
+
+ pIcc = OpenIccProfile(profileName);
+
+ if (!pIcc)
+ printf("Unable to open '%s'\n", profileName);
+ else
+ {
+ icHeader *pHdr = &pIcc->m_Header;
+ CIccInfo Fmt;
+ char buf[64];
+
+ fprintf(outfile,"Profile: '%s'\n", profileName);
+ if(Fmt.IsProfileIDCalculated(&pHdr->profileID))
+ fprintf(outfile,"Profile ID: %s\n", Fmt.GetProfileID(&pHdr->profileID));
+ else
+ fprintf(outfile,"Profile ID: Profile ID not calculated.\n");
+ fprintf(outfile,"Size: %ld(0x%lx) bytes\n", pHdr->size, pHdr->size);
+
+ fprintf(outfile,"\nHeader\n");
+ fprintf(outfile,"------\n");
+ fprintf(outfile,"Attributes: %s\n", Fmt.GetDeviceAttrName(pHdr->attributes));
+ fprintf(outfile,"Cmm: %s\n", Fmt.GetCmmSigName((icCmmSignature)(pHdr->cmmId)));
+ fprintf(outfile,"Creation Date: %d/%d/%d %02u:%02u:%02u\n",
+ pHdr->date.month, pHdr->date.day, pHdr->date.year,
+ pHdr->date.hours, pHdr->date.minutes, pHdr->date.seconds);
+ fprintf(outfile,"Creator: %s\n", icGetSig(buf, pHdr->creator));
+ fprintf(outfile,"Data Color Space: %s\n", Fmt.GetColorSpaceSigName(pHdr->colorSpace));
+ fprintf(outfile,"Flags %s\n", Fmt.GetProfileFlagsName(pHdr->flags));
+ fprintf(outfile,"PCS Color Space: %s\n", Fmt.GetColorSpaceSigName(pHdr->pcs));
+ fprintf(outfile,"Platform: %s\n", Fmt.GetPlatformSigName(pHdr->platform));
+ fprintf(outfile,"Rendering Intent: %s\n", Fmt.GetRenderingIntentName((icRenderingIntent)(pHdr->renderingIntent)));
+ fprintf(outfile,"Type: %s\n", Fmt.GetProfileClassSigName(pHdr->deviceClass));
+ fprintf(outfile,"Version: %s\n", Fmt.GetVersionName(pHdr->version));
+ fprintf(outfile,"Illuminant: X=%.4lf, Y=%.4lf, Z=%.4lf\n",
+ icFtoD(pHdr->illuminant.X),
+ icFtoD(pHdr->illuminant.Y),
+ icFtoD(pHdr->illuminant.Z));
+
+ fprintf(outfile,"\nProfile Tags\n");
+ fprintf(outfile,"------------\n");
+
+ fprintf(outfile,"%25s ID %8s\t%8s\n", "Tag", "Offset", "Size");
+ fprintf(outfile,"%25s ------ %8s\t%8s\n", "----", "------", "----");
+
+ int n;
+ TagEntryList::iterator i;
+
+ for (n=0, i=pIcc->m_Tags->begin(); i!=pIcc->m_Tags->end(); i++, n++)
+ {
+ fprintf(outfile,"%25s %s %8ld\t%8ld\n", Fmt.GetTagSigName(i->TagInfo.sig),
+ icGetSig(buf, i->TagInfo.sig, false),
+ i->TagInfo.offset, i->TagInfo.size);
+ }
+
+ for (n=0, i=pIcc->m_Tags->begin(); i!=pIcc->m_Tags->end(); i++, n++)
+ dumpTag(outfile, pIcc, i->TagInfo.sig);
+ }
+ delete pIcc;
+}
+
+int main(int argc, char* argv[])
+{
+ const char* myName = path_tail(argv[0]);
+
+ try
+ {
+ const char* const out_file_pathname = icc_file_name;
+
+ CIccProfile profile;
+ profile.InitHeader();
+
+ profile.m_Header.date.year = data_last_changed_year;
+ profile.m_Header.date.month = data_last_changed_month;
+ profile.m_Header.date.day = data_last_day;
+ profile.m_Header.date.hours = data_last_changed_hour;
+ profile.m_Header.date.minutes = data_last_changed_minute;
+ profile.m_Header.date.seconds = 0;
+
+ profile.m_Header.deviceClass = icSigDisplayClass;
+ profile.m_Header.colorSpace = icSigRgbData;
+ profile.m_Header.pcs = icSigXYZData;
+ profile.m_Header.platform = icSigUnkownPlatform;
+ profile.m_Header.attributes = static_cast<icUInt64Number>(icReflective);
+ profile.m_Header.renderingIntent = icPerceptual;
+
+ profile.m_Header.cmmId = 0x6E6F6E65; /* 'none' */
+ profile.m_Header.model = 0x73524742;//sRGB
+
+ profile.m_Header.version=icVersionNumberV2_1;
+
+ // Required tags for a three-component matrix-based display profile, as laid
+ // out by specification ICC.1:1998-09 (clause 6.3) are:
+ //
+ // copyrightTag
+ // profileDescriptionTag
+ // redMatrixColumnTag
+ // greenMatrixColumnTag
+ // blueMatrixColumnTag
+ // redTRCTag
+ // greenTRCTag
+ // blueTRCTag
+ // mediaWhitePointTag
+
+ // the other tags:
+ //
+ // technologyTag
+ // deviceModelTag
+ // deviceMfgDescTag
+ // mediaBlackPointTag
+ // viewingCondDescTag
+ // viewingConditionsTag
+ // luminanceTag
+ // measurementTag
+ //
+ // are optionals, added for completeness
+
+ // the element below are sorted in the same order as
+ // the list above, but the LUT table,
+ // embedded at the end of the profile
+
+ // copyrightTag
+ CIccTagText* copyrightTag = new CIccTagText;
+ copyrightTag->SetText(copyright);
+ profile.AttachTag(icSigCopyrightTag, copyrightTag);
+
+ // profileDescriptionTag
+ CIccTagTextDescription* descriptionTag = new CIccTagTextDescription;
+ descriptionTag->SetText(description);
+ profile.AttachTag(icSigProfileDescriptionTag, descriptionTag);
+
+ CIccTagXYZ* redMatrixColumnTag = new CIccTagXYZ;
+ //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
+ //should be: 0.4361, 0.2225, 0.0139 according to application notes,
+ // the 'X' value below is the one commonly in use on a very
+ // diffused sRGB profile
+ (*redMatrixColumnTag)[0].X = icDtoF(0.4361);
+ (*redMatrixColumnTag)[0].Y = icDtoF(0.2225);
+ (*redMatrixColumnTag)[0].Z = icDtoF(0.0139);
+ profile.AttachTag(icSigRedMatrixColumnTag, redMatrixColumnTag);
+
+ CIccTagXYZ* greenMatrixColumnTag = new CIccTagXYZ;
+ //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
+ (*greenMatrixColumnTag)[0].X = icDtoF(0.3851);
+ (*greenMatrixColumnTag)[0].Y = icDtoF(0.7169);
+ (*greenMatrixColumnTag)[0].Z = icDtoF(0.0971);
+ profile.AttachTag(icSigGreenMatrixColumnTag, greenMatrixColumnTag);
+
+ CIccTagXYZ* blueMatrixColumnTag = new CIccTagXYZ;
+ //values from raccomandation of ICC for sRGB, D50 referenced characterisation data
+ //should be: 0.1431, 0.0606, 0.7139 according to application notes,
+ // the 'Z' value below is the one commonly in use on a very
+ // diffused sRGB profile
+ (*blueMatrixColumnTag)[0].X = icDtoF(0.1431);
+ (*blueMatrixColumnTag)[0].Y = icDtoF(0.0606);
+ (*blueMatrixColumnTag)[0].Z = icDtoF(0.7141);
+ profile.AttachTag(icSigBlueMatrixColumnTag, blueMatrixColumnTag);
+
+ // mediaWhitePointTag
+ CIccTagXYZ* whitePointTag = new CIccTagXYZ;
+ (*whitePointTag)[0].X = icDtoF(0.9505);
+ (*whitePointTag)[0].Y = icDtoF(1.0);
+ (*whitePointTag)[0].Z = icDtoF(1.0891);
+ profile.AttachTag(icSigMediaWhitePointTag, whitePointTag);
+
+ //device signature (technologytag)
+ CIccTagSignature* deviceSign = new CIccTagSignature;
+ deviceSign->SetValue( icSigCRTDisplay );
+ profile.AttachTag( icSigTechnologyTag, deviceSign );
+
+ //device model tag
+ CIccTagTextDescription* deviceModelTag = new CIccTagTextDescription;
+ deviceModelTag->SetText("IEC 61966-2.1 Default RGB colour space - sRGB");
+ profile.AttachTag( icSigDeviceModelDescTag, deviceModelTag);
+
+ // deviceMfgDescTag
+ CIccTagTextDescription* deviceMfgTag = new CIccTagTextDescription;
+ deviceMfgTag->SetText("IEC http://www.iec.ch");
+ profile.AttachTag( icSigDeviceMfgDescTag, deviceMfgTag);
+
+ // mediaBlackPointTag
+ CIccTagXYZ* blackPointTag = new CIccTagXYZ;
+ (*blackPointTag)[0].X =
+ (*blackPointTag)[0].Y =
+ (*blackPointTag)[0].Z = icDtoF(0.0);
+ profile.AttachTag(icSigMediaBlackPointTag, blackPointTag);
+
+ // viewingCondDescTag
+ CIccTagTextDescription* viewingCondDescTag = new CIccTagTextDescription;
+ viewingCondDescTag->SetText("Reference viewing condition according to IEC 61966-2.1");
+ profile.AttachTag( icSigViewingCondDescTag, viewingCondDescTag );
+
+ // viewingConditionsTag
+ CIccTagViewingConditions* viewingConditionsTag = new CIccTagViewingConditions;
+ // Illuminant tristimulus value
+ (*viewingConditionsTag).m_XYZIllum.X = icDtoF(19.6445);
+ (*viewingConditionsTag).m_XYZIllum.Y = icDtoF(20.3718);
+ (*viewingConditionsTag).m_XYZIllum.Z = icDtoF(16.8089);
+ // surround tristimulus value
+ (*viewingConditionsTag).m_XYZSurround.X = icDtoF(3.9289);
+ (*viewingConditionsTag).m_XYZSurround.Y = icDtoF(4.0744);
+ (*viewingConditionsTag).m_XYZSurround.Z = icDtoF(3.3618);
+ (*viewingConditionsTag).m_illumType = icIlluminantD50;
+ profile.AttachTag( icSigViewingConditionsType, viewingConditionsTag );
+
+ // luminanceTag
+ CIccTagXYZ* luminanceTag = new CIccTagXYZ;
+ (*luminanceTag)[0].X = icDtoF(76.0365);
+ (*luminanceTag)[0].Y = icDtoF(80.0);
+ (*luminanceTag)[0].Z = icDtoF(87.1246);
+ profile.AttachTag(icSigLuminanceTag, luminanceTag);
+
+ // measurementTag
+ CIccTagMeasurement* measurementTag = new CIccTagMeasurement;
+ (*measurementTag).m_Data.stdObserver = icStdObs1931TwoDegrees;
+ (*measurementTag).m_Data.backing.X =
+ (*measurementTag).m_Data.backing.Y =
+ (*measurementTag).m_Data.backing.Z = icDtoF(0.0);
+ (*measurementTag).m_Data.geometry = icGeometryUnknown;
+ // the flare is 1%, but the library doesn't seem all right with this
+ // see specification ICC.1:1998-09, clause 6.5.8, table 55 fot the right
+ // format of the data value
+ (*measurementTag).m_Data.flare = static_cast< icMeasurementFlare > ( icDtoUF( 0.01 ) );//means 1%
+ (*measurementTag).m_Data.illuminant = icIlluminantD65;
+ profile.AttachTag(icSigMeasurementTag, measurementTag );
+
+ // compute the LUT curves, they are equal for all three colors
+ // so only one LUT is computed and stored
+ int N = 1024; // number of points in LUTs
+ CIccTagCurve* colorTRCTag = new CIccTagCurve(N);
+ // apply conversion from RGB to XYZ, stepping the RGB value linearly from 0 to 100%
+ // 1024 steps are computed
+ for (int i = 0; i < N; ++i)
+ (*colorTRCTag)[i] = computeIEC_RGBtoXYZ( (icFloatNumber)i/(N-1));
+
+ profile.AttachTag(icSigRedTRCTag, colorTRCTag);
+ profile.AttachTag(icSigGreenTRCTag, colorTRCTag);
+ profile.AttachTag(icSigBlueTRCTag, colorTRCTag);
+
+ //Verify things
+ string validationReport;
+ icValidateStatus validationStatus = profile.Validate(validationReport);
+
+ switch (validationStatus)
+ {
+ case icValidateOK:
+ break;
+
+ case icValidateWarning:
+ clog << "Profile validation warning" << endl
+ << validationReport;
+ break;
+
+ case icValidateNonCompliant:
+ clog << "Profile non compliancy" << endl
+ << validationReport;
+ break;
+
+ case icValidateCriticalError:
+ default:
+ clog << "Profile Error" << endl
+ << validationReport;
+ }
+
+ // Out it goes
+ CIccFileIO out;
+ out.Open(out_file_pathname, "wb+");
+ profile.Write(&out);
+ out.Close();
+
+ FILE *headerfile = fopen(hxx_file_name,"w");
+
+ //print OpenOffice standard file header
+ const char *the_string;
+
+ int idx = 0;
+
+ while((the_string = TheHeader1[idx++]) != NULL )
+ fprintf(headerfile,"%s\n",the_string);
+// print the creation date (today)
+// print the date of sRGB ICC profile data
+ fprintf(headerfile," * the date of last change to sRGB ICC profile data is:\n * %4d/%02d/%02d - %02d:%02d\n",
+ data_last_changed_year, data_last_changed_month,
+ data_last_day, data_last_changed_hour,data_last_changed_minute );
+
+ idx = 0;
+
+ while((the_string = TheHeader2[idx++]) != NULL )
+ fprintf(headerfile,"%s\n",the_string);
+
+ {
+// spit out the data structure (an array of unsigned char)
+ FILE *infile;
+
+ int achar, number = 1;
+
+ infile = fopen(out_file_pathname,"rb");
+
+ fseek(infile,0,SEEK_END);
+ long int thesize= ftell(infile);
+ fseek(infile,0,SEEK_SET);
+
+ fprintf(headerfile,"\nsal_uInt8 nsRGB_ICC_profile[%d]=\n{\n ",thesize);
+
+ do
+ {
+ achar = fgetc(infile);
+ if(achar == EOF)
+ break;
+ fprintf(headerfile,"0x%02x",achar);
+ if(number % 12 == 0)
+ fprintf(headerfile,",\n ");
+ else
+ fprintf(headerfile,", ");
+ number++;
+ } while(achar != EOF );
+ fprintf(headerfile,"\n};\n\n");
+
+ fclose(infile);
+ }
+ // append the file contents, in human readable form, as comment in the header
+ // get the functions from iccDump
+
+ fprintf(headerfile,"/*****************\n\n");
+
+ fprintf(headerfile,"This ICC profile contains the following data:\n\n");
+
+ dumpProfile(headerfile, out_file_pathname );
+
+ fprintf(headerfile,"\n*****************/\n");
+ //now append the tail
+ idx = 0;
+ while((the_string = TheTail[idx++]) != NULL )
+ fprintf(headerfile,"%s\n",the_string);
+
+ fclose(headerfile);
+
+ return EXIT_SUCCESS;
+ }
+ catch (const std::exception& e)
+ {
+ cout << myName << ": error: " << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+}