13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 // This file is available under and governed by the GNU General Public
26 // License version 2 only, as published by the Free Software Foundation.
27 // However, the following notice accompanied the original version of this
28 // file:
29 //
30 //---------------------------------------------------------------------------------
31 //
32 // Little Color Management System
33 // Copyright (c) 1998-2012 Marti Maria Saguer
34 //
35 // Permission is hereby granted, free of charge, to any person obtaining
36 // a copy of this software and associated documentation files (the "Software"),
37 // to deal in the Software without restriction, including without limitation
38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
39 // and/or sell copies of the Software, and to permit persons to whom the Software
40 // is furnished to do so, subject to the following conditions:
41 //
42 // The above copyright notice and this permission notice shall be included in
43 // all copies or substantial portions of the Software.
44 //
45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 //
53 //---------------------------------------------------------------------------------
54 //
55
56 #include "lcms2_internal.h"
57
58
59 // Auxiliar: append a Lab identity after the given sequence of profiles
60 // and return the transform. Lab profile is closed, rest of profiles are kept open.
61 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
62 cmsUInt32Number nProfiles,
63 cmsUInt32Number InputFormat,
64 cmsUInt32Number OutputFormat,
65 const cmsUInt32Number Intents[],
66 const cmsHPROFILE hProfiles[],
67 const cmsBool BPC[],
68 const cmsFloat64Number AdaptationStates[],
69 cmsUInt32Number dwFlags)
70 {
71 cmsHTRANSFORM xform;
72 cmsHPROFILE hLab;
73 cmsHPROFILE ProfileList[256];
74 cmsBool BPCList[256];
75 cmsFloat64Number AdaptationList[256];
76 cmsUInt32Number IntentList[256];
77 cmsUInt32Number i;
78
79 // This is a rather big number and there is no need of dynamic memory
184 // Make sure last is an output profile
185 if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL;
186
187 // Create individual curves. BPC works also as each K to L* is
188 // computed as a BPC to zero black point in case of L*
189 in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
190 if (in == NULL) return NULL;
191
192 out = ComputeKToLstar(ContextID, nPoints, 1,
193 Intents + (nProfiles - 1),
194 &hProfiles [nProfiles - 1],
195 BPC + (nProfiles - 1),
196 AdaptationStates + (nProfiles - 1),
197 dwFlags);
198 if (out == NULL) {
199 cmsFreeToneCurve(in);
200 return NULL;
201 }
202
203 // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
204 // since this is used on black-preserving LUTs, we are not loosing accuracy in any case
205 KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
206
207 // Get rid of components
208 cmsFreeToneCurve(in); cmsFreeToneCurve(out);
209
210 // Something went wrong...
211 if (KTone == NULL) return NULL;
212
213 // Make sure it is monotonic
214 if (!cmsIsToneCurveMonotonic(KTone)) {
215 cmsFreeToneCurve(KTone);
216 return NULL;
217 }
218
219 return KTone;
220 }
221
222
223 // Gamut LUT Creation -----------------------------------------------------------------------------------------
224
290
291 // dE1 is big and dE2 is also big, could be due to perceptual mapping
292 // so take error ratio
293 if (dE2 == 0.0)
294 ErrorRatio = dE1;
295 else
296 ErrorRatio = dE1 / dE2;
297
298 if (ErrorRatio > t->Thereshold)
299 Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
300 else
301 Out[0] = 0;
302 }
303 }
304
305
306 return TRUE;
307 }
308
309 // Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
310 // the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE
311 // and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
312 //
313 // **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
314 // of course, many perceptual and saturation intents does not work in such way, but relativ. ones should.
315
316 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
317 cmsHPROFILE hProfiles[],
318 cmsBool BPC[],
319 cmsUInt32Number Intents[],
320 cmsFloat64Number AdaptationStates[],
321 cmsUInt32Number nGamutPCSposition,
322 cmsHPROFILE hGamut)
323 {
324 cmsHPROFILE hLab;
325 cmsPipeline* Gamut;
326 cmsStage* CLUT;
327 cmsUInt32Number dwFormat;
328 GAMUTCHAIN Chain;
329 int nChannels, nGridpoints;
330 cmsColorSpaceSignature ColorSpace;
|
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 // This file is available under and governed by the GNU General Public
26 // License version 2 only, as published by the Free Software Foundation.
27 // However, the following notice accompanied the original version of this
28 // file:
29 //
30 //---------------------------------------------------------------------------------
31 //
32 // Little Color Management System
33 // Copyright (c) 1998-2016 Marti Maria Saguer
34 //
35 // Permission is hereby granted, free of charge, to any person obtaining
36 // a copy of this software and associated documentation files (the "Software"),
37 // to deal in the Software without restriction, including without limitation
38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
39 // and/or sell copies of the Software, and to permit persons to whom the Software
40 // is furnished to do so, subject to the following conditions:
41 //
42 // The above copyright notice and this permission notice shall be included in
43 // all copies or substantial portions of the Software.
44 //
45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 //
53 //---------------------------------------------------------------------------------
54 //
55
56 #include "lcms2_internal.h"
57
58
59 // Auxiliary: append a Lab identity after the given sequence of profiles
60 // and return the transform. Lab profile is closed, rest of profiles are kept open.
61 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
62 cmsUInt32Number nProfiles,
63 cmsUInt32Number InputFormat,
64 cmsUInt32Number OutputFormat,
65 const cmsUInt32Number Intents[],
66 const cmsHPROFILE hProfiles[],
67 const cmsBool BPC[],
68 const cmsFloat64Number AdaptationStates[],
69 cmsUInt32Number dwFlags)
70 {
71 cmsHTRANSFORM xform;
72 cmsHPROFILE hLab;
73 cmsHPROFILE ProfileList[256];
74 cmsBool BPCList[256];
75 cmsFloat64Number AdaptationList[256];
76 cmsUInt32Number IntentList[256];
77 cmsUInt32Number i;
78
79 // This is a rather big number and there is no need of dynamic memory
184 // Make sure last is an output profile
185 if (cmsGetDeviceClass(hProfiles[nProfiles - 1]) != cmsSigOutputClass) return NULL;
186
187 // Create individual curves. BPC works also as each K to L* is
188 // computed as a BPC to zero black point in case of L*
189 in = ComputeKToLstar(ContextID, nPoints, nProfiles - 1, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
190 if (in == NULL) return NULL;
191
192 out = ComputeKToLstar(ContextID, nPoints, 1,
193 Intents + (nProfiles - 1),
194 &hProfiles [nProfiles - 1],
195 BPC + (nProfiles - 1),
196 AdaptationStates + (nProfiles - 1),
197 dwFlags);
198 if (out == NULL) {
199 cmsFreeToneCurve(in);
200 return NULL;
201 }
202
203 // Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
204 // since this is used on black-preserving LUTs, we are not losing accuracy in any case
205 KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
206
207 // Get rid of components
208 cmsFreeToneCurve(in); cmsFreeToneCurve(out);
209
210 // Something went wrong...
211 if (KTone == NULL) return NULL;
212
213 // Make sure it is monotonic
214 if (!cmsIsToneCurveMonotonic(KTone)) {
215 cmsFreeToneCurve(KTone);
216 return NULL;
217 }
218
219 return KTone;
220 }
221
222
223 // Gamut LUT Creation -----------------------------------------------------------------------------------------
224
290
291 // dE1 is big and dE2 is also big, could be due to perceptual mapping
292 // so take error ratio
293 if (dE2 == 0.0)
294 ErrorRatio = dE1;
295 else
296 ErrorRatio = dE1 / dE2;
297
298 if (ErrorRatio > t->Thereshold)
299 Out[0] = (cmsUInt16Number) _cmsQuickFloor((ErrorRatio - t->Thereshold) + .5);
300 else
301 Out[0] = 0;
302 }
303 }
304
305
306 return TRUE;
307 }
308
309 // Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
310 // the dE obtained is then annotated on the LUT. Values truly out of gamut are clipped to dE = 0xFFFE
311 // and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
312 //
313 // **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
314 // of course, many perceptual and saturation intents does not work in such way, but relativ. ones should.
315
316 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
317 cmsHPROFILE hProfiles[],
318 cmsBool BPC[],
319 cmsUInt32Number Intents[],
320 cmsFloat64Number AdaptationStates[],
321 cmsUInt32Number nGamutPCSposition,
322 cmsHPROFILE hGamut)
323 {
324 cmsHPROFILE hLab;
325 cmsPipeline* Gamut;
326 cmsStage* CLUT;
327 cmsUInt32Number dwFormat;
328 GAMUTCHAIN Chain;
329 int nChannels, nGridpoints;
330 cmsColorSpaceSignature ColorSpace;
|