1#include "mupdf/fitz.h"
2
3#include <math.h>
4
5/* Fast color transforms */
6
7static void gray_to_gray(fz_context *ctx, fz_color_converter *cc, const float *gray, float *xyz)
8{
9 xyz[0] = gray[0];
10}
11
12static void gray_to_rgb(fz_context *ctx, fz_color_converter *cc, const float *gray, float *rgb)
13{
14 rgb[0] = gray[0];
15 rgb[1] = gray[0];
16 rgb[2] = gray[0];
17}
18
19static void rgb_to_gray(fz_context *ctx, fz_color_converter *cc, const float *rgb, float *gray)
20{
21 gray[0] = rgb[0] * 0.3f + rgb[1] * 0.59f + rgb[2] * 0.11f;
22}
23
24static void bgr_to_gray(fz_context *ctx, fz_color_converter *cc, const float *bgr, float *gray)
25{
26 gray[0] = bgr[0] * 0.11f + bgr[1] * 0.59f + bgr[2] * 0.3f;
27}
28
29static void rgb_to_rgb(fz_context *ctx, fz_color_converter *cc, const float *rgb, float *xyz)
30{
31 xyz[0] = rgb[0];
32 xyz[1] = rgb[1];
33 xyz[2] = rgb[2];
34}
35
36static void rgb_to_bgr(fz_context *ctx, fz_color_converter *cc, const float *rgb, float *bgr)
37{
38 bgr[0] = rgb[2];
39 bgr[1] = rgb[1];
40 bgr[2] = rgb[0];
41}
42
43static void cmyk_to_cmyk(fz_context *ctx, fz_color_converter *cc, const float *cmyk, float *xyz)
44{
45 xyz[0] = cmyk[0];
46 xyz[1] = cmyk[1];
47 xyz[2] = cmyk[2];
48 xyz[3] = cmyk[3];
49}
50
51static void gray_to_cmyk(fz_context *ctx, fz_color_converter *cc, const float *gray, float *cmyk)
52{
53 cmyk[0] = 0;
54 cmyk[1] = 0;
55 cmyk[2] = 0;
56 cmyk[3] = 1 - gray[0];
57}
58
59static void cmyk_to_gray(fz_context *ctx, fz_color_converter *cc, const float *cmyk, float *gray)
60{
61 float c = cmyk[0] * 0.3f;
62 float m = cmyk[1] * 0.59f;
63 float y = cmyk[2] * 0.11f;
64 gray[0] = 1 - fz_min(c + m + y + cmyk[3], 1);
65}
66
67static void rgb_to_cmyk(fz_context *ctx, fz_color_converter *cc, const float *rgb, float *cmyk)
68{
69 float c, m, y, k;
70 c = 1 - rgb[0];
71 m = 1 - rgb[1];
72 y = 1 - rgb[2];
73 k = fz_min(c, fz_min(m, y));
74 cmyk[0] = c - k;
75 cmyk[1] = m - k;
76 cmyk[2] = y - k;
77 cmyk[3] = k;
78}
79
80static void bgr_to_cmyk(fz_context *ctx, fz_color_converter *cc, const float *bgr, float *cmyk)
81{
82 float c, m, y, k;
83 c = 1 - bgr[2];
84 m = 1 - bgr[1];
85 y = 1 - bgr[0];
86 k = fz_min(c, fz_min(m, y));
87 cmyk[0] = c - k;
88 cmyk[1] = m - k;
89 cmyk[2] = y - k;
90 cmyk[3] = k;
91}
92
93static void cmyk_to_rgb(fz_context *ctx, fz_color_converter *cc, const float *cmyk, float *rgb)
94{
95 rgb[0] = 1 - fz_min(1, cmyk[0] + cmyk[3]);
96 rgb[1] = 1 - fz_min(1, cmyk[1] + cmyk[3]);
97 rgb[2] = 1 - fz_min(1, cmyk[2] + cmyk[3]);
98}
99
100static void cmyk_to_bgr(fz_context *ctx, fz_color_converter *cc, const float *cmyk, float *bgr)
101{
102 bgr[0] = 1 - fz_min(cmyk[2] + cmyk[3], 1);
103 bgr[1] = 1 - fz_min(cmyk[1] + cmyk[3], 1);
104 bgr[2] = 1 - fz_min(cmyk[0] + cmyk[3], 1);
105}
106
107static inline float fung(float x)
108{
109 if (x >= 6.0f / 29.0f)
110 return x * x * x;
111 return (108.0f / 841.0f) * (x - (4.0f / 29.0f));
112}
113
114static void lab_to_rgb(fz_context *ctx, fz_color_converter *cc, const float *lab, float *rgb)
115{
116 /* input is in range (0..100, -128..127, -128..127) not (0..1, 0..1, 0..1) */
117 float lstar, astar, bstar, l, m, n, x, y, z, r, g, b;
118 lstar = lab[0];
119 astar = lab[1];
120 bstar = lab[2];
121 m = (lstar + 16) / 116;
122 l = m + astar / 500;
123 n = m - bstar / 200;
124 x = fung(l);
125 y = fung(m);
126 z = fung(n);
127 r = (3.240449f * x + -1.537136f * y + -0.498531f * z) * 0.830026f;
128 g = (-0.969265f * x + 1.876011f * y + 0.041556f * z) * 1.05452f;
129 b = (0.055643f * x + -0.204026f * y + 1.057229f * z) * 1.1003f;
130 rgb[0] = sqrtf(fz_clamp(r, 0, 1));
131 rgb[1] = sqrtf(fz_clamp(g, 0, 1));
132 rgb[2] = sqrtf(fz_clamp(b, 0, 1));
133}
134
135static void lab_to_gray(fz_context *ctx, fz_color_converter *cc, const float *lab, float *gray)
136{
137 gray[0] = lab[0] / 100;
138}
139
140static void lab_to_bgr(fz_context *ctx, fz_color_converter *cc, const float *lab, float *bgr)
141{
142 float rgb[3];
143 lab_to_rgb(ctx, cc, lab, rgb);
144 rgb_to_bgr(ctx, cc, rgb, bgr);
145}
146
147static void lab_to_cmyk(fz_context *ctx, fz_color_converter *cc, const float *lab, float *cmyk)
148{
149 float rgb[3];
150 lab_to_rgb(ctx, cc, lab, rgb);
151 rgb_to_cmyk(ctx, cc, rgb, cmyk);
152}
153
154fz_color_convert_fn *
155fz_lookup_fast_color_converter(fz_context *ctx, fz_colorspace *ss, fz_colorspace *ds)
156{
157 int stype = ss->type;
158 int dtype = ds->type;
159
160 if (stype == FZ_COLORSPACE_GRAY)
161 {
162 if (dtype == FZ_COLORSPACE_GRAY) return gray_to_gray;
163 if (dtype == FZ_COLORSPACE_RGB) return gray_to_rgb;
164 if (dtype == FZ_COLORSPACE_BGR) return gray_to_rgb;
165 if (dtype == FZ_COLORSPACE_CMYK) return gray_to_cmyk;
166 }
167
168 else if (stype == FZ_COLORSPACE_RGB)
169 {
170 if (dtype == FZ_COLORSPACE_GRAY) return rgb_to_gray;
171 if (dtype == FZ_COLORSPACE_RGB) return rgb_to_rgb;
172 if (dtype == FZ_COLORSPACE_BGR) return rgb_to_bgr;
173 if (dtype == FZ_COLORSPACE_CMYK) return rgb_to_cmyk;
174 }
175
176 else if (stype == FZ_COLORSPACE_BGR)
177 {
178 if (dtype == FZ_COLORSPACE_GRAY) return bgr_to_gray;
179 if (dtype == FZ_COLORSPACE_RGB) return rgb_to_bgr;
180 if (dtype == FZ_COLORSPACE_BGR) return rgb_to_rgb;
181 if (dtype == FZ_COLORSPACE_CMYK) return bgr_to_cmyk;
182 }
183
184 else if (stype == FZ_COLORSPACE_CMYK)
185 {
186 if (dtype == FZ_COLORSPACE_GRAY) return cmyk_to_gray;
187 if (dtype == FZ_COLORSPACE_RGB) return cmyk_to_rgb;
188 if (dtype == FZ_COLORSPACE_BGR) return cmyk_to_bgr;
189 if (dtype == FZ_COLORSPACE_CMYK) return cmyk_to_cmyk;
190 }
191
192 else if (stype == FZ_COLORSPACE_LAB)
193 {
194 if (dtype == FZ_COLORSPACE_GRAY) return lab_to_gray;
195 if (dtype == FZ_COLORSPACE_RGB) return lab_to_rgb;
196 if (dtype == FZ_COLORSPACE_BGR) return lab_to_bgr;
197 if (dtype == FZ_COLORSPACE_CMYK) return lab_to_cmyk;
198 }
199
200 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find color converter");
201}
202
203/* Fast pixmap color conversions */
204
205static void fast_gray_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
206{
207 unsigned char *s = src->samples;
208 unsigned char *d = dst->samples;
209 size_t w = src->w;
210 int h = src->h;
211 int sn = src->n;
212 int ss = src->s;
213 int sa = src->alpha;
214 int dn = dst->n;
215 int ds = dst->s;
216 int da = dst->alpha;
217 ptrdiff_t d_line_inc = dst->stride - w * dn;
218 ptrdiff_t s_line_inc = src->stride - w * sn;
219
220 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
221 if (copy_spots && ss != ds)
222 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
223 if (!da && sa)
224 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
225
226 if ((int)w < 0 || h < 0)
227 return;
228
229 if (d_line_inc == 0 && s_line_inc == 0)
230 {
231 w *= h;
232 h = 1;
233 }
234
235 if (ss == 0 && ds == 0)
236 {
237 /* Common, no spots case */
238 if (da)
239 {
240 if (sa)
241 {
242 while (h--)
243 {
244 size_t ww = w;
245 while (ww--)
246 {
247 d[0] = s[0];
248 d[1] = s[0];
249 d[2] = s[0];
250 d[3] = s[1];
251 s += 2;
252 d += 4;
253 }
254 d += d_line_inc;
255 s += s_line_inc;
256 }
257 }
258 else
259 {
260 while (h--)
261 {
262 size_t ww = w;
263 while (ww--)
264 {
265 d[0] = s[0];
266 d[1] = s[0];
267 d[2] = s[0];
268 d[3] = 255;
269 s++;
270 d += 4;
271 }
272 d += d_line_inc;
273 s += s_line_inc;
274 }
275 }
276 }
277 else
278 {
279 while (h--)
280 {
281 size_t ww = w;
282 while (ww--)
283 {
284 d[0] = s[0];
285 d[1] = s[0];
286 d[2] = s[0];
287 s++;
288 d += 3;
289 }
290 d += d_line_inc;
291 s += s_line_inc;
292 }
293 }
294 }
295 else if (copy_spots)
296 {
297 /* Slower, spots capable version */
298 int i;
299 while (h--)
300 {
301 size_t ww = w;
302 while (ww--)
303 {
304 d[0] = s[0];
305 d[1] = s[0];
306 d[2] = s[0];
307 s += 1;
308 d += 3;
309 for (i=ss; i > 0; i--)
310 *d++ = *s++;
311 if (da)
312 *d++ = sa ? *s++ : 255;
313 }
314 d += d_line_inc;
315 s += s_line_inc;
316 }
317 }
318 else
319 {
320 while (h--)
321 {
322 size_t ww = w;
323 while (ww--)
324 {
325 d[0] = s[0];
326 d[1] = s[0];
327 d[2] = s[0];
328 s += sn;
329 d += dn;
330 if (da)
331 d[-1] = sa ? s[-1] : 255;
332 }
333 d += d_line_inc;
334 s += s_line_inc;
335 }
336 }
337}
338
339static void fast_gray_to_cmyk(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
340{
341 unsigned char *s = src->samples;
342 unsigned char *d = dst->samples;
343 size_t w = src->w;
344 int h = src->h;
345 int sn = src->n;
346 int ss = src->s;
347 int sa = src->alpha;
348 int dn = dst->n;
349 int ds = dst->s;
350 int da = dst->alpha;
351 ptrdiff_t d_line_inc = dst->stride - w * dn;
352 ptrdiff_t s_line_inc = src->stride - w * sn;
353 int k, g;
354 int a = 255;
355 int i;
356
357 if (copy_spots && ss != ds)
358 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
359
360 if ((int)w < 0 || h < 0)
361 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
362
363 while (h--)
364 {
365 size_t ww = w;
366 while (ww--)
367 {
368 g = s[0];
369
370 if (sa)
371 {
372 a = s[1+ss];
373 g = fz_div255(g, a);
374 }
375
376 k = 255 - g;
377
378 if (da)
379 {
380 *d++ = 0;
381 *d++ = 0;
382 *d++ = 0;
383 *d++ = fz_mul255(k, a);
384 }
385 else
386 {
387 *d++ = 0;
388 *d++ = 0;
389 *d++ = 0;
390 *d++ = k;
391 }
392
393 if (copy_spots)
394 {
395 s += 1;
396 for (i=ss; i > 0; --i)
397 *d++ = *s++;
398 s += sa;
399 }
400 else
401 {
402 s += 1 + ss + sa;
403 d += ds;
404 }
405
406 if (da)
407 {
408 *d++ = a;
409 }
410 }
411 d += d_line_inc;
412 s += s_line_inc;
413 }
414}
415
416static void fast_rgb_to_gray(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
417{
418 unsigned char *s = src->samples;
419 unsigned char *d = dst->samples;
420 size_t w = src->w;
421 int h = src->h;
422 int sn = src->n;
423 int ss = src->s;
424 int sa = src->alpha;
425 int dn = dst->n;
426 int ds = dst->s;
427 int da = dst->alpha;
428 ptrdiff_t d_line_inc = dst->stride - w * dn;
429 ptrdiff_t s_line_inc = src->stride - w * sn;
430
431 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
432 if (copy_spots && ss != ds)
433 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
434 if (!da && sa)
435 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
436
437 if ((int)w < 0 || h < 0)
438 return;
439
440 if (d_line_inc == 0 && s_line_inc == 0)
441 {
442 w *= h;
443 h = 1;
444 }
445
446 if (ss == 0 && ds == 0)
447 {
448 /* Common, no spots case */
449 if (da)
450 {
451 if (sa)
452 {
453 while (h--)
454 {
455 size_t ww = w;
456 while (ww--)
457 {
458 d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
459 d[1] = s[3];
460 s += 4;
461 d += 2;
462 }
463 d += d_line_inc;
464 s += s_line_inc;
465 }
466 }
467 else
468 {
469 while (h--)
470 {
471 size_t ww = w;
472 while (ww--)
473 {
474 d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
475 d[1] = 255;
476 s += 3;
477 d += 2;
478 }
479 d += d_line_inc;
480 s += s_line_inc;
481 }
482 }
483 }
484 else
485 {
486 while (h--)
487 {
488 size_t ww = w;
489 while (ww--)
490 {
491 d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
492 s += 3;
493 d++;
494 }
495 d += d_line_inc;
496 s += s_line_inc;
497 }
498 }
499 }
500 else if (copy_spots)
501 {
502 /* Slower, spots capable version */
503 int i;
504 while (h--)
505 {
506 size_t ww = w;
507 while (ww--)
508 {
509 d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
510 s += 3;
511 d++;
512 for (i=ss; i > 0; i--)
513 *d++ = *s++;
514 if (da)
515 *d++ = sa ? *s++ : 255;
516 }
517 d += d_line_inc;
518 s += s_line_inc;
519 }
520 }
521 else
522 {
523 while (h--)
524 {
525 size_t ww = w;
526 while (ww--)
527 {
528 d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
529 s += sn;
530 d += dn;
531 if (da)
532 d[-1] = sa ? s[-1] : 255;
533 }
534 d += d_line_inc;
535 s += s_line_inc;
536 }
537 }
538}
539
540static void fast_bgr_to_gray(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
541{
542 unsigned char *s = src->samples;
543 unsigned char *d = dst->samples;
544 size_t w = src->w;
545 int h = src->h;
546 int sn = src->n;
547 int ss = src->s;
548 int sa = src->alpha;
549 int dn = dst->n;
550 int ds = dst->s;
551 int da = dst->alpha;
552 ptrdiff_t d_line_inc = dst->stride - w * dn;
553 ptrdiff_t s_line_inc = src->stride - w * sn;
554
555 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
556 if (copy_spots && ss != ds)
557 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
558 if (!da && sa)
559 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
560
561 if ((int)w < 0 || h < 0)
562 return;
563
564 if (d_line_inc == 0 && s_line_inc == 0)
565 {
566 w *= h;
567 h = 1;
568 }
569
570 if (ss == 0 && ds == 0)
571 {
572 /* Common, no spots case */
573 if (da)
574 {
575 if (sa)
576 {
577 while (h--)
578 {
579 size_t ww = w;
580 while (ww--)
581 {
582 d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
583 d[1] = s[3];
584 s += 4;
585 d += 2;
586 }
587 d += d_line_inc;
588 s += s_line_inc;
589 }
590 }
591 else
592 {
593 while (h--)
594 {
595 size_t ww = w;
596 while (ww--)
597 {
598 d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
599 d[1] = 255;
600 s += 3;
601 d += 2;
602 }
603 d += d_line_inc;
604 s += s_line_inc;
605 }
606 }
607 }
608 else
609 {
610 int si = 3 + src->alpha;
611
612 while (h--)
613 {
614 size_t ww = w;
615 while (ww--)
616 {
617 d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
618 s += si;
619 d++;
620 }
621 d += d_line_inc;
622 s += s_line_inc;
623 }
624 }
625 }
626 else if (copy_spots)
627 {
628 /* Slower, spots capable version */
629 while (h--)
630 {
631 int i;
632 size_t ww = w;
633 while (ww--)
634 {
635 d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
636 s += 3;
637 d++;
638 for (i=ss; i > 0; i--)
639 *d++ = *s++;
640 if (da)
641 *d++ = sa ? *s++ : 255;
642 }
643 d += d_line_inc;
644 s += s_line_inc;
645 }
646 }
647 else
648 {
649 /* Slower, spots capable version */
650 while (h--)
651 {
652 size_t ww = w;
653 while (ww--)
654 {
655 d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
656 s += sn;
657 d += dn;
658 if (da)
659 d[-1] = sa ? s[-1] : 255;
660 }
661 d += d_line_inc;
662 s += s_line_inc;
663 }
664 }
665}
666
667static void fast_rgb_to_cmyk(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
668{
669 unsigned char *s = src->samples;
670 unsigned char *d = dst->samples;
671 size_t w = src->w;
672 int h = src->h;
673 int sn = src->n;
674 int ss = src->s;
675 int sa = src->alpha;
676 int dn = dst->n;
677 int ds = dst->s;
678 int da = dst->alpha;
679 ptrdiff_t d_line_inc = dst->stride - w * dn;
680 ptrdiff_t s_line_inc = src->stride - w * sn;
681 int c, m, y, k, r, g, b;
682 int a = 255;
683 int i;
684
685 if (copy_spots && ss != ds)
686 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
687
688 if ((int)w < 0 || h < 0)
689 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
690
691 while (h--)
692 {
693 size_t ww = w;
694 while (ww--)
695 {
696 r = s[0];
697 g = s[1];
698 b = s[2];
699
700 if (sa)
701 {
702 a = s[3+ss];
703 r = fz_div255(r, a);
704 g = fz_div255(g, a);
705 b = fz_div255(b, a);
706 }
707
708 c = 255 - r;
709 m = 255 - g;
710 y = 255 - b;
711 k = fz_mini(c, fz_mini(m, y));
712 c = c - k;
713 m = m - k;
714 y = y - k;
715
716 if (da)
717 {
718 *d++ = fz_mul255(c, a);
719 *d++ = fz_mul255(m, a);
720 *d++ = fz_mul255(y, a);
721 *d++ = fz_mul255(k, a);
722 }
723 else
724 {
725 *d++ = c;
726 *d++ = m;
727 *d++ = y;
728 *d++ = k;
729 }
730
731 if (copy_spots)
732 {
733 s += 3;
734 for (i=ss; i > 0; --i)
735 *d++ = *s++;
736 s += sa;
737 }
738 else
739 {
740 s += 3 + ss + sa;
741 d += ds;
742 }
743
744 if (da)
745 {
746 *d++ = a;
747 }
748 }
749 d += d_line_inc;
750 s += s_line_inc;
751 }
752}
753
754static void fast_bgr_to_cmyk(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
755{
756 unsigned char *s = src->samples;
757 unsigned char *d = dst->samples;
758 size_t w = src->w;
759 int h = src->h;
760 int sn = src->n;
761 int ss = src->s;
762 int sa = src->alpha;
763 int dn = dst->n;
764 int ds = dst->s;
765 int da = dst->alpha;
766 ptrdiff_t d_line_inc = dst->stride - w * dn;
767 ptrdiff_t s_line_inc = src->stride - w * sn;
768 int c, m, y, k, r, g, b;
769 int a = 255;
770 int i;
771
772 if (copy_spots && ss != ds)
773 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
774
775 if ((int)w < 0 || h < 0)
776 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
777
778 while (h--)
779 {
780 size_t ww = w;
781 while (ww--)
782 {
783 b = s[0];
784 g = s[1];
785 r = s[2];
786
787 if (sa)
788 {
789 a = s[3+ss];
790 r = fz_div255(r, a);
791 g = fz_div255(g, a);
792 b = fz_div255(b, a);
793 }
794
795 c = 255 - r;
796 m = 255 - g;
797 y = 255 - b;
798 k = fz_mini(c, fz_mini(m, y));
799 c = c - k;
800 m = m - k;
801 y = y - k;
802
803 if (da)
804 {
805 *d++ = fz_mul255(c, a);
806 *d++ = fz_mul255(m, a);
807 *d++ = fz_mul255(y, a);
808 *d++ = fz_mul255(k, a);
809 }
810 else
811 {
812 *d++ = c;
813 *d++ = m;
814 *d++ = y;
815 *d++ = k;
816 }
817
818 if (copy_spots)
819 {
820 s += 3;
821 for (i=ss; i > 0; --i)
822 *d++ = *s++;
823 s += sa;
824 }
825 else
826 {
827 s += 3 + ss + sa;
828 d += ds;
829 }
830
831 if (da)
832 {
833 *d++ = a;
834 }
835 }
836 d += d_line_inc;
837 s += s_line_inc;
838 }
839}
840
841static void fast_cmyk_to_gray(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
842{
843 unsigned char *s = src->samples;
844 unsigned char *d = dst->samples;
845 size_t w = src->w;
846 int h = src->h;
847 int sn = src->n;
848 int ss = src->s;
849 int sa = src->alpha;
850 int dn = dst->n;
851 int ds = dst->s;
852 int da = dst->alpha;
853 ptrdiff_t d_line_inc = dst->stride - w * dn;
854 ptrdiff_t s_line_inc = src->stride - w * sn;
855 int c, m, y, k, g;
856 int a = 255;
857 int i;
858
859 if (copy_spots && ss != ds)
860 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
861
862 if ((int)w < 0 || h < 0)
863 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
864
865 while (h--)
866 {
867 size_t ww = w;
868 while (ww--)
869 {
870 c = s[0];
871 m = s[1];
872 y = s[2];
873 k = s[3];
874
875 if (sa)
876 {
877 a = s[4+ss];
878 c = fz_div255(c, a);
879 m = fz_div255(m, a);
880 y = fz_div255(y, a);
881 k = fz_div255(k, a);
882 }
883
884 g = 255 - fz_mini(c + m + y + k, 255);
885
886 if (da)
887 {
888 *d++ = fz_mul255(g, a);
889 }
890 else
891 {
892 *d++ = g;
893 }
894
895 if (copy_spots)
896 {
897 s += 4;
898 for (i=ss; i > 0; --i)
899 *d++ = *s++;
900 s += sa;
901 }
902 else
903 {
904 s += 4 + ss + sa;
905 d += ds;
906 }
907
908 if (da)
909 {
910 *d++ = a;
911 }
912 }
913 d += d_line_inc;
914 s += s_line_inc;
915 }
916}
917
918static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
919{
920 unsigned char *s = src->samples;
921 unsigned char *d = dst->samples;
922 size_t w = src->w;
923 int h = src->h;
924 int sn = src->n;
925 int ss = src->s;
926 int sa = src->alpha;
927 int dn = dst->n;
928 int ds = dst->s;
929 int da = dst->alpha;
930 ptrdiff_t d_line_inc = dst->stride - w * dn;
931 ptrdiff_t s_line_inc = src->stride - w * sn;
932 int c, m, y, k, r, g, b;
933 int a = 255;
934 int i;
935
936 if (copy_spots && ss != ds)
937 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
938
939 if ((int)w < 0 || h < 0)
940 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
941
942 while (h--)
943 {
944 size_t ww = w;
945 while (ww--)
946 {
947 c = s[0];
948 m = s[1];
949 y = s[2];
950 k = s[3];
951
952 if (sa)
953 {
954 a = s[4+ss];
955 c = fz_div255(c, a);
956 m = fz_div255(m, a);
957 y = fz_div255(y, a);
958 k = fz_div255(k, a);
959 }
960
961 r = 255 - fz_mini(c + k, 255);
962 g = 255 - fz_mini(m + k, 255);
963 b = 255 - fz_mini(y + k, 255);
964
965 if (da)
966 {
967 *d++ = fz_mul255(r, a);
968 *d++ = fz_mul255(g, a);
969 *d++ = fz_mul255(b, a);
970 }
971 else
972 {
973 *d++ = r;
974 *d++ = g;
975 *d++ = b;
976 }
977
978 if (copy_spots)
979 {
980 s += 4;
981 for (i=ss; i > 0; --i)
982 *d++ = *s++;
983 s += sa;
984 }
985 else
986 {
987 s += 4 + ss + sa;
988 d += ds;
989 }
990
991 if (da)
992 {
993 *d++ = a;
994 }
995 }
996 d += d_line_inc;
997 s += s_line_inc;
998 }
999}
1000
1001static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1002{
1003 unsigned char *s = src->samples;
1004 unsigned char *d = dst->samples;
1005 size_t w = src->w;
1006 int h = src->h;
1007 int sn = src->n;
1008 int ss = src->s;
1009 int sa = src->alpha;
1010 int dn = dst->n;
1011 int ds = dst->s;
1012 int da = dst->alpha;
1013 ptrdiff_t d_line_inc = dst->stride - w * dn;
1014 ptrdiff_t s_line_inc = src->stride - w * sn;
1015 int c, m, y, k, r, g, b;
1016 int a = 255;
1017 int i;
1018
1019 if (copy_spots && ss != ds)
1020 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
1021
1022 if ((int)w < 0 || h < 0)
1023 fz_throw(ctx, FZ_ERROR_GENERIC, "integer overflow");
1024
1025 while (h--)
1026 {
1027 size_t ww = w;
1028 while (ww--)
1029 {
1030 c = s[0];
1031 m = s[1];
1032 y = s[2];
1033 k = s[3];
1034
1035 if (sa)
1036 {
1037 a = s[4+ss];
1038 c = fz_div255(c, a);
1039 m = fz_div255(m, a);
1040 y = fz_div255(y, a);
1041 k = fz_div255(k, a);
1042 }
1043
1044 r = 255 - fz_mini(c + k, 255);
1045 g = 255 - fz_mini(m + k, 255);
1046 b = 255 - fz_mini(y + k, 255);
1047
1048 if (da)
1049 {
1050 *d++ = fz_mul255(b, a);
1051 *d++ = fz_mul255(g, a);
1052 *d++ = fz_mul255(r, a);
1053 }
1054 else
1055 {
1056 *d++ = b;
1057 *d++ = g;
1058 *d++ = r;
1059 }
1060
1061 if (copy_spots)
1062 {
1063 s += 4;
1064 for (i=ss; i > 0; --i)
1065 *d++ = *s++;
1066 s += sa;
1067 }
1068 else
1069 {
1070 s += 4 + ss + sa;
1071 d += ds;
1072 }
1073
1074 if (da)
1075 {
1076 *d++ = a;
1077 }
1078 }
1079 d += d_line_inc;
1080 s += s_line_inc;
1081 }
1082}
1083
1084static void fast_rgb_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1085{
1086 unsigned char *s = src->samples;
1087 unsigned char *d = dst->samples;
1088 size_t w = src->w;
1089 int h = src->h;
1090 int sn = src->n;
1091 int ss = src->s;
1092 int sa = src->alpha;
1093 int dn = dst->n;
1094 int ds = dst->s;
1095 int da = dst->alpha;
1096 ptrdiff_t d_line_inc = dst->stride - w * dn;
1097 ptrdiff_t s_line_inc = src->stride - w * sn;
1098
1099 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
1100 if (copy_spots && ss != ds)
1101 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
1102 if (!da && sa)
1103 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
1104
1105 if ((int)w < 0 || h < 0)
1106 return;
1107
1108 if (d_line_inc == 0 && s_line_inc == 0)
1109 {
1110 w *= h;
1111 h = 1;
1112 }
1113
1114 if (ss == 0 && ds == 0)
1115 {
1116 /* Common, no spots case */
1117 if (da)
1118 {
1119 if (sa)
1120 {
1121 while (h--)
1122 {
1123 size_t ww = w;
1124 while (ww--)
1125 {
1126 d[0] = s[2];
1127 d[1] = s[1];
1128 d[2] = s[0];
1129 d[3] = s[3];
1130 s += 4;
1131 d += 4;
1132 }
1133 }
1134 }
1135 else
1136 {
1137 while (h--)
1138 {
1139 size_t ww = w;
1140 while (ww--)
1141 {
1142 d[0] = s[2];
1143 d[1] = s[1];
1144 d[2] = s[0];
1145 d[3] = 255;
1146 s += 3;
1147 d += 4;
1148 }
1149 }
1150 }
1151 }
1152 else
1153 {
1154 while (h--)
1155 {
1156 size_t ww = w;
1157 while (ww--)
1158 {
1159 d[0] = s[2];
1160 d[1] = s[1];
1161 d[2] = s[0];
1162 s += 3;
1163 d += 3;
1164 }
1165 }
1166 }
1167 }
1168 else if (copy_spots)
1169 {
1170 /* Slower, spots capable version */
1171 while (h--)
1172 {
1173 int i;
1174 size_t ww = w;
1175 while (ww--)
1176 {
1177 d[0] = s[2];
1178 d[1] = s[1];
1179 d[2] = s[0];
1180 s += 3;
1181 d += 3;
1182 for (i=ss; i > 0; i--)
1183 *d++ = *s++;
1184 if (da)
1185 *d++ = sa ? *s++ : 255;
1186 }
1187 d += d_line_inc;
1188 s += s_line_inc;
1189 }
1190 }
1191 else
1192 {
1193 while (h--)
1194 {
1195 size_t ww = w;
1196 while (ww--)
1197 {
1198 d[0] = s[2];
1199 d[1] = s[1];
1200 d[2] = s[0];
1201 s += sn;
1202 d += dn;
1203 if (da)
1204 d[-1] = sa ? s[-1] : 255;
1205 }
1206 d += d_line_inc;
1207 s += s_line_inc;
1208 }
1209 }
1210}
1211
1212static void fast_gray_to_gray(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1213{
1214 unsigned char *s = src->samples;
1215 unsigned char *d = dst->samples;
1216 size_t w = src->w;
1217 int h = src->h;
1218 int sn = src->n;
1219 int ss = src->s;
1220 int sa = src->alpha;
1221 int dn = dst->n;
1222 int ds = dst->s;
1223 int da = dst->alpha;
1224 ptrdiff_t d_line_inc = dst->stride - w * dn;
1225 ptrdiff_t s_line_inc = src->stride - w * sn;
1226
1227 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
1228 if (copy_spots && ss != ds)
1229 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
1230 if (!da && sa)
1231 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
1232
1233 if ((int)w < 0 || h < 0)
1234 return;
1235
1236 if (d_line_inc == 0 && s_line_inc == 0)
1237 {
1238 w *= h;
1239 h = 1;
1240 }
1241
1242 if (ss == 0 && ds == 0)
1243 {
1244 /* Common, no spots case */
1245 if (da)
1246 {
1247 if (sa)
1248 {
1249 while (h--)
1250 {
1251 size_t ww = w;
1252 while (ww--)
1253 {
1254 d[0] = s[0];
1255 d[1] = s[1];
1256 s += 2;
1257 d += 2;
1258 }
1259 }
1260 }
1261 else
1262 {
1263 while (h--)
1264 {
1265 size_t ww = w;
1266 while (ww--)
1267 {
1268 d[0] = s[0];
1269 d[1] = 255;
1270 s += 1;
1271 d += 2;
1272 }
1273 }
1274 }
1275 }
1276 else
1277 {
1278 while (h--)
1279 {
1280 size_t ww = w;
1281 while (ww--)
1282 {
1283 d[0] = s[0];
1284 s += 1;
1285 d += 1;
1286 }
1287 }
1288 }
1289 }
1290 else if (copy_spots)
1291 {
1292 /* Slower, spots capable version */
1293 while (h--)
1294 {
1295 int i;
1296 size_t ww = w;
1297 while (ww--)
1298 {
1299 d[0] = s[0];
1300 s += 1;
1301 d += 1;
1302 for (i=ss; i > 0; i--)
1303 *d++ = *s++;
1304 if (da)
1305 *d++ = sa ? *s++ : 255;
1306 }
1307 d += d_line_inc;
1308 s += s_line_inc;
1309 }
1310 }
1311 else
1312 {
1313 while (h--)
1314 {
1315 size_t ww = w;
1316 while (ww--)
1317 {
1318 d[0] = s[0];
1319 s += sn;
1320 d += dn;
1321 if (da)
1322 d[-1] = sa ? s[-1] : 255;
1323 }
1324 d += d_line_inc;
1325 s += s_line_inc;
1326 }
1327 }
1328}
1329
1330static void fast_rgb_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1331{
1332 unsigned char *s = src->samples;
1333 unsigned char *d = dst->samples;
1334 size_t w = src->w;
1335 int h = src->h;
1336 int sn = src->n;
1337 int ss = src->s;
1338 int sa = src->alpha;
1339 int dn = dst->n;
1340 int ds = dst->s;
1341 int da = dst->alpha;
1342 ptrdiff_t d_line_inc = dst->stride - w * dn;
1343 ptrdiff_t s_line_inc = src->stride - w * sn;
1344
1345 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
1346 if (copy_spots && ss != ds)
1347 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
1348 if (!da && sa)
1349 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
1350
1351 if ((int)w < 0 || h < 0)
1352 return;
1353
1354 if (d_line_inc == 0 && s_line_inc == 0)
1355 {
1356 w *= h;
1357 h = 1;
1358 }
1359
1360 if (ss == 0 && ds == 0)
1361 {
1362 /* Common, no spots case */
1363 if (da)
1364 {
1365 if (sa)
1366 {
1367 while (h--)
1368 {
1369 size_t ww = w;
1370 while (ww--)
1371 {
1372 d[0] = s[0];
1373 d[1] = s[1];
1374 d[2] = s[2];
1375 d[3] = s[3];
1376 s += 4;
1377 d += 4;
1378 }
1379 }
1380 }
1381 else
1382 {
1383 while (h--)
1384 {
1385 size_t ww = w;
1386 while (ww--)
1387 {
1388 d[0] = s[0];
1389 d[1] = s[1];
1390 d[2] = s[2];
1391 d[3] = 255;
1392 s += 3;
1393 d += 4;
1394 }
1395 }
1396 }
1397 }
1398 else
1399 {
1400 while (h--)
1401 {
1402 size_t ww = w;
1403 while (ww--)
1404 {
1405 d[0] = s[0];
1406 d[1] = s[1];
1407 d[2] = s[2];
1408 s += 3;
1409 d += 3;
1410 }
1411 }
1412 }
1413 }
1414 else if (copy_spots)
1415 {
1416 /* Slower, spots capable version */
1417 while (h--)
1418 {
1419 int i;
1420 size_t ww = w;
1421 while (ww--)
1422 {
1423 d[0] = s[0];
1424 d[1] = s[1];
1425 d[2] = s[2];
1426 s += 3;
1427 d += 3;
1428 for (i=ss; i > 0; i--)
1429 *d++ = *s++;
1430 if (da)
1431 *d++ = sa ? *s++ : 255;
1432 }
1433 d += d_line_inc;
1434 s += s_line_inc;
1435 }
1436 }
1437 else
1438 {
1439 while (h--)
1440 {
1441 size_t ww = w;
1442 while (ww--)
1443 {
1444 d[0] = s[0];
1445 d[1] = s[1];
1446 d[2] = s[2];
1447 s += sn;
1448 d += dn;
1449 if (da)
1450 d[-1] = sa ? s[-1] : 255;
1451 }
1452 d += d_line_inc;
1453 s += s_line_inc;
1454 }
1455 }
1456}
1457
1458static void fast_cmyk_to_cmyk(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1459{
1460 unsigned char *s = src->samples;
1461 unsigned char *d = dst->samples;
1462 size_t w = src->w;
1463 int h = src->h;
1464 int sn = src->n;
1465 int ss = src->s;
1466 int sa = src->alpha;
1467 int dn = dst->n;
1468 int ds = dst->s;
1469 int da = dst->alpha;
1470 ptrdiff_t d_line_inc = dst->stride - w * dn;
1471 ptrdiff_t s_line_inc = src->stride - w * sn;
1472
1473 /* If copying spots, they must match, and we can never drop alpha (but we can invent it) */
1474 if (copy_spots && ss != ds)
1475 fz_throw(ctx, FZ_ERROR_GENERIC, "incompatible number of spots when converting pixmap");
1476 if (!da && sa)
1477 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot drop alpha when converting pixmap");
1478
1479 if ((int)w < 0 || h < 0)
1480 return;
1481
1482 if (d_line_inc == 0 && s_line_inc == 0)
1483 {
1484 w *= h;
1485 h = 1;
1486 }
1487
1488 if (ss == 0 && ds == 0)
1489 {
1490 /* Common, no spots case */
1491 if (da)
1492 {
1493 if (sa)
1494 {
1495 while (h--)
1496 {
1497 size_t ww = w;
1498 while (ww--)
1499 {
1500 d[0] = s[0];
1501 d[1] = s[1];
1502 d[2] = s[2];
1503 d[3] = s[3];
1504 d[4] = s[4];
1505 s += 5;
1506 d += 5;
1507 }
1508 }
1509 }
1510 else
1511 {
1512 while (h--)
1513 {
1514 size_t ww = w;
1515 while (ww--)
1516 {
1517 d[0] = s[0];
1518 d[1] = s[1];
1519 d[2] = s[2];
1520 d[3] = s[3];
1521 d[4] = 255;
1522 s += 4;
1523 d += 5;
1524 }
1525 }
1526 }
1527 }
1528 else
1529 {
1530 while (h--)
1531 {
1532 size_t ww = w;
1533 while (ww--)
1534 {
1535 d[0] = s[0];
1536 d[1] = s[1];
1537 d[2] = s[2];
1538 d[3] = s[3];
1539 s += 4;
1540 d += 4;
1541 }
1542 }
1543 }
1544 }
1545 else if (copy_spots)
1546 {
1547 /* Slower, spots capable version */
1548 while (h--)
1549 {
1550 int i;
1551 size_t ww = w;
1552 while (ww--)
1553 {
1554 d[0] = s[0];
1555 d[1] = s[1];
1556 d[2] = s[2];
1557 d[3] = s[3];
1558 s += 4;
1559 d += 4;
1560 for (i=ss; i > 0; i--)
1561 *d++ = *s++;
1562 if (da)
1563 *d++ = sa ? *s++ : 255;
1564 }
1565 d += d_line_inc;
1566 s += s_line_inc;
1567 }
1568 }
1569 else
1570 {
1571 while (h--)
1572 {
1573 size_t ww = w;
1574 while (ww--)
1575 {
1576 d[0] = s[0];
1577 d[1] = s[1];
1578 d[2] = s[2];
1579 d[3] = s[3];
1580 s += sn;
1581 d += dn;
1582 if (da)
1583 d[-1] = sa ? s[-1] : 255;
1584 }
1585 d += d_line_inc;
1586 s += s_line_inc;
1587 }
1588 }
1589}
1590
1591void
1592fz_fast_any_to_alpha(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1593{
1594 if (!src->alpha)
1595 fz_clear_pixmap_with_value(ctx, dst, 255);
1596 else
1597 {
1598 unsigned char *s = src->samples;
1599 unsigned char *d = dst->samples;
1600 size_t w = src->w;
1601 int h = src->h;
1602 int n = src->n;
1603 ptrdiff_t d_line_inc = dst->stride - w * dst->n;
1604 ptrdiff_t s_line_inc = src->stride - w * src->n;
1605
1606 if ((int)w < 0 || h < 0)
1607 return;
1608
1609 if (d_line_inc == 0 && s_line_inc == 0)
1610 {
1611 w *= h;
1612 h = 1;
1613 }
1614
1615 s += n-1;
1616 while (h--)
1617 {
1618 size_t ww = w;
1619 while (ww--)
1620 {
1621 *d++ = *s;
1622 s += n;
1623 }
1624 d += d_line_inc;
1625 s += s_line_inc;
1626 }
1627 }
1628}
1629
1630void
1631fz_convert_fast_pixmap_samples(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst, int copy_spots)
1632{
1633 fz_colorspace *ss = src->colorspace;
1634 fz_colorspace *ds = dst->colorspace;
1635 int dtype = ds ? ds->type : FZ_COLORSPACE_GRAY;
1636 int stype = ss ? ss->type : FZ_COLORSPACE_GRAY;
1637
1638 if (!ds)
1639 {
1640 fz_fast_any_to_alpha(ctx, src, dst, copy_spots);
1641 }
1642
1643 else if (stype == FZ_COLORSPACE_GRAY)
1644 {
1645 if (dtype == FZ_COLORSPACE_GRAY)
1646 fast_gray_to_gray(ctx, src, dst, copy_spots);
1647 else if (dtype == FZ_COLORSPACE_RGB)
1648 fast_gray_to_rgb(ctx, src, dst, copy_spots);
1649 else if (dtype == FZ_COLORSPACE_BGR)
1650 fast_gray_to_rgb(ctx, src, dst, copy_spots);
1651 else if (dtype == FZ_COLORSPACE_CMYK)
1652 fast_gray_to_cmyk(ctx, src, dst, copy_spots);
1653 else
1654 goto slow;
1655 }
1656
1657 else if (stype == FZ_COLORSPACE_RGB)
1658 {
1659 if (dtype == FZ_COLORSPACE_GRAY)
1660 fast_rgb_to_gray(ctx, src, dst, copy_spots);
1661 else if (dtype == FZ_COLORSPACE_RGB)
1662 fast_rgb_to_rgb(ctx, src, dst, copy_spots);
1663 else if (dtype == FZ_COLORSPACE_BGR)
1664 fast_rgb_to_bgr(ctx, src, dst, copy_spots);
1665 else if (dtype == FZ_COLORSPACE_CMYK)
1666 fast_rgb_to_cmyk(ctx, src, dst, copy_spots);
1667 else
1668 goto slow;
1669 }
1670
1671 else if (stype == FZ_COLORSPACE_BGR)
1672 {
1673 if (dtype == FZ_COLORSPACE_GRAY)
1674 fast_bgr_to_gray(ctx, src, dst, copy_spots);
1675 else if (dtype == FZ_COLORSPACE_RGB)
1676 fast_rgb_to_bgr(ctx, src, dst, copy_spots);
1677 else if (dtype == FZ_COLORSPACE_BGR)
1678 fast_rgb_to_rgb(ctx, src, dst, copy_spots);
1679 else if (dtype == FZ_COLORSPACE_CMYK)
1680 fast_bgr_to_cmyk(ctx, src, dst, copy_spots);
1681 else
1682 goto slow;
1683 }
1684
1685 else if (stype == FZ_COLORSPACE_CMYK)
1686 {
1687 if (dtype == FZ_COLORSPACE_GRAY)
1688 fast_cmyk_to_gray(ctx, src, dst, copy_spots);
1689 else if (dtype == FZ_COLORSPACE_RGB)
1690 fast_cmyk_to_rgb(ctx, src, dst, copy_spots);
1691 else if (dtype == FZ_COLORSPACE_BGR)
1692 fast_cmyk_to_bgr(ctx, src, dst, copy_spots);
1693 else if (dtype == FZ_COLORSPACE_CMYK)
1694 fast_cmyk_to_cmyk(ctx, src, dst, copy_spots);
1695 else
1696 goto slow;
1697 }
1698 else
1699 {
1700 goto slow;
1701 }
1702 return;
1703
1704slow:
1705 fz_convert_slow_pixmap_samples(ctx, src, dst, NULL, fz_default_color_params, copy_spots);
1706}
1707