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-2011 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 //---------------------------------------------------------------------------------
230
231
232 /*
233 Closest point in sector line1 to sector line2 (both are defined as 0 <=t <= 1)
234 http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
235
236 Copyright 2001, softSurfer (www.softsurfer.com)
237 This code may be freely used and modified for any purpose
238 providing that this copyright notice is included with it.
239 SoftSurfer makes no warranty for this code, and cannot be held
240 liable for any real or imagined damage resulting from its use.
241 Users of this code must verify correctness for their application.
242
243 */
244
245 static
246 cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2)
247 {
248 cmsFloat64Number a, b, c, d, e, D;
249 cmsFloat64Number sc, sN, sD;
250 cmsFloat64Number tc, tN, tD;
251 cmsVEC3 w0;
252
253 _cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
254
255 a = _cmsVEC3dot(&line1 ->u, &line1 ->u);
256 b = _cmsVEC3dot(&line1 ->u, &line2 ->u);
257 c = _cmsVEC3dot(&line2 ->u, &line2 ->u);
258 d = _cmsVEC3dot(&line1 ->u, &w0);
259 e = _cmsVEC3dot(&line2 ->u, &w0);
260
261 D = a*c - b * b; // Denominator
262 sD = tD = D; // default sD = D >= 0
263
264 if (D < MATRIX_DET_TOLERANCE) { // the lines are almost parallel
265
266 sN = 0.0; // force using point P0 on segment S1
267 sD = 1.0; // to prevent possible division by 0.0 later
268 tN = e;
269 tD = c;
270 }
298 sN = -d;
299 sD = a;
300 }
301 }
302 else if (tN > tD) { // tc > 1 => the t=1 edge is visible
303
304 tN = tD;
305
306 // recompute sc for this edge
307 if ((-d + b) < 0.0)
308 sN = 0;
309 else if ((-d + b) > a)
310 sN = sD;
311 else {
312 sN = (-d + b);
313 sD = a;
314 }
315 }
316 // finally do the division to get sc and tc
317 sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
318 tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD);
319
320 GetPointOfLine(r, line1, sc);
321 return TRUE;
322 }
323
324
325
326 // ------------------------------------------------------------------ Wrapper
327
328
329 // Allocate & free structure
330 cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID)
331 {
332 cmsGDB* gbd = (cmsGDB*) _cmsMallocZero(ContextID, sizeof(cmsGDB));
333 if (gbd == NULL) return NULL;
334
335 gbd -> ContextID = ContextID;
336
337 return (cmsHANDLE) gbd;
338 }
339
340
341 void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
342 {
343 cmsGDB* gbd = (cmsGDB*) hGBD;
344 if (hGBD != NULL)
345 _cmsFree(gbd->ContextID, (void*) gbd);
346 }
347
348
349 // Auxiliar to retrieve a pointer to the segmentr containing the Lab value
350 static
351 cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
352 {
353 cmsVEC3 v;
354 int alpha, theta;
355
356 // Housekeeping
357 _cmsAssert(gbd != NULL);
358 _cmsAssert(Lab != NULL);
359 _cmsAssert(sp != NULL);
360
361 // Center L* by substracting half of its domain, that's 50
362 _cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
363
364 // Convert to spherical coordinates
365 ToSpherical(sp, &v);
366
367 if (sp ->r < 0 || sp ->alpha < 0 || sp->theta < 0) {
368 cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, "spherical value out of range");
369 return NULL;
370 }
371
372 // On which sector it falls?
373 QuantizeToSector(sp, &alpha, &theta);
374
375 if (alpha < 0 || theta < 0 || alpha >= SECTORS || theta >= SECTORS) {
376 cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, " quadrant out of range");
377 return NULL;
378 }
379
380 // Get pointer to the sector
381 return &gbd ->Gamut[theta][alpha];
|
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 //---------------------------------------------------------------------------------
230
231
232 /*
233 Closest point in sector line1 to sector line2 (both are defined as 0 <=t <= 1)
234 http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm
235
236 Copyright 2001, softSurfer (www.softsurfer.com)
237 This code may be freely used and modified for any purpose
238 providing that this copyright notice is included with it.
239 SoftSurfer makes no warranty for this code, and cannot be held
240 liable for any real or imagined damage resulting from its use.
241 Users of this code must verify correctness for their application.
242
243 */
244
245 static
246 cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2)
247 {
248 cmsFloat64Number a, b, c, d, e, D;
249 cmsFloat64Number sc, sN, sD;
250 //cmsFloat64Number tc; // left for future use
251 cmsFloat64Number tN, tD;
252 cmsVEC3 w0;
253
254 _cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
255
256 a = _cmsVEC3dot(&line1 ->u, &line1 ->u);
257 b = _cmsVEC3dot(&line1 ->u, &line2 ->u);
258 c = _cmsVEC3dot(&line2 ->u, &line2 ->u);
259 d = _cmsVEC3dot(&line1 ->u, &w0);
260 e = _cmsVEC3dot(&line2 ->u, &w0);
261
262 D = a*c - b * b; // Denominator
263 sD = tD = D; // default sD = D >= 0
264
265 if (D < MATRIX_DET_TOLERANCE) { // the lines are almost parallel
266
267 sN = 0.0; // force using point P0 on segment S1
268 sD = 1.0; // to prevent possible division by 0.0 later
269 tN = e;
270 tD = c;
271 }
299 sN = -d;
300 sD = a;
301 }
302 }
303 else if (tN > tD) { // tc > 1 => the t=1 edge is visible
304
305 tN = tD;
306
307 // recompute sc for this edge
308 if ((-d + b) < 0.0)
309 sN = 0;
310 else if ((-d + b) > a)
311 sN = sD;
312 else {
313 sN = (-d + b);
314 sD = a;
315 }
316 }
317 // finally do the division to get sc and tc
318 sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
319 //tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD); // left for future use.
320
321 GetPointOfLine(r, line1, sc);
322 return TRUE;
323 }
324
325
326
327 // ------------------------------------------------------------------ Wrapper
328
329
330 // Allocate & free structure
331 cmsHANDLE CMSEXPORT cmsGBDAlloc(cmsContext ContextID)
332 {
333 cmsGDB* gbd = (cmsGDB*) _cmsMallocZero(ContextID, sizeof(cmsGDB));
334 if (gbd == NULL) return NULL;
335
336 gbd -> ContextID = ContextID;
337
338 return (cmsHANDLE) gbd;
339 }
340
341
342 void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
343 {
344 cmsGDB* gbd = (cmsGDB*) hGBD;
345 if (hGBD != NULL)
346 _cmsFree(gbd->ContextID, (void*) gbd);
347 }
348
349
350 // Auxiliary to retrieve a pointer to the segmentr containing the Lab value
351 static
352 cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
353 {
354 cmsVEC3 v;
355 int alpha, theta;
356
357 // Housekeeping
358 _cmsAssert(gbd != NULL);
359 _cmsAssert(Lab != NULL);
360 _cmsAssert(sp != NULL);
361
362 // Center L* by subtracting half of its domain, that's 50
363 _cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
364
365 // Convert to spherical coordinates
366 ToSpherical(sp, &v);
367
368 if (sp ->r < 0 || sp ->alpha < 0 || sp->theta < 0) {
369 cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, "spherical value out of range");
370 return NULL;
371 }
372
373 // On which sector it falls?
374 QuantizeToSector(sp, &alpha, &theta);
375
376 if (alpha < 0 || theta < 0 || alpha >= SECTORS || theta >= SECTORS) {
377 cmsSignalError(gbd ->ContextID, cmsERROR_RANGE, " quadrant out of range");
378 return NULL;
379 }
380
381 // Get pointer to the sector
382 return &gbd ->Gamut[theta][alpha];
|