/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// This file is available under and governed by the GNU General Public
// License version 2 only, as published by the Free Software Foundation.
// However, the following notice accompanied the original version of this
// file:
//
//---------------------------------------------------------------------------------
//
// Little Color Management System
// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//---------------------------------------------------------------------------------
//
#include "lcms2_internal.h"
// ------------------------------------------------------------------------
// Gamut boundary description by using Jan Morovic's Segment maxima method
// Many thanks to Jan for allowing me to use his algorithm.
// r = C*
// alpha = Hab
// theta = L*
// Spherical coordinates
typedef struct {
} cmsSpherical;
typedef enum {
} GDBPointType;
typedef struct {
cmsSpherical p; // Keep also alpha & theta of maximum
} cmsGDBPoint;
typedef struct {
} cmsGDB;
// A line using the parametric form
// P = a + t*u
typedef struct {
cmsVEC3 a;
cmsVEC3 u;
} cmsLine;
// A plane using the parametric form
// Q = b + r*v + s*w
typedef struct {
cmsVEC3 b;
cmsVEC3 v;
cmsVEC3 w;
} cmsPlane;
// --------------------------------------------------------------------------------------------
// ATAN2() which always returns degree positive numbers
static
{
// Deal with undefined case
if (x == 0.0 && y == 0.0) return 0;
while (a < 0) {
a += 360;
}
return a;
}
// Convert to spherical coordinates
static
{
cmsFloat64Number L, a, b;
L = v ->n[VX];
a = v ->n[VY];
b = v ->n[VZ];
if (sp ->r == 0) {
return;
}
}
// Convert to cartesian from spherical
static
{
cmsFloat64Number L, a, b;
v ->n[VX] = L;
v ->n[VY] = a;
v ->n[VZ] = b;
}
// Quantize sector of a spherical coordinate. Saturate 360, 180 to last sector
// The limits are the centers of each sector, so
static
{
}
// Line determined by 2 points
static
{
}
// Evaluate parametric line
static
{
}
/*
Closest point in sector line1 to sector line2 (both are defined as 0 <=t <= 1)
Copyright 2001, softSurfer (www.softsurfer.com)
This code may be freely used and modified for any purpose
providing that this copyright notice is included with it.
SoftSurfer makes no warranty for this code, and cannot be held
liable for any real or imagined damage resulting from its use.
Users of this code must verify correctness for their application.
*/
static
{
cmsFloat64Number a, b, c, d, e, D;
D = a*c - b * b; // Denominator
if (D < MATRIX_DET_TOLERANCE) { // the lines are almost parallel
tN = e;
tD = c;
}
else { // get the closest points on the infinite lines
sN = (b*e - c*d);
tN = (a*e - b*d);
sN = 0.0;
tN = e;
tD = c;
}
tN = e + b;
tD = c;
}
}
tN = 0.0;
// recompute sc for this edge
if (-d < 0.0)
sN = 0.0;
else if (-d > a)
else {
sN = -d;
sD = a;
}
}
// recompute sc for this edge
if ((-d + b) < 0.0)
sN = 0;
else if ((-d + b) > a)
else {
sN = (-d + b);
sD = a;
}
}
// finally do the division to get sc and tc
return TRUE;
}
// ------------------------------------------------------------------ Wrapper
// Allocate & free structure
{
}
{
}
// Auxiliar to retrieve a pointer to the segmentr containing the Lab value
static
{
cmsVEC3 v;
// Housekeeping
// Center L* by substracting half of its domain, that's 50
// Convert to spherical coordinates
ToSpherical(sp, &v);
return NULL;
}
// On which sector it falls?
return NULL;
}
// Get pointer to the sector
}
// Add a point to gamut descriptor. Point to add is in Lab color space.
// GBD is centered on a=b=0 and L*=50
{
// Get pointer to the sector
// If no samples at this sector, add it
}
else {
// Substitute only if radius is greater
}
}
return TRUE;
}
// Check if a given point falls inside gamut
{
// Get pointer to the sector
// If no samples at this sector, return no data
// In gamut only if radius is greater
}
// -----------------------------------------------------------------------------------------------------------------------
// Find near sectors. The list of sectors found is returned on Close[].
// The function returns the number of sectors as well.
// 24 9 10 11 12
// 23 8 1 2 13
// 22 7 * 3 14
// 21 6 5 4 15
// 20 19 18 17 16
//
// Those are the relative movements
// {-2,-2}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2},
// {-2,-1}, {-1, -1}, {0, -1}, {+1, -1}, {+2, -1},
// {-2, 0}, {-1, 0}, {0, 0}, {+1, 0}, {+2, 0},
// {-2,+1}, {-1, +1}, {0, +1}, {+1, +1}, {+2, +1},
// {-2,+2}, {-1, +2}, {0, +2}, {+1, +2}, {+2, +2}};
static
const struct _spiral {
{-1, 0}, {-1, -1}, {-1, -2}, {0, -2}, {+1, -2}, {+2, -2},
{+2, -1}, {+2, 0}, {+2, +1}, {+2, +2}, {+1, +2}, {0, +2},
{-1, +2}, {-2, +2}, {-2, +1}, {-2, 0}, {-2, -1}, {-2, -2} };
static
{
int nSectors = 0;
int a, t;
for (i=0; i < NSTEPS; i++) {
// Cycle at the end
a %= SECTORS;
t %= SECTORS;
// Cycle at the begin
if (a < 0) a = SECTORS + a;
if (t < 0) t = SECTORS + t;
}
}
return nSectors;
}
// Interpolate a missing sector. Method identifies whatever this is top, bottom or mid
static
{
int nCloseSectors;
int k, m;
// Is that point already specified?
// Fill close points
// Find a central point on the sector
sp.r = 50.0;
// Convert to Cartesian
// Create a ray line from centre to this point
// For all close sectors
closel.r = 0.0;
for (k=0; k < nCloseSectors; k++) {
for(m = k+1; m < nCloseSectors; m++) {
// A line from sector to sector
// Find a line
// Convert to spherical
}
}
}
return TRUE;
}
// Interpolate missing parts. The algorithm fist computes slices at
// theta=0 and theta=Max.
{
// Interpolate black
}
// Interpolate white
}
// Interpolate Mid
}
}
// Done
return TRUE;
}
// --------------------------------------------------------------------------------------------------------
// Great for debug, but not suitable for real use
#if 0
{
int i, j;
return FALSE;
// set the viewing orientation and distance
// Output the background stuff
// Output the shape stuff
// Draw the axes as a shape:
// fill in the points here
// We need to transverse all gamut hull.
for (i=0; i < SECTORS; i++)
for (j=0; j < SECTORS; j++) {
cmsVEC3 v;
ToCartesian(&v, &pt ->p);
else
}
// fill in the face colors
for (i=0; i < SECTORS; i++)
for (j=0; j < SECTORS; j++) {
cmsVEC3 v;
ToCartesian(&v, &pt ->p);
else
else {
}
else
}
return TRUE;
}
#endif