Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / workbench / libs / lcms2 / utils / linkicc / linkicc.c
blobb9b7bfb9009a2c2f01322db127be03ad7d88dad1
1 //---------------------------------------------------------------------------------
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2011 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:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
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.
24 //---------------------------------------------------------------------------------
26 #include "utils.h"
28 // ---------------------------------------------------------------------------------
30 static char* Description = "Devicelink profile";
31 static char* Copyright = "No copyright, use freely";
32 static int Intent = INTENT_PERCEPTUAL;
33 static char* cOutProf = "devicelink.icc";
34 static int PrecalcMode = 1;
35 static int NumOfGridPoints = 0;
37 static cmsFloat64Number ObserverAdaptationState = 1.0; // According ICC 4.2 this is the default
39 static cmsBool BlackPointCompensation = FALSE;
41 static cmsFloat64Number InkLimit = 400;
42 static cmsBool lUse8bits = FALSE;
43 static cmsBool TagResult = FALSE;
44 static cmsBool KeepLinearization = FALSE;
45 static cmsFloat64Number Version = 4.3;
48 // The manual
49 static
50 int Help(int level)
52 switch (level) {
54 default:
55 case 0:
57 fprintf(stderr, "\nlinkicc: Links profiles into a single devicelink.\n");
59 fprintf(stderr, "\n");
60 fprintf(stderr, "usage: linkicc [flags] <profiles>\n\n");
61 fprintf(stderr, "flags:\n\n");
62 fprintf(stderr, "%co<profile> - Output devicelink profile. [defaults to 'devicelink.icc']\n", SW);
64 PrintRenderingIntents();
66 fprintf(stderr, "%cc<0,1,2> - Precision (0=LowRes, 1=Normal, 2=Hi-res) [defaults to 1]\n", SW);
67 fprintf(stderr, "%cn<gridpoints> - Alternate way to set precision, number of CLUT points\n", SW);
68 fprintf(stderr, "%cd<description> - description text (quotes can be used)\n", SW);
69 fprintf(stderr, "%cy<copyright> - copyright notice (quotes can be used)\n", SW);
71 fprintf(stderr, "\n%ck<0..400> - Ink-limiting in %% (CMYK only)\n", SW);
72 fprintf(stderr, "%c8 - Creates 8-bit devicelink\n", SW);
73 fprintf(stderr, "%cx - Creatively, guess deviceclass of resulting profile.\n", SW);
74 fprintf(stderr, "%cb - Black point compensation\n", SW);
75 fprintf(stderr, "%ca<0..1> - Observer adaptation state (abs.col. only)\n\n", SW);
76 fprintf(stderr, "%cl - Use linearization curves (may affect accuracy)\n", SW);
77 fprintf(stderr, "%cr<v.r> - Profile version. (CAUTION: may change the profile implementation)\n", SW);
78 fprintf(stderr, "\n");
79 fprintf(stderr, "Colorspaces must be paired except Lab/XYZ, that can be interchanged.\n\n");
81 fprintf(stderr, "%ch<0,1,2,3> - More help\n", SW);
82 break;
84 case 1:
85 PrintBuiltins();
86 break;
88 case 2:
90 fprintf(stderr, "\nExamples:\n\n"
91 "To create 'devicelink.icm' from a.icc to b.icc:\n"
92 "\tlinkicc a.icc b.icc\n\n"
93 "To create 'out.icc' from sRGB to cmyk.icc:\n"
94 "\tlinkicc -o out.icc *sRGB cmyk.icc\n\n"
95 "To create a sRGB input profile working in Lab:\n"
96 "\tlinkicc -x -o sRGBLab.icc *sRGB *Lab\n\n"
97 "To create a XYZ -> sRGB output profile:\n"
98 "\tlinkicc -x -o sRGBLab.icc *XYZ *sRGB\n\n"
99 "To create a abstract profile doing softproof for cmyk.icc:\n"
100 "\tlinkicc -t1 -x -o softproof.icc *Lab cmyk.icc cmyk.icc *Lab\n\n"
101 "To create a 'grayer' sRGB input profile:\n"
102 "\tlinkicc -x -o grayer.icc *sRGB gray.icc gray.icc *Lab\n\n"
103 "To embed ink limiting into a cmyk output profile:\n"
104 "\tlinkicc -x -o cmyklimited.icc -k 250 cmyk.icc *Lab\n\n");
105 break;
107 case 3:
109 fprintf(stderr, "This program is intended to be a demo of the little cms\n"
110 "engine. Both lcms and this program are freeware. You can\n"
111 "obtain both in source code at http://www.littlecms.com\n"
112 "For suggestions, comments, bug reports etc. send mail to\n"
113 "info@littlecms.com\n\n");
116 exit(0);
119 // The toggles stuff
120 static
121 void HandleSwitches(int argc, char *argv[])
123 int s;
125 while ((s = xgetopt(argc,argv,"a:A:BbC:c:D:d:h:H:k:K:lLn:N:O:o:r:R:T:t:V:v:xX8y:Y:")) != EOF) {
127 switch (s) {
130 case 'a':
131 case 'A':
132 ObserverAdaptationState = atof(xoptarg);
133 if (ObserverAdaptationState < 0 ||
134 ObserverAdaptationState > 1.0)
135 FatalError("Adaptation state should be 0..1");
136 break;
138 case 'b':
139 case 'B':
140 BlackPointCompensation = TRUE;
141 break;
143 case 'c':
144 case 'C':
145 PrecalcMode = atoi(xoptarg);
146 if (PrecalcMode < 0 || PrecalcMode > 2) {
147 FatalError("Unknown precalc mode '%d'", PrecalcMode);
149 break;
151 case 'd':
152 case 'D':
153 // Doing that is correct and safe: Description points to memory allocated in the command line.
154 // same for Copyright and output devicelink.
155 Description = xoptarg;
156 break;
158 case 'h':
159 case 'H':
160 Help(atoi(xoptarg));
161 return;
163 case 'k':
164 case 'K':
165 InkLimit = atof(xoptarg);
166 if (InkLimit < 0.0 || InkLimit > 400.0) {
167 FatalError("Ink limit must be 0%%..400%%");
169 break;
172 case 'l':
173 case 'L': KeepLinearization = TRUE;
174 break;
176 case 'n':
177 case 'N':
178 if (PrecalcMode != 1) {
179 FatalError("Precalc mode already specified");
181 NumOfGridPoints = atoi(xoptarg);
182 break;
184 case 'o':
185 case 'O':
186 cOutProf = xoptarg;
187 break;
190 case 'r':
191 case 'R':
192 Version = atof(xoptarg);
193 if (Version < 2.0 || Version > 4.3) {
194 fprintf(stderr, "WARNING: lcms was not aware of this version, tag types may be wrong!\n");
196 break;
198 case 't':
199 case 'T':
200 Intent = atoi(xoptarg); // Will be validated latter on
201 break;
203 case 'V':
204 case 'v':
205 Verbose = atoi(xoptarg);
206 if (Verbose < 0 || Verbose > 3) {
207 FatalError("Unknown verbosity level '%d'", Verbose);
209 break;
211 case '8':
212 lUse8bits = TRUE;
213 break;
217 case 'y':
218 case 'Y':
219 Copyright = xoptarg;
220 break;
224 case 'x':
225 case 'X': TagResult = TRUE;
226 break;
230 default:
232 FatalError("Unknown option - run without args to see valid ones.\n");
237 // Set the copyright and description
238 static
239 cmsBool SetTextTags(cmsHPROFILE hProfile)
241 cmsMLU *DescriptionMLU, *CopyrightMLU;
242 cmsBool rc = FALSE;
243 cmsContext ContextID = cmsGetProfileContextID(hProfile);
245 DescriptionMLU = cmsMLUalloc(ContextID, 1);
246 CopyrightMLU = cmsMLUalloc(ContextID, 1);
248 if (DescriptionMLU == NULL || CopyrightMLU == NULL) goto Error;
250 if (!cmsMLUsetASCII(DescriptionMLU, "en", "US", Description)) goto Error;
251 if (!cmsMLUsetASCII(CopyrightMLU, "en", "US", Copyright)) goto Error;
253 if (!cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU)) goto Error;
254 if (!cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU)) goto Error;
256 rc = TRUE;
258 Error:
260 if (DescriptionMLU)
261 cmsMLUfree(DescriptionMLU);
262 if (CopyrightMLU)
263 cmsMLUfree(CopyrightMLU);
264 return rc;
269 int main(int argc, char *argv[])
271 int i, nargs, rc;
272 cmsHPROFILE Profiles[257];
273 cmsHPROFILE hProfile;
274 cmsUInt32Number dwFlags;
275 cmsHTRANSFORM hTransform = NULL;
277 // Here we are
278 fprintf(stderr, "little cms ICC device link generator - v2.2 [LittleCMS %2.2f]\n", LCMS_VERSION / 1000.0);
279 fflush(stderr);
281 // Initialize
282 InitUtils("linkicc");
283 rc = 0;
285 // Get the options
286 HandleSwitches(argc, argv);
288 // How many profiles to link?
289 nargs = (argc - xoptind);
290 if (nargs < 1)
291 return Help(0);
293 if (nargs > 255) {
294 FatalError("Holy profile! what are you trying to do with so many profiles!?");
295 goto Cleanup;
298 // Open all profiles
299 memset(Profiles, 0, sizeof(Profiles));
300 for (i=0; i < nargs; i++) {
302 Profiles[i] = OpenStockProfile(0, argv[i + xoptind]);
303 if (Profiles[i] == NULL) goto Cleanup;
305 if (Verbose >= 1) {
306 PrintProfileInformation(Profiles[i]);
310 // Ink limiting
311 if (InkLimit != 400.0) {
312 cmsColorSpaceSignature EndingColorSpace = cmsGetColorSpace(Profiles[nargs-1]);
313 Profiles[nargs++] = cmsCreateInkLimitingDeviceLink(EndingColorSpace, InkLimit);
316 // Set the flags
317 dwFlags = cmsFLAGS_KEEP_SEQUENCE;
318 switch (PrecalcMode) {
320 case 0: dwFlags |= cmsFLAGS_LOWRESPRECALC; break;
321 case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break;
322 case 1:
323 if (NumOfGridPoints > 0)
324 dwFlags |= cmsFLAGS_GRIDPOINTS(NumOfGridPoints);
325 break;
327 default:
329 FatalError("Unknown precalculation mode '%d'", PrecalcMode);
330 goto Cleanup;
334 if (BlackPointCompensation)
335 dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
337 if (TagResult)
338 dwFlags |= cmsFLAGS_GUESSDEVICECLASS;
340 if (KeepLinearization)
341 dwFlags |= cmsFLAGS_CLUT_PRE_LINEARIZATION|cmsFLAGS_CLUT_POST_LINEARIZATION;
343 if (lUse8bits) dwFlags |= cmsFLAGS_8BITS_DEVICELINK;
345 cmsSetAdaptationState(ObserverAdaptationState);
347 // Create the color transform. Specify 0 for the format is safe as the transform
348 // is intended to be used only for the devicelink.
349 hTransform = cmsCreateMultiprofileTransform(Profiles, nargs, 0, 0, Intent, dwFlags|cmsFLAGS_NOOPTIMIZE);
350 if (hTransform == NULL) {
351 FatalError("Transform creation failed");
352 goto Cleanup;
355 hProfile = cmsTransform2DeviceLink(hTransform, Version, dwFlags);
356 if (hProfile == NULL) {
357 FatalError("Devicelink creation failed");
358 goto Cleanup;
361 SetTextTags(hProfile);
362 cmsSetHeaderRenderingIntent(hProfile, Intent);
364 if (cmsSaveProfileToFile(hProfile, cOutProf)) {
366 if (Verbose > 0)
367 fprintf(stderr, "Ok");
369 else
370 FatalError("Error saving file!");
372 cmsCloseProfile(hProfile);
375 Cleanup:
377 if (hTransform != NULL) cmsDeleteTransform(hTransform);
378 for (i=0; i < nargs; i++) {
380 if (Profiles[i] != NULL) cmsCloseProfile(Profiles[i]);
383 return rc;