Imported Upstream version 2.4
[platform/upstream/lcms2.git] / utils / common / vprf.c
1 //---------------------------------------------------------------------------------\r
2 //\r
3 //  Little Color Management System\r
4 //  Copyright (c) 1998-2010 Marti Maria Saguer\r
5 //\r
6 // Permission is hereby granted, free of charge, to any person obtaining\r
7 // a copy of this software and associated documentation files (the "Software"),\r
8 // to deal in the Software without restriction, including without limitation\r
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
10 // and/or sell copies of the Software, and to permit persons to whom the Software\r
11 // is furnished to do so, subject to the following conditions:\r
12 //\r
13 // The above copyright notice and this permission notice shall be included in\r
14 // all copies or substantial portions of the Software.\r
15 //\r
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO\r
18 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
23 //\r
24 //---------------------------------------------------------------------------------\r
25 //\r
26 \r
27 #include "utils.h"\r
28 \r
29 \r
30 int Verbose = 0;\r
31 \r
32 static char ProgramName[256] = "";\r
33 \r
34 void FatalError(const char *frm, ...)\r
35 {\r
36     va_list args;\r
37 \r
38     va_start(args, frm);\r
39     fprintf(stderr, "[%s fatal error]: ", ProgramName);\r
40     vfprintf(stderr, frm, args);\r
41     fprintf(stderr, "\n");\r
42     va_end(args);\r
43 \r
44     exit(1);\r
45 }\r
46 \r
47 // Show errors to the end user (unless quiet option)\r
48 static\r
49 void MyErrorLogHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text)\r
50 {\r
51     if (Verbose >= 0)\r
52         fprintf(stderr, "[%s]: %s\n", ProgramName, Text);\r
53 \r
54     UTILS_UNUSED_PARAMETER(ErrorCode);\r
55     UTILS_UNUSED_PARAMETER(ContextID);\r
56 }\r
57 \r
58 \r
59 void InitUtils(const char* PName)\r
60 {\r
61       strncpy(ProgramName, PName, sizeof(ProgramName));\r
62       ProgramName[sizeof(ProgramName)-1] = 0;\r
63 \r
64       cmsSetLogErrorHandler(MyErrorLogHandler);\r
65 }\r
66 \r
67 \r
68 // Virtual profiles are handled here.\r
69 cmsHPROFILE OpenStockProfile(cmsContext ContextID, const char* File)\r
70 {\r
71        if (!File)\r
72             return cmsCreate_sRGBProfileTHR(ContextID);\r
73 \r
74        if (cmsstrcasecmp(File, "*Lab2") == 0)\r
75                 return cmsCreateLab2ProfileTHR(ContextID, NULL);\r
76 \r
77        if (cmsstrcasecmp(File, "*Lab4") == 0)\r
78                 return cmsCreateLab4ProfileTHR(ContextID, NULL);\r
79 \r
80        if (cmsstrcasecmp(File, "*Lab") == 0)\r
81                 return cmsCreateLab4ProfileTHR(ContextID, NULL);\r
82 \r
83        if (cmsstrcasecmp(File, "*LabD65") == 0) {\r
84 \r
85            cmsCIExyY D65xyY;\r
86 \r
87            cmsWhitePointFromTemp( &D65xyY, 6504);\r
88            return cmsCreateLab4ProfileTHR(ContextID, &D65xyY);\r
89        }\r
90 \r
91        if (cmsstrcasecmp(File, "*XYZ") == 0)\r
92                 return cmsCreateXYZProfileTHR(ContextID);\r
93 \r
94        if (cmsstrcasecmp(File, "*Gray22") == 0) {\r
95 \r
96            cmsToneCurve* Curve = cmsBuildGamma(ContextID, 2.2);\r
97            cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve);\r
98            cmsFreeToneCurve(Curve);\r
99            return hProfile;\r
100        }\r
101 \r
102         if (cmsstrcasecmp(File, "*Gray30") == 0) {\r
103 \r
104            cmsToneCurve* Curve = cmsBuildGamma(ContextID, 3.0);\r
105            cmsHPROFILE hProfile = cmsCreateGrayProfileTHR(ContextID, cmsD50_xyY(), Curve);\r
106            cmsFreeToneCurve(Curve);\r
107            return hProfile;\r
108        }\r
109 \r
110        if (cmsstrcasecmp(File, "*srgb") == 0)\r
111                 return cmsCreate_sRGBProfileTHR(ContextID);\r
112 \r
113        if (cmsstrcasecmp(File, "*null") == 0)\r
114                 return cmsCreateNULLProfileTHR(ContextID);\r
115 \r
116 \r
117        if (cmsstrcasecmp(File, "*Lin2222") == 0) {\r
118 \r
119             cmsToneCurve*  Gamma = cmsBuildGamma(0, 2.2);\r
120             cmsToneCurve*  Gamma4[4];\r
121             cmsHPROFILE hProfile;\r
122 \r
123             Gamma4[0] = Gamma4[1] = Gamma4[2] = Gamma4[3] = Gamma;\r
124             hProfile = cmsCreateLinearizationDeviceLink(cmsSigCmykData, Gamma4);\r
125             cmsFreeToneCurve(Gamma);\r
126             return hProfile;\r
127        }\r
128 \r
129 \r
130         return cmsOpenProfileFromFileTHR(ContextID, File, "r");\r
131 }\r
132 \r
133 // Help on available built-ins\r
134 void PrintBuiltins(void)\r
135 {\r
136      fprintf(stderr, "\nBuilt-in profiles:\n\n");\r
137      fprintf(stderr, "\t*Lab2  -- D50-based v2 CIEL*a*b\n"\r
138                      "\t*Lab4  -- D50-based v4 CIEL*a*b\n"\r
139                      "\t*Lab   -- D50-based v4 CIEL*a*b\n"\r
140                      "\t*XYZ   -- CIE XYZ (PCS)\n"\r
141                      "\t*sRGB  -- sRGB color space\n"\r
142                      "\t*Gray22 - Monochrome of Gamma 2.2\n"\r
143                      "\t*Gray30 - Monochrome of Gamma 3.0\n"\r
144                      "\t*null   - Monochrome black for all input\n"\r
145                      "\t*Lin2222- CMYK linearization of gamma 2.2 on each channel\n");\r
146 }\r
147 \r
148 \r
149 // Auxiliar for printing information on profile\r
150 static\r
151 void PrintInfo(cmsHPROFILE h, cmsInfoType Info)\r
152 {\r
153     char* text;\r
154     int len;\r
155 \r
156     len = cmsGetProfileInfoASCII(h, Info, "en", "US", NULL, 0);\r
157     if (len == 0) return;\r
158 \r
159     text = malloc(len * sizeof(char));\r
160     if (text == NULL) return;\r
161 \r
162     cmsGetProfileInfoASCII(h, Info, "en", "US", text, len);\r
163 \r
164     if (strlen(text) > 0)\r
165         printf("%s\n", text);\r
166 \r
167     free(text);\r
168 }\r
169 \r
170 \r
171 \r
172 // Displays the colorant table\r
173 static\r
174 void PrintColorantTable(cmsHPROFILE hInput, cmsTagSignature Sig, const char* Title)\r
175 {\r
176     cmsNAMEDCOLORLIST* list;\r
177     int i, n;\r
178 \r
179     if (cmsIsTag(hInput, Sig)) {\r
180 \r
181         printf("%s:\n", Title);\r
182 \r
183         list = cmsReadTag(hInput, Sig);\r
184         if (list == NULL) {\r
185             printf("(Unavailable)\n");\r
186             return;\r
187         }\r
188 \r
189         n = cmsNamedColorCount(list);\r
190         for (i=0; i < n; i++) {\r
191 \r
192             char Name[cmsMAX_PATH];\r
193 \r
194             cmsNamedColorInfo(list, i, Name, NULL, NULL, NULL, NULL);\r
195             printf("\t%s\n", Name);\r
196         }\r
197 \r
198         printf("\n");\r
199     }\r
200 \r
201 }\r
202 \r
203 \r
204 void PrintProfileInformation(cmsHPROFILE hInput)\r
205 {\r
206     PrintInfo(hInput, cmsInfoDescription);\r
207     PrintInfo(hInput, cmsInfoManufacturer);\r
208     PrintInfo(hInput, cmsInfoModel);\r
209     PrintInfo(hInput, cmsInfoCopyright);\r
210 \r
211     if (Verbose > 2) {\r
212 \r
213         PrintColorantTable(hInput, cmsSigColorantTableTag,    "Input colorant table");\r
214         PrintColorantTable(hInput, cmsSigColorantTableOutTag, "Input colorant out table");\r
215     }\r
216 \r
217     printf("\n");\r
218 }\r
219 \r
220 // -----------------------------------------------------------------------------\r
221 \r
222 \r
223 void PrintRenderingIntents(void)\r
224 {\r
225     cmsUInt32Number Codes[200];\r
226     char* Descriptions[200];\r
227     cmsUInt32Number n, i;\r
228 \r
229     fprintf(stderr, "%ct<n> rendering intent:\n\n", SW);\r
230 \r
231     n = cmsGetSupportedIntents(200, Codes, Descriptions);\r
232 \r
233     for (i=0; i < n; i++) {\r
234         fprintf(stderr, "\t%d - %s\n", Codes[i], Descriptions[i]);\r
235     }\r
236     fprintf(stderr, "\n");\r
237 }\r
238 \r
239 \r
240 \r
241 // ------------------------------------------------------------------------------\r
242 \r
243 cmsBool SaveMemoryBlock(const cmsUInt8Number* Buffer, cmsUInt32Number dwLen, const char* Filename)\r
244 {\r
245     FILE* out = fopen(Filename, "wb");\r
246     if (out == NULL) {\r
247         FatalError("Cannot create '%s'", Filename);\r
248         return FALSE;\r
249     }\r
250 \r
251     if (fwrite(Buffer, 1, dwLen, out) != dwLen) {\r
252         FatalError("Cannot write %ld bytes to %s", dwLen, Filename);\r
253         return FALSE;\r
254     }\r
255 \r
256     if (fclose(out) != 0) {\r
257         FatalError("Error flushing file '%s'", Filename);\r
258         return FALSE;\r
259     }\r
260 \r
261     return TRUE;\r
262 }\r
263 \r
264 // ------------------------------------------------------------------------------\r
265 \r
266 // Return a pixel type on depending on the number of channels\r
267 int PixelTypeFromChanCount(int ColorChannels)\r
268 {\r
269     switch (ColorChannels) {\r
270 \r
271         case 1: return PT_GRAY;\r
272         case 2: return PT_MCH2;\r
273         case 3: return PT_MCH3;\r
274         case 4: return PT_CMYK;\r
275         case 5: return PT_MCH5;\r
276         case 6: return PT_MCH6;\r
277         case 7: return PT_MCH7;\r
278         case 8: return PT_MCH8;\r
279         case 9: return PT_MCH9;\r
280         case 10: return PT_MCH10;\r
281         case 11: return PT_MCH11;\r
282         case 12: return PT_MCH12;\r
283         case 13: return PT_MCH13;\r
284         case 14: return PT_MCH14;\r
285         case 15: return PT_MCH15;\r
286 \r
287         default:\r
288 \r
289             FatalError("What a weird separation of %d channels?!?!", ColorChannels);\r
290             return -1;\r
291     }\r
292 }\r
293 \r
294 \r
295 // ------------------------------------------------------------------------------\r
296 \r
297 // Return number of channels of pixel type\r
298 int ChanCountFromPixelType(int ColorChannels)\r
299 {\r
300     switch (ColorChannels) {\r
301 \r
302       case PT_GRAY: return 1;\r
303 \r
304       case PT_RGB:\r
305       case PT_CMY:\r
306       case PT_Lab:\r
307       case PT_YUV:\r
308       case PT_YCbCr: return 3;\r
309 \r
310       case PT_CMYK: return 4 ;\r
311       case PT_MCH2: return 2 ;\r
312       case PT_MCH3: return 3 ;\r
313       case PT_MCH4: return 4 ;\r
314       case PT_MCH5: return 5 ;\r
315       case PT_MCH6: return 6 ;\r
316       case PT_MCH7: return 7 ;\r
317       case PT_MCH8: return 8 ;\r
318       case PT_MCH9: return 9 ;\r
319       case PT_MCH10: return 10;\r
320       case PT_MCH11: return 11;\r
321       case PT_MCH12: return 12;\r
322       case PT_MCH13: return 12;\r
323       case PT_MCH14: return 14;\r
324       case PT_MCH15: return 15;\r
325 \r
326       default:\r
327 \r
328           FatalError("Unsupported color space of %d channels", ColorChannels);\r
329           return -1;\r
330     }\r
331 }\r
332 \r
333 \r