home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
evbl0627.zip
/
everblue_20010627.zip
/
x11
/
Xcms_CvCols.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-02
|
29KB
|
1,059 lines
/* $XConsortium: CvCols.c,v 1.12 93/09/07 21:30:32 rws Exp $" */
/*
* Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
* All Rights Reserved
*
* This file is a component of an X Window System-specific implementation
* of Xcms based on the TekColor Color Management System. Permission is
* hereby granted to use, copy, modify, sell, and otherwise distribute this
* software and its documentation for any purpose and without fee, provided
* that this copyright, permission, and disclaimer notice is reproduced in
* all copies of this software and in supporting documentation. TekColor
* is a trademark of Tektronix, Inc.
*
* Tektronix makes no representation about the suitability of this software
* for any purpose. It is provided "as is" and with all faults.
*
* TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
* INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
*
*
* NAME
* XcmsCvCols.c
*
* DESCRIPTION
* Xcms API routine that converts between the
* device-independent color spaces.
*
*
*/
#include "Xlib_private.h"
#include "Xcmsint.h"
/*
* EXTERNS
* External declarations required locally to this package
* that are not already declared in any of the included header
* files (external includes or internal includes).
*/
extern XcmsRegColorSpaceEntry _XcmsRegColorSpaces[];
extern XcmsColorSpace **_XcmsDIColorSpaces;
extern XcmsColorSpace **_XcmsDDColorSpaces;
/*
* LOCAL DEFINES
*/
#define DD_FORMAT 0x01
#define DI_FORMAT 0x02
#define MIX_FORMAT 0x04
#ifndef MAX
# define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
/*
* FORWARD DECLARATIONS
*/
Status _XcmsDIConvertColors();
Status _XcmsDDConvertColors();
/************************************************************************
* *
* PRIVATE ROUTINES *
* *
************************************************************************/
/*
* NAME
* EqualCIEXYZ
*
* SYNOPSIS
*/
static int
EqualCIEXYZ(p1, p2)
XcmsColor *p1, *p2;
/*
* DESCRIPTION
* Compares two XcmsColor structures that are in XcmsCIEXYZFormat
*
* RETURNS
* Returns 1 if equal; 0 otherwise.
*
*/
{
DBUG_ENTER("EqualCIEXYZ")
if (p1->format != XcmsCIEXYZFormat || p2->format != XcmsCIEXYZFormat) {
DBUG_RETURN(0);
}
if ((p1->spec.CIEXYZ.X != p2->spec.CIEXYZ.X)
|| (p1->spec.CIEXYZ.Y != p2->spec.CIEXYZ.Y)
|| (p1->spec.CIEXYZ.Z != p2->spec.CIEXYZ.Z)) {
DBUG_RETURN(0);
}
DBUG_RETURN(1);
}
/*
* NAME
* XcmsColorSpace
*
* SYNOPSIS
*/
static XcmsColorSpace *
ColorSpaceOfID(ccc, id)
XcmsCCC ccc;
XcmsColorFormat id;
/*
* DESCRIPTION
* Returns a pointer to the color space structure
* (XcmsColorSpace) associated with the specified color space
* ID.
*
* RETURNS
* Pointer to matching XcmsColorSpace structure if found;
* otherwise NULL.
*/
{
DBUG_ENTER("ColorSpaceOfID")
XcmsColorSpace **papColorSpaces;
if (ccc == NULL) {
DBUG_RETURN(NULL);
}
/*
* First try Device-Independent color spaces
*/
papColorSpaces = _XcmsDIColorSpaces;
if (papColorSpaces != NULL) {
while (*papColorSpaces != NULL) {
if ((*papColorSpaces)->id == id) {
DBUG_RETURN(*papColorSpaces);
}
papColorSpaces++;
}
}
/*
* Next try Device-Dependent color spaces
*/
papColorSpaces = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces;
if (papColorSpaces != NULL) {
while (*papColorSpaces != NULL) {
if ((*papColorSpaces)->id == id) {
DBUG_RETURN(*papColorSpaces);
}
papColorSpaces++;
}
}
DBUG_RETURN(NULL);
}
/*
* NAME
* ValidDIColorSpaceID
*
* SYNOPSIS
*/
static int
ValidDIColorSpaceID(id)
XcmsColorFormat id;
/*
* DESCRIPTION
* Determines if the specified color space ID is a valid
* Device-Independent color space in the specified Color
* Conversion Context.
*
* RETURNS
* Returns zero if not valid; otherwise non-zero.
*/
{
DBUG_ENTER("ValidDIColorSpaceID")
XcmsColorSpace **papRec;
papRec = _XcmsDIColorSpaces;
if (papRec != NULL) {
while (*papRec != NULL) {
if ((*papRec)->id == id) {
DBUG_RETURN(1);
}
papRec++;
}
}
DBUG_RETURN(0);
}
/*
* NAME
* ValidDDColorSpaceID
*
* SYNOPSIS
*/
static int
ValidDDColorSpaceID(ccc, id)
XcmsCCC ccc;
XcmsColorFormat id;
/*
* DESCRIPTION
* Determines if the specified color space ID is a valid
* Device-Dependent color space in the specified Color
* Conversion Context.
*
* RETURNS
* Returns zero if not valid; otherwise non-zero.
*/
{
DBUG_ENTER("ValidDDColorSpaceID")
XcmsColorSpace **papRec;
if (ccc->pPerScrnInfo->state != XcmsInitNone) {
papRec = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces;
while (*papRec != NULL) {
if ((*papRec)->id == id) {
DBUG_RETURN(1);
}
papRec++;
}
}
DBUG_RETURN(0);
}
/*
* NAME
* ConvertMixedColors - Convert XcmsColor structures
*
* SYNOPSIS
*/
static Status
ConvertMixedColors(ccc, pColors_in_out, pWhitePt, nColors,
targetFormat, format_flag)
XcmsCCC ccc;
XcmsColor *pColors_in_out;
XcmsColor *pWhitePt;
unsigned int nColors;
XcmsColorFormat targetFormat;
unsigned char format_flag;
/*
* DESCRIPTION
* This routine will only convert the following types of
* batches:
* DI to DI
* DD to DD
* DD to CIEXYZ
* In other words, it will not convert the following types of
* batches:
* DI to DD
* DD to DI(not CIEXYZ)
*
* format_flag:
* 0x01 : convert Device-Dependent only specifications to the
* target format.
* 0x02 : convert Device-Independent only specifications to the
* target format.
* 0x03 : convert all specifications to the target format.
*
* RETURNS
* XcmsFailure if failed,
* XcmsSuccess if none of the color specifications were
* compressed in the conversion process
* XcmsSuccessWithCompression if at least one of the
* color specifications were compressed in the
* conversion process.
*
*/
{
DBUG_ENTER("ConvertMixedColors")
XcmsColor *pColor, *pColors_start;
XcmsColorFormat format;
Status retval_tmp;
Status retval = XcmsSuccess;
unsigned int iColors;
unsigned int nBatch;
/*
* Convert array of mixed color specifications in batches of
* contiguous formats to the target format
*/
iColors = 0;
while (iColors < nColors) {
/*
* Find contiguous array of color specifications with the
* same format
*/
pColor = pColors_start = pColors_in_out + iColors;
format = pColors_start->format;
nBatch = 0;
while (iColors < nColors && pColor->format == format) {
pColor++;
nBatch++;
iColors++;
}
if (format != targetFormat) {
/*
* Need to convert this batch from current format to target format.
*/
if (XCMS_DI_ID(format) && (format_flag & DI_FORMAT) &&
XCMS_DI_ID(targetFormat)) {
/*
* DI->DI
*
* Format of interest is Device-Independent,
* This batch contains Device-Independent specifications, and
* the Target format is Device-Independent.
*/
retval_tmp = _XcmsDIConvertColors(ccc, pColors_start, pWhitePt,
nBatch, targetFormat);
} else if (XCMS_DD_ID(format) && (format_flag & DD_FORMAT) &&
(targetFormat == XcmsCIEXYZFormat)) {
/*
* DD->CIEXYZ
*
* Format of interest is Device-Dependent,
* This batch contains Device-Dependent specifications, and
* the Target format is CIEXYZ.
*
* Since DD->CIEXYZ we can use NULL instead of pCompressed.
*/
if ((ccc->whitePtAdjProc != NULL) && !_XcmsEqualWhitePts(ccc,
pWhitePt, ScreenWhitePointOfCCC(ccc))) {
/*
* Need to call WhiteAdjustProc (Screen White Point to
* White Point).
*/
retval_tmp = (*ccc->whitePtAdjProc)(ccc,
ScreenWhitePointOfCCC(ccc), pWhitePt,
XcmsCIEXYZFormat, pColors_start, nBatch,
(Bool *)NULL);
} else {
retval_tmp = _XcmsDDConvertColors(ccc, pColors_start,
nBatch, XcmsCIEXYZFormat, (Bool *)NULL);
}
} else if (XCMS_DD_ID(format) && (format_flag & DD_FORMAT) &&
XCMS_DD_ID(targetFormat)) {
/*
* DD->DD(not CIEXYZ)
*
* Format of interest is Device-Dependent,
* This batch contains Device-Dependent specifications, and
* the Target format is Device-Dependent and not CIEXYZ.
*/
retval_tmp = _XcmsDDConvertColors(ccc, pColors_start, nBatch,
targetFormat, (Bool *)NULL);
} else {
/*
* This routine is called for the wrong reason.
*/
DBUG_RETURN(XcmsFailure);
}
if (retval_tmp == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
retval = MAX(retval, retval_tmp);
}
}
DBUG_RETURN(retval);
}
/************************************************************************
* *
* API PRIVATE ROUTINES *
* *
************************************************************************/
/*
* NAME
* _XcmsEqualWhitePts
*
* SYNOPSIS
*/
int
_XcmsEqualWhitePts(ccc, pWhitePt1, pWhitePt2)
XcmsCCC ccc;
XcmsColor *pWhitePt1, *pWhitePt2;
/*
* DESCRIPTION
*
* RETURNS
* Returns 0 if not equal; otherwise 1.
*
*/
{
DBUG_ENTER("_XcmsEqualWhitePts")
XcmsColor tmp1, tmp2;
memcpy((char *)&tmp1, (char *)pWhitePt1, sizeof(XcmsColor));
memcpy((char *)&tmp2, (char *)pWhitePt2, sizeof(XcmsColor));
if (tmp1.format != XcmsCIEXYZFormat) {
if (_XcmsDIConvertColors(ccc, &tmp1, (XcmsColor *) NULL, 1,
XcmsCIEXYZFormat)==0) {
DBUG_RETURN(0);
}
}
if (tmp2.format != XcmsCIEXYZFormat) {
if (_XcmsDIConvertColors(ccc, &tmp2, (XcmsColor *) NULL, 1,
XcmsCIEXYZFormat)==0) {
DBUG_RETURN(0);
}
}
DBUG_RETURN(EqualCIEXYZ(&tmp1, &tmp2));
}
/*
* NAME
* _XcmsDIConvertColors - Convert XcmsColor structures
*
* SYNOPSIS
*/
Status
_XcmsDIConvertColors(ccc, pColors_in_out, pWhitePt, nColors,
newFormat)
XcmsCCC ccc;
XcmsColor *pColors_in_out;
XcmsColor *pWhitePt;
unsigned int nColors;
XcmsColorFormat newFormat;
/*
* DESCRIPTION
* Convert XcmsColor structures to another Device-Independent
* form.
*
* Here are some assumptions that this routine makes:
* 1. The calling routine has already checked if
* pColors_in_out->format == newFormat, therefore
* there is no need to check again here.
* 2. The calling routine has already checked nColors,
* therefore this routine assumes nColors > 0.
* 3. The calling routine may want to convert only between
* CIExyY <-> CIEXYZ <-> CIEuvY
* therefore, this routine allows pWhitePt to equal NULL.
*
*
* RETURNS
* XcmsFailure if failed,
* XcmsSuccess if succeeded.
*
*/
{
DBUG_ENTER("_XcmsDIConvertColors")
XcmsColorSpace *pFrom, *pTo;
XcmsConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ;
XcmsConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ;
XcmsConversionProc *to_CIEXYZ_stop, *from_CIEXYZ_start;
XcmsConversionProc *tmp;
/*
* Allow pWhitePt to equal NULL. This appropriate when converting
* anywhere between:
* CIExyY <-> CIEXYZ <-> CIEuvY
*/
if (pColors_in_out == NULL ||
!ValidDIColorSpaceID(pColors_in_out->format) ||
!ValidDIColorSpaceID(newFormat)) {
DBUG_RETURN(XcmsFailure);
}
/*
* Get a handle on the function list for the current specification format
*/
if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format))
== NULL) {
DBUG_RETURN(XcmsFailure);
}
/*
* Get a handle on the function list for the new specification format
*/
if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL) {
DBUG_RETURN(XcmsFailure);
}
src_to_CIEXYZ = pFrom->to_CIEXYZ;
src_from_CIEXYZ = pFrom->from_CIEXYZ;
dest_to_CIEXYZ = pTo->to_CIEXYZ;
dest_from_CIEXYZ = pTo->from_CIEXYZ;
if (pTo->inverse_flag && pFrom->inverse_flag) {
/*
* Find common function pointers
*/
for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){
for (tmp = dest_to_CIEXYZ; *tmp; tmp++) {
if (*to_CIEXYZ_stop == *tmp) {
goto Continue;
}
}
}
Continue:
/*
* Execute the functions to CIEXYZ, stopping short as necessary
*/
while (src_to_CIEXYZ != to_CIEXYZ_stop) {
if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out,
nColors) == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
}
/*
* Determine where to start on the from_CIEXYZ path.
*/
from_CIEXYZ_start = dest_from_CIEXYZ;
tmp = src_from_CIEXYZ;
while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL)) {
from_CIEXYZ_start++;
tmp++;
}
} else {
/*
* The function in at least one of the Color Spaces are not
* complementary, i.e.,
* for an i, 0 <= i < n elements
* from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i]
*
* Execute the functions all the way to CIEXYZ
*/
while (*src_to_CIEXYZ) {
if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out,
nColors) == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
}
/*
* Determine where to start on the from_CIEXYZ path.
*/
from_CIEXYZ_start = dest_from_CIEXYZ;
}
/*
* Execute the functions from CIEXYZ.
*/
while (*from_CIEXYZ_start) {
if ((*from_CIEXYZ_start++)(ccc, pWhitePt, pColors_in_out,
nColors) == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
}
DBUG_RETURN(XcmsSuccess);
}
/*
* NAME
* _XcmsDDConvertColors - Convert XcmsColor structures
*
* SYNOPSIS
*/
Status
_XcmsDDConvertColors(ccc, pColors_in_out, nColors, newFormat,
pCompressed)
XcmsCCC ccc;
XcmsColor *pColors_in_out;
unsigned int nColors;
XcmsColorFormat newFormat;
Bool *pCompressed;
/*
* DESCRIPTION
* Convert XcmsColor structures:
*
* 1. From CIEXYZ to Device-Dependent formats (typically RGB and
* RGBi),
* or
* 2. Between Device-Dependent formats (typically RGB and RGBi).
*
* Assumes that these specifications have already been white point
* adjusted if necessary from Client White Point to Screen
* White Point. Therefore, the white point now associated
* with the specifications is the Screen White Point.
*
* pCompressed may be NULL. If so this indicates that the
* calling routine is not interested in knowing exactly which
* color was compressed, if any.
*
*
* RETURNS
* XcmsFailure if failed,
* XcmsSuccess if none of the color specifications were
* compressed in the conversion process
* XcmsSuccessWithCompression if at least one of the
* color specifications were compressed in the
* conversion process.
*
*/
{
DBUG_ENTER("_XcmsDDConvertColors")
XcmsColorSpace *pFrom, *pTo;
XcmsConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ;
XcmsConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ;
XcmsConversionProc *from_CIEXYZ_start, *to_CIEXYZ_stop;
XcmsConversionProc *tmp;
int retval;
int hasCompressed = 0;
if (ccc == NULL || pColors_in_out == NULL) {
DBUG_RETURN(XcmsFailure);
}
if (nColors == 0 || pColors_in_out->format == newFormat) {
/* do nothing */
DBUG_RETURN(XcmsSuccess);
}
if (((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet) == NULL) {
DBUG_RETURN(XcmsFailure); /* hmm, an internal error? */
}
/*
* Its ok if pColors_in_out->format == XcmsCIEXYZFormat
* or
* if newFormat == XcmsCIEXYZFormat
*/
if ( !( ValidDDColorSpaceID(ccc, pColors_in_out->format)
||
(pColors_in_out->format == XcmsCIEXYZFormat))
||
!(ValidDDColorSpaceID(ccc, newFormat)
||
newFormat == XcmsCIEXYZFormat)) {
DBUG_RETURN(XcmsFailure);
}
if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format)) == NULL){
DBUG_RETURN(XcmsFailure);
}
if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL) {
DBUG_RETURN(XcmsFailure);
}
src_to_CIEXYZ = pFrom->to_CIEXYZ;
src_from_CIEXYZ = pFrom->from_CIEXYZ;
dest_to_CIEXYZ = pTo->to_CIEXYZ;
dest_from_CIEXYZ = pTo->from_CIEXYZ;
if (pTo->inverse_flag && pFrom->inverse_flag) {
/*
* Find common function pointers
*/
for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){
for (tmp = dest_to_CIEXYZ; *tmp; tmp++) {
if (*to_CIEXYZ_stop == *tmp) {
goto Continue;
}
}
}
Continue:
/*
* Execute the functions
*/
while (src_to_CIEXYZ != to_CIEXYZ_stop) {
retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors,
pCompressed);
if (retval == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
hasCompressed |= (retval == XcmsSuccessWithCompression);
}
/*
* Determine where to start on the from_CIEXYZ path.
*/
from_CIEXYZ_start = dest_from_CIEXYZ;
tmp = src_from_CIEXYZ;
while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL)) {
from_CIEXYZ_start++;
tmp++;
}
} else {
/*
* The function in at least one of the Color Spaces are not
* complementary, i.e.,
* for an i, 0 <= i < n elements
* from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i]
*
* Execute the functions all the way to CIEXYZ
*/
while (*src_to_CIEXYZ) {
retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors,
pCompressed);
if (retval == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
hasCompressed |= (retval == XcmsSuccessWithCompression);
}
/*
* Determine where to start on the from_CIEXYZ path.
*/
from_CIEXYZ_start = dest_from_CIEXYZ;
}
while (*from_CIEXYZ_start) {
retval = (*from_CIEXYZ_start++)(ccc, pColors_in_out, nColors,
pCompressed);
if (retval == XcmsFailure) {
DBUG_RETURN(XcmsFailure);
}
hasCompressed |= (retval == XcmsSuccessWithCompression);
}
DBUG_RETURN(hasCompressed ? XcmsSuccessWithCompression : XcmsSuccess);
}
/************************************************************************
* *
* PUBLIC ROUTINES *
* *
************************************************************************/
/*
* NAME
* XcmsConvertColors - Convert XcmsColor structures
*
* SYNOPSIS
*/
Status
XcmsConvertColors(ccc, pColors_in_out, nColors, targetFormat, pCompressed)
XcmsCCC ccc;
XcmsColor *pColors_in_out;
unsigned int nColors;
XcmsColorFormat targetFormat;
Bool *pCompressed;
/*
* DESCRIPTION
* Convert XcmsColor structures to another format
*
* RETURNS
* XcmsFailure if failed,
* XcmsSuccess if succeeded without gamut compression,
* XcmsSuccessWithCompression if succeeded with gamut
* compression.
*
*/
{
DBUG_ENTER("XcmsConvertColors")
XcmsColor clientWhitePt;
XcmsColor Color1;
XcmsColor *pColors_tmp;
int callWhiteAdjustProc = 0;
XcmsColorFormat format;
Status retval;
unsigned char contents_flag = 0x00;
unsigned int iColors;
if (ccc == NULL || pColors_in_out == NULL ||
!(ValidDIColorSpaceID(targetFormat) ||
ValidDDColorSpaceID(ccc, targetFormat))) {
DBUG_RETURN(XcmsFailure);
}
/*
* Check formats in color specification array
*/
format = pColors_in_out->format;
for (pColors_tmp = pColors_in_out, iColors = nColors; iColors; pColors_tmp++, iColors--) {
if (!(ValidDIColorSpaceID(pColors_tmp->format) ||
ValidDDColorSpaceID(ccc, pColors_tmp->format))) {
DBUG_RETURN(XcmsFailure);
}
if (XCMS_DI_ID(pColors_tmp->format)) {
contents_flag |= DI_FORMAT;
} else {
contents_flag |= DD_FORMAT;
}
if (pColors_tmp->format != format) {
contents_flag |= MIX_FORMAT;
}
}
/*
* Check if we need the Client White Point.
*/
if ((contents_flag & DI_FORMAT) || XCMS_DI_ID(targetFormat)) {
/* To proceed, we need to get the Client White Point */
memcpy((char *)&clientWhitePt, (char *)&ccc->clientWhitePt,
sizeof(XcmsColor));
if (clientWhitePt.format == XcmsUndefinedFormat) {
/*
* Client White Point is undefined, therefore set to the Screen
* White Point.
* Since Client White Point == Screen White Point, WhiteAdjustProc
* is not called.
*/
memcpy((char *)&clientWhitePt,
(char *)&ccc->pPerScrnInfo->screenWhitePt,
sizeof(XcmsColor));
} else if ((ccc->whitePtAdjProc != NULL) && !_XcmsEqualWhitePts(ccc,
&clientWhitePt, ScreenWhitePointOfCCC(ccc))) {
/*
* Client White Point != Screen White Point, and WhiteAdjustProc
* is not NULL, therefore, will need to call it when
* converting between DI and DD specifications.
*/
callWhiteAdjustProc = 1;
}
}
/*
* Make copy of array of color specifications
*/
if (nColors > 1) {
pColors_tmp = (XcmsColor *) Xmalloc(nColors * sizeof(XcmsColor));
} else {
pColors_tmp = &Color1;
}
memcpy((char *)pColors_tmp, (char *)pColors_in_out,
nColors * sizeof(XcmsColor));
/*
* zero out pCompressed
*/
if (pCompressed) {
bzero((char *)pCompressed, nColors * sizeof(Bool));
}
if (contents_flag == DD_FORMAT || contents_flag == DI_FORMAT) {
/*
* ENTIRE ARRAY IS IN ONE FORMAT.
*/
if (XCMS_DI_ID(format) && XCMS_DI_ID(targetFormat)) {
/*
* DI-to-DI only conversion
*/
retval = _XcmsDIConvertColors(ccc, pColors_tmp,
&clientWhitePt, nColors, targetFormat);
} else if (XCMS_DD_ID(format) && XCMS_DD_ID(targetFormat)) {
/*
* DD-to-DD only conversion
* Since DD->DD there will be no compressed thus we can
* pass NULL instead of pCompressed.
*/
retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors,
targetFormat, (Bool *)NULL);
} else {
/*
* Otherwise we have:
* 1. Device-Independent to Device-Dependent Conversion
* OR
* 2. Device-Dependent to Device-Independent Conversion
*
* We need to go from oldFormat -> CIEXYZ -> targetFormat
* adjusting for white points as necessary.
*/
if (XCMS_DI_ID(format)) {
/*
* 1. Device-Independent to Device-Dependent Conversion
*/
if (callWhiteAdjustProc) {
/*
* White Point Adjustment
* Client White Point to Screen White Point
*/
retval = (*ccc->whitePtAdjProc)(ccc, &clientWhitePt,
ScreenWhitePointOfCCC(ccc), targetFormat,
pColors_tmp, nColors, pCompressed);
} else {
if (_XcmsDIConvertColors(ccc, pColors_tmp,
&clientWhitePt, nColors, XcmsCIEXYZFormat)
== XcmsFailure) {
goto Failure;
}
retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors,
targetFormat, pCompressed);
}
} else {
/*
* 2. Device-Dependent to Device-Independent Conversion
*/
if (callWhiteAdjustProc) {
/*
* White Point Adjustment
* Screen White Point to Client White Point
*/
retval = (*ccc->whitePtAdjProc)(ccc,
ScreenWhitePointOfCCC(ccc), &clientWhitePt,
targetFormat, pColors_tmp, nColors, pCompressed);
} else {
/*
* Since DD->CIEXYZ, no compression takes place therefore
* we can pass NULL instead of pCompressed.
*/
if (_XcmsDDConvertColors(ccc, pColors_tmp, nColors,
XcmsCIEXYZFormat, (Bool *)NULL) == XcmsFailure) {
goto Failure;
}
retval = _XcmsDIConvertColors(ccc, pColors_tmp,
&clientWhitePt, nColors, targetFormat);
}
}
}
} else {
/*
* ARRAY HAS MIXED FORMATS.
*/
if ((contents_flag == (DI_FORMAT | MIX_FORMAT)) &&
XCMS_DI_ID(targetFormat)) {
/*
* Convert from DI to DI in batches of contiguous formats
*
* Because DI->DI, WhiteAdjustProc not called.
*/
retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt,
nColors, targetFormat, (unsigned char)DI_FORMAT);
} else if ((contents_flag == (DD_FORMAT | MIX_FORMAT)) &&
XCMS_DD_ID(targetFormat)) {
/*
* Convert from DD to DD in batches of contiguous formats
*
* Because DD->DD, WhiteAdjustProc not called.
*/
retval = ConvertMixedColors(ccc, pColors_tmp,
(XcmsColor *)NULL, nColors, targetFormat,
(unsigned char)DD_FORMAT);
} else if (XCMS_DI_ID(targetFormat)) {
/*
* We need to convert from DI-to-DI and DD-to-DI, therefore
* 1. convert DD specifications to CIEXYZ, then
* 2. convert all in batches to the target DI format.
*
* Note that ConvertMixedColors will call WhiteAdjustProc
* as necessary.
*/
/*
* Convert only DD specifications in batches of contiguous formats
* to CIEXYZ
*
* Since DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc
* if required.
*/
retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt,
nColors, XcmsCIEXYZFormat, (unsigned char)DD_FORMAT);
/*
* Because at this point we may have a mix of DI formats
* (e.g., CIEXYZ, CIELuv) we must convert the specs to the
* target DI format in batches of contiguous source formats.
*/
retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt,
nColors, targetFormat, (unsigned char)DI_FORMAT);
} else {
/*
* We need to convert from DI-to-DD and DD-to-DD, therefore
* 1. convert DI specifications to CIEXYZ, then
* 2. convert all to the DD target format.
*
* This allows white point adjustment and gamut compression
* to be applied to all the color specifications in one
* swoop if those functions do in fact modify the entire
* group of color specifications.
*/
/*
* Convert in batches to CIEXYZ
*
* If DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc
* if required.
*/
if ((retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt,
nColors, XcmsCIEXYZFormat,
(unsigned char)(DI_FORMAT | DD_FORMAT))) == XcmsFailure) {
goto Failure;
}
/*
* Convert all specifications (now in CIEXYZ format) to
* the target DD format.
* Since CIEXYZ->DD, compression MAY take place therefore
* we must pass pCompressed.
* Note that WhiteAdjustProc must be used if necessary.
*/
if (callWhiteAdjustProc) {
/*
* White Point Adjustment
* Client White Point to Screen White Point
*/
retval = (*ccc->whitePtAdjProc)(ccc,
&clientWhitePt, ScreenWhitePointOfCCC(ccc),
targetFormat, pColors_tmp, nColors, pCompressed);
} else {
retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors,
targetFormat, pCompressed);
}
}
}
if (retval != XcmsFailure) {
memcpy((char *)pColors_in_out, (char *)pColors_tmp,
nColors * sizeof(XcmsColor));
}
if (nColors > 1) {
Xfree((char *)pColors_tmp);
}
DBUG_RETURN(retval);
Failure:
if (nColors > 1) {
Xfree((char *)pColors_tmp);
}
DBUG_RETURN(XcmsFailure);
}
/*
* NAME
* XcmsRegFormatOfPrefix
*
* SYNOPSIS
*/
XcmsColorFormat
_XcmsRegFormatOfPrefix(prefix)
char *prefix;
/*
* DESCRIPTION
* Returns a color space ID associated with the specified
* X Consortium registered color space prefix.
*
* RETURNS
* The color space ID if found;
* otherwise NULL.
*/
{
DBUG_ENTER("_XcmsRegFormatOfPrefix")
XcmsRegColorSpaceEntry *pEntry = _XcmsRegColorSpaces;
while (pEntry->prefix != NULL) {
if (strcmp(prefix, pEntry->prefix) == 0) {
DBUG_RETURN(pEntry->id);
}
pEntry++;
}
DBUG_RETURN(XcmsUndefinedFormat);
}