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