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