File: | src/xcms/CvCols.c |
Location: | line 929, column 6 |
Description: | Value stored to 'retval' is never read |
1 | |
2 | /* |
3 | * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. |
4 | * All Rights Reserved |
5 | * |
6 | * This file is a component of an X Window System-specific implementation |
7 | * of Xcms based on the TekColor Color Management System. Permission is |
8 | * hereby granted to use, copy, modify, sell, and otherwise distribute this |
9 | * software and its documentation for any purpose and without fee, provided |
10 | * that this copyright, permission, and disclaimer notice is reproduced in |
11 | * all copies of this software and in supporting documentation. TekColor |
12 | * is a trademark of Tektronix, Inc. |
13 | * |
14 | * Tektronix makes no representation about the suitability of this software |
15 | * for any purpose. It is provided "as is" and with all faults. |
16 | * |
17 | * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, |
18 | * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
19 | * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY |
20 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER |
21 | * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF |
22 | * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
23 | * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. |
24 | * |
25 | * |
26 | * NAME |
27 | * XcmsCvCols.c |
28 | * |
29 | * DESCRIPTION |
30 | * Xcms API routine that converts between the |
31 | * device-independent color spaces. |
32 | * |
33 | * |
34 | */ |
35 | |
36 | #ifdef HAVE_CONFIG_H1 |
37 | #include <config.h> |
38 | #endif |
39 | #include "Xlibint.h" |
40 | #include "Xcmsint.h" |
41 | #include "Cv.h" |
42 | |
43 | /* |
44 | * LOCAL DEFINES |
45 | */ |
46 | #define DD_FORMAT0x01 0x01 |
47 | #define DI_FORMAT0x02 0x02 |
48 | #define MIX_FORMAT0x04 0x04 |
49 | #ifndef MAX |
50 | # define MAX(x,y)((x) > (y) ? (x) : (y)) ((x) > (y) ? (x) : (y)) |
51 | #endif |
52 | |
53 | |
54 | /************************************************************************ |
55 | * * |
56 | * PRIVATE ROUTINES * |
57 | * * |
58 | ************************************************************************/ |
59 | |
60 | /* |
61 | * NAME |
62 | * EqualCIEXYZ |
63 | * |
64 | * SYNOPSIS |
65 | */ |
66 | static int |
67 | EqualCIEXYZ( |
68 | XcmsColor *p1, XcmsColor *p2) |
69 | /* |
70 | * DESCRIPTION |
71 | * Compares two XcmsColor structures that are in XcmsCIEXYZFormat |
72 | * |
73 | * RETURNS |
74 | * Returns 1 if equal; 0 otherwise. |
75 | * |
76 | */ |
77 | { |
78 | if (p1->format != XcmsCIEXYZFormat(XcmsColorFormat)0x00000001 || p2->format != XcmsCIEXYZFormat(XcmsColorFormat)0x00000001) { |
79 | return(0); |
80 | } |
81 | if ((p1->spec.CIEXYZ.X != p2->spec.CIEXYZ.X) |
82 | || (p1->spec.CIEXYZ.Y != p2->spec.CIEXYZ.Y) |
83 | || (p1->spec.CIEXYZ.Z != p2->spec.CIEXYZ.Z)) { |
84 | return(0); |
85 | } |
86 | return(1); |
87 | } |
88 | |
89 | |
90 | /* |
91 | * NAME |
92 | * XcmsColorSpace |
93 | * |
94 | * SYNOPSIS |
95 | */ |
96 | static XcmsColorSpace * |
97 | ColorSpaceOfID( |
98 | XcmsCCC ccc, |
99 | XcmsColorFormat id) |
100 | /* |
101 | * DESCRIPTION |
102 | * Returns a pointer to the color space structure |
103 | * (XcmsColorSpace) associated with the specified color space |
104 | * ID. |
105 | * |
106 | * RETURNS |
107 | * Pointer to matching XcmsColorSpace structure if found; |
108 | * otherwise NULL. |
109 | */ |
110 | { |
111 | XcmsColorSpace **papColorSpaces; |
112 | |
113 | if (ccc == NULL((void*)0)) { |
114 | return(NULL((void*)0)); |
115 | } |
116 | |
117 | /* |
118 | * First try Device-Independent color spaces |
119 | */ |
120 | papColorSpaces = _XcmsDIColorSpaces; |
121 | if (papColorSpaces != NULL((void*)0)) { |
122 | while (*papColorSpaces != NULL((void*)0)) { |
123 | if ((*papColorSpaces)->id == id) { |
124 | return(*papColorSpaces); |
125 | } |
126 | papColorSpaces++; |
127 | } |
128 | } |
129 | |
130 | /* |
131 | * Next try Device-Dependent color spaces |
132 | */ |
133 | papColorSpaces = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces; |
134 | if (papColorSpaces != NULL((void*)0)) { |
135 | while (*papColorSpaces != NULL((void*)0)) { |
136 | if ((*papColorSpaces)->id == id) { |
137 | return(*papColorSpaces); |
138 | } |
139 | papColorSpaces++; |
140 | } |
141 | } |
142 | |
143 | return(NULL((void*)0)); |
144 | } |
145 | |
146 | |
147 | /* |
148 | * NAME |
149 | * ValidDIColorSpaceID |
150 | * |
151 | * SYNOPSIS |
152 | */ |
153 | static int |
154 | ValidDIColorSpaceID( |
155 | XcmsColorFormat id) |
156 | /* |
157 | * DESCRIPTION |
158 | * Determines if the specified color space ID is a valid |
159 | * Device-Independent color space in the specified Color |
160 | * Conversion Context. |
161 | * |
162 | * RETURNS |
163 | * Returns zero if not valid; otherwise non-zero. |
164 | */ |
165 | { |
166 | XcmsColorSpace **papRec; |
167 | papRec = _XcmsDIColorSpaces; |
168 | if (papRec != NULL((void*)0)) { |
169 | while (*papRec != NULL((void*)0)) { |
170 | if ((*papRec)->id == id) { |
171 | return(1); |
172 | } |
173 | papRec++; |
174 | } |
175 | } |
176 | return(0); |
177 | } |
178 | |
179 | |
180 | /* |
181 | * NAME |
182 | * ValidDDColorSpaceID |
183 | * |
184 | * SYNOPSIS |
185 | */ |
186 | static int |
187 | ValidDDColorSpaceID( |
188 | XcmsCCC ccc, |
189 | XcmsColorFormat id) |
190 | /* |
191 | * DESCRIPTION |
192 | * Determines if the specified color space ID is a valid |
193 | * Device-Dependent color space in the specified Color |
194 | * Conversion Context. |
195 | * |
196 | * RETURNS |
197 | * Returns zero if not valid; otherwise non-zero. |
198 | */ |
199 | { |
200 | XcmsColorSpace **papRec; |
201 | |
202 | if (ccc->pPerScrnInfo->state != XcmsInitNone0x00) { |
203 | papRec = ((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet)->DDColorSpaces; |
204 | while (*papRec != NULL((void*)0)) { |
205 | if ((*papRec)->id == id) { |
206 | return(1); |
207 | } |
208 | papRec++; |
209 | } |
210 | } |
211 | return(0); |
212 | } |
213 | |
214 | |
215 | /* |
216 | * NAME |
217 | * ConvertMixedColors - Convert XcmsColor structures |
218 | * |
219 | * SYNOPSIS |
220 | */ |
221 | static Statusint |
222 | ConvertMixedColors( |
223 | XcmsCCC ccc, |
224 | XcmsColor *pColors_in_out, |
225 | XcmsColor *pWhitePt, |
226 | unsigned int nColors, |
227 | XcmsColorFormat targetFormat, |
228 | unsigned char format_flag) |
229 | /* |
230 | * DESCRIPTION |
231 | * This routine will only convert the following types of |
232 | * batches: |
233 | * DI to DI |
234 | * DD to DD |
235 | * DD to CIEXYZ |
236 | * In other words, it will not convert the following types of |
237 | * batches: |
238 | * DI to DD |
239 | * DD to DI(not CIEXYZ) |
240 | * |
241 | * format_flag: |
242 | * 0x01 : convert Device-Dependent only specifications to the |
243 | * target format. |
244 | * 0x02 : convert Device-Independent only specifications to the |
245 | * target format. |
246 | * 0x03 : convert all specifications to the target format. |
247 | * |
248 | * RETURNS |
249 | * XcmsFailure if failed, |
250 | * XcmsSuccess if none of the color specifications were |
251 | * compressed in the conversion process |
252 | * XcmsSuccessWithCompression if at least one of the |
253 | * color specifications were compressed in the |
254 | * conversion process. |
255 | * |
256 | */ |
257 | { |
258 | XcmsColor *pColor, *pColors_start; |
259 | XcmsColorFormat format; |
260 | Statusint retval_tmp; |
261 | Statusint retval = XcmsSuccess1; |
262 | unsigned int iColors; |
263 | unsigned int nBatch; |
264 | |
265 | /* |
266 | * Convert array of mixed color specifications in batches of |
267 | * contiguous formats to the target format |
268 | */ |
269 | iColors = 0; |
270 | while (iColors < nColors) { |
271 | /* |
272 | * Find contiguous array of color specifications with the |
273 | * same format |
274 | */ |
275 | pColor = pColors_start = pColors_in_out + iColors; |
276 | format = pColors_start->format; |
277 | nBatch = 0; |
278 | while (iColors < nColors && pColor->format == format) { |
279 | pColor++; |
280 | nBatch++; |
281 | iColors++; |
282 | } |
283 | if (format != targetFormat) { |
284 | /* |
285 | * Need to convert this batch from current format to target format. |
286 | */ |
287 | if (XCMS_DI_ID(format)(!((format) & (XcmsColorFormat)0x80000000)) && (format_flag & DI_FORMAT0x02) && |
288 | XCMS_DI_ID(targetFormat)(!((targetFormat) & (XcmsColorFormat)0x80000000))) { |
289 | /* |
290 | * DI->DI |
291 | * |
292 | * Format of interest is Device-Independent, |
293 | * This batch contains Device-Independent specifications, and |
294 | * the Target format is Device-Independent. |
295 | */ |
296 | retval_tmp = _XcmsDIConvertColors(ccc, pColors_start, pWhitePt, |
297 | nBatch, targetFormat); |
298 | } else if (XCMS_DD_ID(format)((format) & (XcmsColorFormat)0x80000000) && (format_flag & DD_FORMAT0x01) && |
299 | (targetFormat == XcmsCIEXYZFormat(XcmsColorFormat)0x00000001)) { |
300 | /* |
301 | * DD->CIEXYZ |
302 | * |
303 | * Format of interest is Device-Dependent, |
304 | * This batch contains Device-Dependent specifications, and |
305 | * the Target format is CIEXYZ. |
306 | * |
307 | * Since DD->CIEXYZ we can use NULL instead of pCompressed. |
308 | */ |
309 | if ((ccc->whitePtAdjProc != NULL((void*)0)) && !_XcmsEqualWhitePts(ccc, |
310 | pWhitePt, ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt))) { |
311 | /* |
312 | * Need to call WhiteAdjustProc (Screen White Point to |
313 | * White Point). |
314 | */ |
315 | retval_tmp = (*ccc->whitePtAdjProc)(ccc, |
316 | ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt), pWhitePt, |
317 | XcmsCIEXYZFormat(XcmsColorFormat)0x00000001, pColors_start, nBatch, |
318 | (Boolint *)NULL((void*)0)); |
319 | } else { |
320 | retval_tmp = _XcmsDDConvertColors(ccc, pColors_start, |
321 | nBatch, XcmsCIEXYZFormat(XcmsColorFormat)0x00000001, (Boolint *)NULL((void*)0)); |
322 | } |
323 | } else if (XCMS_DD_ID(format)((format) & (XcmsColorFormat)0x80000000) && (format_flag & DD_FORMAT0x01) && |
324 | XCMS_DD_ID(targetFormat)((targetFormat) & (XcmsColorFormat)0x80000000)) { |
325 | /* |
326 | * DD->DD(not CIEXYZ) |
327 | * |
328 | * Format of interest is Device-Dependent, |
329 | * This batch contains Device-Dependent specifications, and |
330 | * the Target format is Device-Dependent and not CIEXYZ. |
331 | */ |
332 | retval_tmp = _XcmsDDConvertColors(ccc, pColors_start, nBatch, |
333 | targetFormat, (Boolint *)NULL((void*)0)); |
334 | } else { |
335 | /* |
336 | * This routine is called for the wrong reason. |
337 | */ |
338 | return(XcmsFailure0); |
339 | } |
340 | if (retval_tmp == XcmsFailure0) { |
341 | return(XcmsFailure0); |
342 | } |
343 | retval = MAX(retval, retval_tmp)((retval) > (retval_tmp) ? (retval) : (retval_tmp)); |
344 | } |
345 | } |
346 | return(retval); |
347 | } |
348 | |
349 | |
350 | /************************************************************************ |
351 | * * |
352 | * API PRIVATE ROUTINES * |
353 | * * |
354 | ************************************************************************/ |
355 | |
356 | /* |
357 | * NAME |
358 | * _XcmsEqualWhitePts |
359 | * |
360 | * SYNOPSIS |
361 | */ |
362 | int |
363 | _XcmsEqualWhitePts(XcmsCCC ccc, XcmsColor *pWhitePt1, XcmsColor *pWhitePt2) |
364 | /* |
365 | * DESCRIPTION |
366 | * |
367 | * RETURNS |
368 | * Returns 0 if not equal; otherwise 1. |
369 | * |
370 | */ |
371 | { |
372 | XcmsColor tmp1, tmp2; |
373 | |
374 | memcpy((char *)&tmp1, (char *)pWhitePt1, sizeof(XcmsColor)); |
375 | memcpy((char *)&tmp2, (char *)pWhitePt2, sizeof(XcmsColor)); |
376 | |
377 | if (tmp1.format != XcmsCIEXYZFormat(XcmsColorFormat)0x00000001) { |
378 | if (_XcmsDIConvertColors(ccc, &tmp1, (XcmsColor *) NULL((void*)0), 1, |
379 | XcmsCIEXYZFormat(XcmsColorFormat)0x00000001)==0) { |
380 | return(0); |
381 | } |
382 | } |
383 | |
384 | if (tmp2.format != XcmsCIEXYZFormat(XcmsColorFormat)0x00000001) { |
385 | if (_XcmsDIConvertColors(ccc, &tmp2, (XcmsColor *) NULL((void*)0), 1, |
386 | XcmsCIEXYZFormat(XcmsColorFormat)0x00000001)==0) { |
387 | return(0); |
388 | } |
389 | } |
390 | |
391 | return (EqualCIEXYZ(&tmp1, &tmp2)); |
392 | } |
393 | |
394 | |
395 | /* |
396 | * NAME |
397 | * _XcmsDIConvertColors - Convert XcmsColor structures |
398 | * |
399 | * SYNOPSIS |
400 | */ |
401 | Statusint |
402 | _XcmsDIConvertColors( |
403 | XcmsCCC ccc, |
404 | XcmsColor *pColors_in_out, |
405 | XcmsColor *pWhitePt, |
406 | unsigned int nColors, |
407 | XcmsColorFormat newFormat) |
408 | /* |
409 | * DESCRIPTION |
410 | * Convert XcmsColor structures to another Device-Independent |
411 | * form. |
412 | * |
413 | * Here are some assumptions that this routine makes: |
414 | * 1. The calling routine has already checked if |
415 | * pColors_in_out->format == newFormat, therefore |
416 | * there is no need to check again here. |
417 | * 2. The calling routine has already checked nColors, |
418 | * therefore this routine assumes nColors > 0. |
419 | * 3. The calling routine may want to convert only between |
420 | * CIExyY <-> CIEXYZ <-> CIEuvY |
421 | * therefore, this routine allows pWhitePt to equal NULL. |
422 | * |
423 | * |
424 | * RETURNS |
425 | * XcmsFailure if failed, |
426 | * XcmsSuccess if succeeded. |
427 | * |
428 | */ |
429 | { |
430 | XcmsColorSpace *pFrom, *pTo; |
431 | XcmsDIConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ; |
432 | XcmsDIConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ; |
433 | XcmsDIConversionProc *to_CIEXYZ_stop, *from_CIEXYZ_start; |
434 | XcmsDIConversionProc *tmp; |
435 | |
436 | /* |
437 | * Allow pWhitePt to equal NULL. This appropriate when converting |
438 | * anywhere between: |
439 | * CIExyY <-> CIEXYZ <-> CIEuvY |
440 | */ |
441 | |
442 | if (pColors_in_out == NULL((void*)0) || |
443 | !ValidDIColorSpaceID(pColors_in_out->format) || |
444 | !ValidDIColorSpaceID(newFormat)) { |
445 | return(XcmsFailure0); |
446 | } |
447 | |
448 | /* |
449 | * Get a handle on the function list for the current specification format |
450 | */ |
451 | if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format)) |
452 | == NULL((void*)0)) { |
453 | return(XcmsFailure0); |
454 | } |
455 | |
456 | /* |
457 | * Get a handle on the function list for the new specification format |
458 | */ |
459 | if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL((void*)0)) { |
460 | return(XcmsFailure0); |
461 | } |
462 | |
463 | src_to_CIEXYZ = pFrom->to_CIEXYZ; |
464 | src_from_CIEXYZ = pFrom->from_CIEXYZ; |
465 | dest_to_CIEXYZ = pTo->to_CIEXYZ; |
466 | dest_from_CIEXYZ = pTo->from_CIEXYZ; |
467 | |
468 | if (pTo->inverse_flag && pFrom->inverse_flag) { |
469 | /* |
470 | * Find common function pointers |
471 | */ |
472 | for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){ |
473 | for (tmp = dest_to_CIEXYZ; *tmp; tmp++) { |
474 | if (*to_CIEXYZ_stop == *tmp) { |
475 | goto Continue; |
476 | } |
477 | } |
478 | } |
479 | |
480 | Continue: |
481 | |
482 | /* |
483 | * Execute the functions to CIEXYZ, stopping short as necessary |
484 | */ |
485 | while (src_to_CIEXYZ != to_CIEXYZ_stop) { |
486 | if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out, |
487 | nColors) == XcmsFailure0) { |
488 | return(XcmsFailure0); |
489 | } |
490 | } |
491 | |
492 | /* |
493 | * Determine where to start on the from_CIEXYZ path. |
494 | */ |
495 | from_CIEXYZ_start = dest_from_CIEXYZ; |
496 | tmp = src_from_CIEXYZ; |
497 | while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL((void*)0))) { |
498 | from_CIEXYZ_start++; |
499 | tmp++; |
500 | } |
501 | |
502 | } else { |
503 | /* |
504 | * The function in at least one of the Color Spaces are not |
505 | * complementary, i.e., |
506 | * for an i, 0 <= i < n elements |
507 | * from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i] |
508 | * |
509 | * Execute the functions all the way to CIEXYZ |
510 | */ |
511 | while (*src_to_CIEXYZ) { |
512 | if ((*src_to_CIEXYZ++)(ccc, pWhitePt, pColors_in_out, |
513 | nColors) == XcmsFailure0) { |
514 | return(XcmsFailure0); |
515 | } |
516 | } |
517 | |
518 | /* |
519 | * Determine where to start on the from_CIEXYZ path. |
520 | */ |
521 | from_CIEXYZ_start = dest_from_CIEXYZ; |
522 | } |
523 | |
524 | |
525 | /* |
526 | * Execute the functions from CIEXYZ. |
527 | */ |
528 | while (*from_CIEXYZ_start) { |
529 | if ((*from_CIEXYZ_start++)(ccc, pWhitePt, pColors_in_out, |
530 | nColors) == XcmsFailure0) { |
531 | return(XcmsFailure0); |
532 | } |
533 | } |
534 | |
535 | return(XcmsSuccess1); |
536 | } |
537 | |
538 | |
539 | /* |
540 | * NAME |
541 | * _XcmsDDConvertColors - Convert XcmsColor structures |
542 | * |
543 | * SYNOPSIS |
544 | */ |
545 | Statusint |
546 | _XcmsDDConvertColors( |
547 | XcmsCCC ccc, |
548 | XcmsColor *pColors_in_out, |
549 | unsigned int nColors, |
550 | XcmsColorFormat newFormat, |
551 | Boolint *pCompressed) |
552 | /* |
553 | * DESCRIPTION |
554 | * Convert XcmsColor structures: |
555 | * |
556 | * 1. From CIEXYZ to Device-Dependent formats (typically RGB and |
557 | * RGBi), |
558 | * or |
559 | * 2. Between Device-Dependent formats (typically RGB and RGBi). |
560 | * |
561 | * Assumes that these specifications have already been white point |
562 | * adjusted if necessary from Client White Point to Screen |
563 | * White Point. Therefore, the white point now associated |
564 | * with the specifications is the Screen White Point. |
565 | * |
566 | * pCompressed may be NULL. If so this indicates that the |
567 | * calling routine is not interested in knowing exactly which |
568 | * color was compressed, if any. |
569 | * |
570 | * |
571 | * RETURNS |
572 | * XcmsFailure if failed, |
573 | * XcmsSuccess if none of the color specifications were |
574 | * compressed in the conversion process |
575 | * XcmsSuccessWithCompression if at least one of the |
576 | * color specifications were compressed in the |
577 | * conversion process. |
578 | * |
579 | */ |
580 | { |
581 | XcmsColorSpace *pFrom, *pTo; |
582 | XcmsDDConversionProc *src_to_CIEXYZ, *src_from_CIEXYZ; |
583 | XcmsDDConversionProc *dest_to_CIEXYZ, *dest_from_CIEXYZ; |
584 | XcmsDDConversionProc *from_CIEXYZ_start, *to_CIEXYZ_stop; |
585 | XcmsDDConversionProc *tmp; |
586 | int retval; |
587 | int hasCompressed = 0; |
588 | |
589 | if (ccc == NULL((void*)0) || pColors_in_out == NULL((void*)0)) { |
590 | return(XcmsFailure0); |
591 | } |
592 | |
593 | if (nColors == 0 || pColors_in_out->format == newFormat) { |
594 | /* do nothing */ |
595 | return(XcmsSuccess1); |
596 | } |
597 | |
598 | if (((XcmsFunctionSet *)ccc->pPerScrnInfo->functionSet) == NULL((void*)0)) { |
599 | return(XcmsFailure0); /* hmm, an internal error? */ |
600 | } |
601 | |
602 | /* |
603 | * Its ok if pColors_in_out->format == XcmsCIEXYZFormat |
604 | * or |
605 | * if newFormat == XcmsCIEXYZFormat |
606 | */ |
607 | if ( !( ValidDDColorSpaceID(ccc, pColors_in_out->format) |
608 | || |
609 | (pColors_in_out->format == XcmsCIEXYZFormat(XcmsColorFormat)0x00000001)) |
610 | || |
611 | !(ValidDDColorSpaceID(ccc, newFormat) |
612 | || |
613 | newFormat == XcmsCIEXYZFormat(XcmsColorFormat)0x00000001)) { |
614 | return(XcmsFailure0); |
615 | } |
616 | |
617 | if ((pFrom = ColorSpaceOfID(ccc, pColors_in_out->format)) == NULL((void*)0)){ |
618 | return(XcmsFailure0); |
619 | } |
620 | |
621 | if ((pTo = ColorSpaceOfID(ccc, newFormat)) == NULL((void*)0)) { |
622 | return(XcmsFailure0); |
623 | } |
624 | |
625 | src_to_CIEXYZ = (XcmsDDConversionProc *)pFrom->to_CIEXYZ; |
626 | src_from_CIEXYZ = (XcmsDDConversionProc *)pFrom->from_CIEXYZ; |
627 | dest_to_CIEXYZ = (XcmsDDConversionProc *)pTo->to_CIEXYZ; |
628 | dest_from_CIEXYZ = (XcmsDDConversionProc *)pTo->from_CIEXYZ; |
629 | |
630 | if (pTo->inverse_flag && pFrom->inverse_flag) { |
631 | /* |
632 | * Find common function pointers |
633 | */ |
634 | for (to_CIEXYZ_stop = src_to_CIEXYZ; *to_CIEXYZ_stop; to_CIEXYZ_stop++){ |
635 | for (tmp = dest_to_CIEXYZ; *tmp; tmp++) { |
636 | if (*to_CIEXYZ_stop == *tmp) { |
637 | goto Continue; |
638 | } |
639 | } |
640 | } |
641 | Continue: |
642 | |
643 | /* |
644 | * Execute the functions |
645 | */ |
646 | while (src_to_CIEXYZ != to_CIEXYZ_stop) { |
647 | retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors, |
648 | pCompressed); |
649 | if (retval == XcmsFailure0) { |
650 | return(XcmsFailure0); |
651 | } |
652 | hasCompressed |= (retval == XcmsSuccessWithCompression2); |
653 | } |
654 | |
655 | /* |
656 | * Determine where to start on the from_CIEXYZ path. |
657 | */ |
658 | from_CIEXYZ_start = dest_from_CIEXYZ; |
659 | tmp = src_from_CIEXYZ; |
660 | while ((*from_CIEXYZ_start == *tmp) && (*from_CIEXYZ_start != NULL((void*)0))) { |
661 | from_CIEXYZ_start++; |
662 | tmp++; |
663 | } |
664 | |
665 | } else { |
666 | /* |
667 | * The function in at least one of the Color Spaces are not |
668 | * complementary, i.e., |
669 | * for an i, 0 <= i < n elements |
670 | * from_CIEXYZ[i] is not the inverse of to_CIEXYZ[i] |
671 | * |
672 | * Execute the functions all the way to CIEXYZ |
673 | */ |
674 | while (*src_to_CIEXYZ) { |
675 | retval = (*src_to_CIEXYZ++)(ccc, pColors_in_out, nColors, |
676 | pCompressed); |
677 | if (retval == XcmsFailure0) { |
678 | return(XcmsFailure0); |
679 | } |
680 | hasCompressed |= (retval == XcmsSuccessWithCompression2); |
681 | } |
682 | |
683 | /* |
684 | * Determine where to start on the from_CIEXYZ path. |
685 | */ |
686 | from_CIEXYZ_start = dest_from_CIEXYZ; |
687 | } |
688 | |
689 | while (*from_CIEXYZ_start) { |
690 | retval = (*from_CIEXYZ_start++)(ccc, pColors_in_out, nColors, |
691 | pCompressed); |
692 | if (retval == XcmsFailure0) { |
693 | return(XcmsFailure0); |
694 | } |
695 | hasCompressed |= (retval == XcmsSuccessWithCompression2); |
696 | } |
697 | |
698 | return(hasCompressed ? XcmsSuccessWithCompression2 : XcmsSuccess1); |
699 | } |
700 | |
701 | |
702 | /************************************************************************ |
703 | * * |
704 | * PUBLIC ROUTINES * |
705 | * * |
706 | ************************************************************************/ |
707 | |
708 | /* |
709 | * NAME |
710 | * XcmsConvertColors - Convert XcmsColor structures |
711 | * |
712 | * SYNOPSIS |
713 | */ |
714 | Statusint |
715 | XcmsConvertColors( |
716 | XcmsCCC ccc, |
717 | XcmsColor *pColors_in_out, |
718 | unsigned int nColors, |
719 | XcmsColorFormat targetFormat, |
720 | Boolint *pCompressed) |
721 | /* |
722 | * DESCRIPTION |
723 | * Convert XcmsColor structures to another format |
724 | * |
725 | * RETURNS |
726 | * XcmsFailure if failed, |
727 | * XcmsSuccess if succeeded without gamut compression, |
728 | * XcmsSuccessWithCompression if succeeded with gamut |
729 | * compression. |
730 | * |
731 | */ |
732 | { |
733 | XcmsColor clientWhitePt; |
734 | XcmsColor Color1; |
735 | XcmsColor *pColors_tmp; |
736 | int callWhiteAdjustProc = 0; |
737 | XcmsColorFormat format; |
738 | Statusint retval; |
739 | unsigned char contents_flag = 0x00; |
740 | unsigned int iColors; |
741 | |
742 | if (ccc == NULL((void*)0) || pColors_in_out == NULL((void*)0) || |
743 | !(ValidDIColorSpaceID(targetFormat) || |
744 | ValidDDColorSpaceID(ccc, targetFormat))) { |
745 | return(XcmsFailure0); |
746 | } |
747 | |
748 | /* |
749 | * Check formats in color specification array |
750 | */ |
751 | format = pColors_in_out->format; |
752 | for (pColors_tmp = pColors_in_out, iColors = nColors; iColors; pColors_tmp++, iColors--) { |
753 | if (!(ValidDIColorSpaceID(pColors_tmp->format) || |
754 | ValidDDColorSpaceID(ccc, pColors_tmp->format))) { |
755 | return(XcmsFailure0); |
756 | } |
757 | if (XCMS_DI_ID(pColors_tmp->format)(!((pColors_tmp->format) & (XcmsColorFormat)0x80000000 ))) { |
758 | contents_flag |= DI_FORMAT0x02; |
759 | } else { |
760 | contents_flag |= DD_FORMAT0x01; |
761 | } |
762 | if (pColors_tmp->format != format) { |
763 | contents_flag |= MIX_FORMAT0x04; |
764 | } |
765 | } |
766 | |
767 | /* |
768 | * Check if we need the Client White Point. |
769 | */ |
770 | if ((contents_flag & DI_FORMAT0x02) || XCMS_DI_ID(targetFormat)(!((targetFormat) & (XcmsColorFormat)0x80000000))) { |
771 | /* To proceed, we need to get the Client White Point */ |
772 | memcpy((char *)&clientWhitePt, (char *)&ccc->clientWhitePt, |
773 | sizeof(XcmsColor)); |
774 | if (clientWhitePt.format == XcmsUndefinedFormat(XcmsColorFormat)0x00000000) { |
775 | /* |
776 | * Client White Point is undefined, therefore set to the Screen |
777 | * White Point. |
778 | * Since Client White Point == Screen White Point, WhiteAdjustProc |
779 | * is not called. |
780 | */ |
781 | memcpy((char *)&clientWhitePt, |
782 | (char *)&ccc->pPerScrnInfo->screenWhitePt, |
783 | sizeof(XcmsColor)); |
784 | } else if ((ccc->whitePtAdjProc != NULL((void*)0)) && !_XcmsEqualWhitePts(ccc, |
785 | &clientWhitePt, ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt))) { |
786 | /* |
787 | * Client White Point != Screen White Point, and WhiteAdjustProc |
788 | * is not NULL, therefore, will need to call it when |
789 | * converting between DI and DD specifications. |
790 | */ |
791 | callWhiteAdjustProc = 1; |
792 | } |
793 | } |
794 | |
795 | /* |
796 | * Make copy of array of color specifications |
797 | */ |
798 | if (nColors > 1) { |
799 | pColors_tmp = (XcmsColor *) Xmalloc(nColors * sizeof(XcmsColor))malloc(((nColors * sizeof(XcmsColor)) == 0 ? 1 : (nColors * sizeof (XcmsColor)))); |
800 | } else { |
801 | pColors_tmp = &Color1; |
802 | } |
803 | memcpy((char *)pColors_tmp, (char *)pColors_in_out, |
804 | nColors * sizeof(XcmsColor)); |
805 | |
806 | /* |
807 | * zero out pCompressed |
808 | */ |
809 | if (pCompressed) { |
810 | bzero((char *)pCompressed, nColors * sizeof(Bool))memset((char *)pCompressed,0,nColors * sizeof(int)); |
811 | } |
812 | |
813 | if (contents_flag == DD_FORMAT0x01 || contents_flag == DI_FORMAT0x02) { |
814 | /* |
815 | * ENTIRE ARRAY IS IN ONE FORMAT. |
816 | */ |
817 | if (XCMS_DI_ID(format)(!((format) & (XcmsColorFormat)0x80000000)) && XCMS_DI_ID(targetFormat)(!((targetFormat) & (XcmsColorFormat)0x80000000))) { |
818 | /* |
819 | * DI-to-DI only conversion |
820 | */ |
821 | retval = _XcmsDIConvertColors(ccc, pColors_tmp, |
822 | &clientWhitePt, nColors, targetFormat); |
823 | } else if (XCMS_DD_ID(format)((format) & (XcmsColorFormat)0x80000000) && XCMS_DD_ID(targetFormat)((targetFormat) & (XcmsColorFormat)0x80000000)) { |
824 | /* |
825 | * DD-to-DD only conversion |
826 | * Since DD->DD there will be no compressed thus we can |
827 | * pass NULL instead of pCompressed. |
828 | */ |
829 | retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, |
830 | targetFormat, (Boolint *)NULL((void*)0)); |
831 | } else { |
832 | /* |
833 | * Otherwise we have: |
834 | * 1. Device-Independent to Device-Dependent Conversion |
835 | * OR |
836 | * 2. Device-Dependent to Device-Independent Conversion |
837 | * |
838 | * We need to go from oldFormat -> CIEXYZ -> targetFormat |
839 | * adjusting for white points as necessary. |
840 | */ |
841 | |
842 | if (XCMS_DI_ID(format)(!((format) & (XcmsColorFormat)0x80000000))) { |
843 | /* |
844 | * 1. Device-Independent to Device-Dependent Conversion |
845 | */ |
846 | if (callWhiteAdjustProc) { |
847 | /* |
848 | * White Point Adjustment |
849 | * Client White Point to Screen White Point |
850 | */ |
851 | retval = (*ccc->whitePtAdjProc)(ccc, &clientWhitePt, |
852 | ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt), targetFormat, |
853 | pColors_tmp, nColors, pCompressed); |
854 | } else { |
855 | if (_XcmsDIConvertColors(ccc, pColors_tmp, |
856 | &clientWhitePt, nColors, XcmsCIEXYZFormat(XcmsColorFormat)0x00000001) |
857 | == XcmsFailure0) { |
858 | goto Failure; |
859 | } |
860 | retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, |
861 | targetFormat, pCompressed); |
862 | } |
863 | } else { |
864 | /* |
865 | * 2. Device-Dependent to Device-Independent Conversion |
866 | */ |
867 | if (callWhiteAdjustProc) { |
868 | /* |
869 | * White Point Adjustment |
870 | * Screen White Point to Client White Point |
871 | */ |
872 | retval = (*ccc->whitePtAdjProc)(ccc, |
873 | ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt), &clientWhitePt, |
874 | targetFormat, pColors_tmp, nColors, pCompressed); |
875 | } else { |
876 | /* |
877 | * Since DD->CIEXYZ, no compression takes place therefore |
878 | * we can pass NULL instead of pCompressed. |
879 | */ |
880 | if (_XcmsDDConvertColors(ccc, pColors_tmp, nColors, |
881 | XcmsCIEXYZFormat(XcmsColorFormat)0x00000001, (Boolint *)NULL((void*)0)) == XcmsFailure0) { |
882 | goto Failure; |
883 | } |
884 | retval = _XcmsDIConvertColors(ccc, pColors_tmp, |
885 | &clientWhitePt, nColors, targetFormat); |
886 | } |
887 | } |
888 | } |
889 | } else { |
890 | /* |
891 | * ARRAY HAS MIXED FORMATS. |
892 | */ |
893 | if ((contents_flag == (DI_FORMAT0x02 | MIX_FORMAT0x04)) && |
894 | XCMS_DI_ID(targetFormat)(!((targetFormat) & (XcmsColorFormat)0x80000000))) { |
895 | /* |
896 | * Convert from DI to DI in batches of contiguous formats |
897 | * |
898 | * Because DI->DI, WhiteAdjustProc not called. |
899 | */ |
900 | retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, |
901 | nColors, targetFormat, (unsigned char)DI_FORMAT0x02); |
902 | } else if ((contents_flag == (DD_FORMAT0x01 | MIX_FORMAT0x04)) && |
903 | XCMS_DD_ID(targetFormat)((targetFormat) & (XcmsColorFormat)0x80000000)) { |
904 | /* |
905 | * Convert from DD to DD in batches of contiguous formats |
906 | * |
907 | * Because DD->DD, WhiteAdjustProc not called. |
908 | */ |
909 | retval = ConvertMixedColors(ccc, pColors_tmp, |
910 | (XcmsColor *)NULL((void*)0), nColors, targetFormat, |
911 | (unsigned char)DD_FORMAT0x01); |
912 | } else if (XCMS_DI_ID(targetFormat)(!((targetFormat) & (XcmsColorFormat)0x80000000))) { |
913 | /* |
914 | * We need to convert from DI-to-DI and DD-to-DI, therefore |
915 | * 1. convert DD specifications to CIEXYZ, then |
916 | * 2. convert all in batches to the target DI format. |
917 | * |
918 | * Note that ConvertMixedColors will call WhiteAdjustProc |
919 | * as necessary. |
920 | */ |
921 | |
922 | /* |
923 | * Convert only DD specifications in batches of contiguous formats |
924 | * to CIEXYZ |
925 | * |
926 | * Since DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc |
927 | * if required. |
928 | */ |
929 | retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, |
Value stored to 'retval' is never read | |
930 | nColors, XcmsCIEXYZFormat(XcmsColorFormat)0x00000001, (unsigned char)DD_FORMAT0x01); |
931 | |
932 | /* |
933 | * Because at this point we may have a mix of DI formats |
934 | * (e.g., CIEXYZ, CIELuv) we must convert the specs to the |
935 | * target DI format in batches of contiguous source formats. |
936 | */ |
937 | retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, |
938 | nColors, targetFormat, (unsigned char)DI_FORMAT0x02); |
939 | } else { |
940 | /* |
941 | * We need to convert from DI-to-DD and DD-to-DD, therefore |
942 | * 1. convert DI specifications to CIEXYZ, then |
943 | * 2. convert all to the DD target format. |
944 | * |
945 | * This allows white point adjustment and gamut compression |
946 | * to be applied to all the color specifications in one |
947 | * swoop if those functions do in fact modify the entire |
948 | * group of color specifications. |
949 | */ |
950 | |
951 | /* |
952 | * Convert in batches to CIEXYZ |
953 | * |
954 | * If DD->CIEXYZ, ConvertMixedColors will apply WhiteAdjustProc |
955 | * if required. |
956 | */ |
957 | if ((retval = ConvertMixedColors(ccc, pColors_tmp, &clientWhitePt, |
958 | nColors, XcmsCIEXYZFormat(XcmsColorFormat)0x00000001, |
959 | (unsigned char)(DI_FORMAT0x02 | DD_FORMAT0x01))) == XcmsFailure0) { |
960 | goto Failure; |
961 | } |
962 | |
963 | /* |
964 | * Convert all specifications (now in CIEXYZ format) to |
965 | * the target DD format. |
966 | * Since CIEXYZ->DD, compression MAY take place therefore |
967 | * we must pass pCompressed. |
968 | * Note that WhiteAdjustProc must be used if necessary. |
969 | */ |
970 | if (callWhiteAdjustProc) { |
971 | /* |
972 | * White Point Adjustment |
973 | * Client White Point to Screen White Point |
974 | */ |
975 | retval = (*ccc->whitePtAdjProc)(ccc, |
976 | &clientWhitePt, ScreenWhitePointOfCCC(ccc)(&(ccc)->pPerScrnInfo->screenWhitePt), |
977 | targetFormat, pColors_tmp, nColors, pCompressed); |
978 | } else { |
979 | retval = _XcmsDDConvertColors(ccc, pColors_tmp, nColors, |
980 | targetFormat, pCompressed); |
981 | } |
982 | } |
983 | } |
984 | |
985 | if (retval != XcmsFailure0) { |
986 | memcpy((char *)pColors_in_out, (char *)pColors_tmp, |
987 | nColors * sizeof(XcmsColor)); |
988 | } |
989 | if (nColors > 1) { |
990 | Xfree((char *)pColors_tmp)free(((char *)pColors_tmp)); |
991 | } |
992 | return(retval); |
993 | |
994 | Failure: |
995 | if (nColors > 1) { |
996 | Xfree((char *)pColors_tmp)free(((char *)pColors_tmp)); |
997 | } |
998 | return(XcmsFailure0); |
999 | } |
1000 | |
1001 | |
1002 | /* |
1003 | * NAME |
1004 | * XcmsRegFormatOfPrefix |
1005 | * |
1006 | * SYNOPSIS |
1007 | */ |
1008 | XcmsColorFormat |
1009 | _XcmsRegFormatOfPrefix( |
1010 | _Xconstconst char *prefix) |
1011 | /* |
1012 | * DESCRIPTION |
1013 | * Returns a color space ID associated with the specified |
1014 | * X Consortium registered color space prefix. |
1015 | * |
1016 | * RETURNS |
1017 | * The color space ID if found; |
1018 | * otherwise NULL. |
1019 | */ |
1020 | { |
1021 | XcmsRegColorSpaceEntry *pEntry = _XcmsRegColorSpaces; |
1022 | |
1023 | while (pEntry->prefix != NULL((void*)0)) { |
1024 | if (strcmp(prefix, pEntry->prefix) == 0) { |
1025 | return(pEntry->id); |
1026 | } |
1027 | pEntry++; |
1028 | } |
1029 | return(XcmsUndefinedFormat(XcmsColorFormat)0x00000000); |
1030 | } |