1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % CCCC OOO L OOO RRRR SSSSS PPPP AAA CCCC EEEEE % 7 % C O O L O O R R SS P P A A C E % 8 % C O O L O O RRRR SSS PPPP AAAAA C EEE % 9 % C O O L O O R R SS P A A C E % 10 % CCCC OOO LLLLL OOO R R SSSSS P A A CCCC EEEEE % 11 % % 12 % % 13 % MagickCore Image Colorspace Methods % 14 % % 15 % Software Design % 16 % Cristy % 17 % July 1992 % 18 % % 19 % % 20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % http://www.imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % 37 */ 38 39 /* 41 Include declarations. 42 */ 43 #include "MagickCore/studio.h" 44 #include "MagickCore/attribute.h" 45 #include "MagickCore/property.h" 46 #include "MagickCore/cache.h" 47 #include "MagickCore/cache-private.h" 48 #include "MagickCore/cache-view.h" 49 #include "MagickCore/color.h" 50 #include "MagickCore/color-private.h" 51 #include "MagickCore/colorspace.h" 52 #include "MagickCore/colorspace-private.h" 53 #include "MagickCore/exception.h" 54 #include "MagickCore/exception-private.h" 55 #include "MagickCore/image.h" 56 #include "MagickCore/image-private.h" 57 #include "MagickCore/gem.h" 58 #include "MagickCore/gem-private.h" 59 #include "MagickCore/memory_.h" 60 #include "MagickCore/monitor.h" 61 #include "MagickCore/monitor-private.h" 62 #include "MagickCore/pixel-accessor.h" 63 #include "MagickCore/pixel-private.h" 64 #include "MagickCore/quantize.h" 65 #include "MagickCore/quantum.h" 66 #include "MagickCore/quantum-private.h" 67 #include "MagickCore/resource_.h" 68 #include "MagickCore/string_.h" 69 #include "MagickCore/string-private.h" 70 #include "MagickCore/utility.h" 71 72 /* 74 Typedef declarations. 75 */ 76 typedef struct _TransformPacket 77 { 78 MagickRealType 79 x, 80 y, 81 z; 82 } TransformPacket; 83 84 /* 86 Forward declarations. 87 */ 88 static MagickBooleanType 89 TransformsRGBImage(Image *,ExceptionInfo *); 90 91 /* 93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 94 % % 95 % % 96 % % 97 + s R G B T r a n s f o r m I m a g e % 98 % % 99 % % 100 % % 101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 102 % 103 % sRGBTransformImage() converts the reference image from sRGB to an alternate 104 % colorspace. The transformation matrices are not the standard ones: the 105 % weights are rescaled to normalized the range of the transformed values to 106 % be [0..QuantumRange]. 107 % 108 % The format of the sRGBTransformImage method is: 109 % 110 % MagickBooleanType sRGBTransformImage(Image *image, 111 % const ColorspaceType colorspace,EsceptionInfo *exception) 112 % 113 % A description of each parameter follows: 114 % 115 % o image: the image. 116 % 117 % o colorspace: the colorspace to transform the image to. 118 % 119 % o exception: return any errors or warnings in this structure. 120 % 121 */ 122 123 static inline void ConvertRGBToCMY(const double red,const double green, 124 const double blue,double *cyan,double *magenta,double *yellow) 125 { 126 *cyan=QuantumScale*(QuantumRange-red); 127 *magenta=QuantumScale*(QuantumRange-green); 128 *yellow=QuantumScale*(QuantumRange-blue); 129 } 130 131 static inline void ConvertXYZToLMS(const double x,const double y, 132 const double z,double *L,double *M,double *S) 133 { 134 *L=0.7328*x+0.4296*y-0.1624*z; 135 *M=(-0.7036*x+1.6975*y+0.0061*z); 136 *S=0.0030*x+0.0136*y+0.9834*z; 137 } 138 139 static void ConvertRGBToLMS(const double red,const double green, 140 const double blue,double *L,double *M,double *S) 141 { 142 double 143 X, 144 Y, 145 Z; 146 147 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 148 ConvertXYZToLMS(X,Y,Z,L,M,S); 149 } 150 151 static void ConvertRGBToLab(const double red,const double green, 152 const double blue,double *L,double *a,double *b) 153 { 154 double 155 X, 156 Y, 157 Z; 158 159 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 160 ConvertXYZToLab(X,Y,Z,L,a,b); 161 } 162 163 static void ConvertRGBToLuv(const double red,const double green, 164 const double blue,double *L,double *u,double *v) 165 { 166 double 167 X, 168 Y, 169 Z; 170 171 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 172 ConvertXYZToLuv(X,Y,Z,L,u,v); 173 } 174 175 static void ConvertRGBToxyY(const double red,const double green, 176 const double blue,double *low_x,double *low_y,double *cap_Y) 177 { 178 double 179 X, 180 Y, 181 Z; 182 183 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 184 *low_x=X/(X+Y+Z); 185 *low_y=Y/(X+Y+Z); 186 *cap_Y=Y; 187 } 188 189 static void ConvertRGBToYDbDr(const double red,const double green, 190 const double blue,double *Y,double *Db,double *Dr) 191 { 192 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 193 *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5; 194 *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5; 195 } 196 197 static void ConvertRGBToYIQ(const double red,const double green, 198 const double blue,double *Y,double *I,double *Q) 199 { 200 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 201 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5; 202 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5; 203 } 204 205 static void ConvertRGBToYPbPr(const double red,const double green, 206 const double blue,double *Y,double *Pb,double *Pr) 207 { 208 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 209 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5; 210 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5; 211 } 212 213 static void ConvertRGBToYCbCr(const double red,const double green, 214 const double blue,double *Y,double *Cb,double *Cr) 215 { 216 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr); 217 } 218 219 static void ConvertRGBToYUV(const double red,const double green, 220 const double blue,double *Y,double *U,double *V) 221 { 222 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 223 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5; 224 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5; 225 } 226 227 static MagickBooleanType sRGBTransformImage(Image *image, 228 const ColorspaceType colorspace,ExceptionInfo *exception) 229 { 230 #define sRGBTransformImageTag "RGBTransform/Image" 231 232 CacheView 233 *image_view; 234 235 MagickBooleanType 236 status; 237 238 MagickOffsetType 239 progress; 240 241 PrimaryInfo 242 primary_info; 243 244 register ssize_t 245 i; 246 247 ssize_t 248 y; 249 250 TransformPacket 251 *x_map, 252 *y_map, 253 *z_map; 254 255 assert(image != (Image *) NULL); 256 assert(image->signature == MagickCoreSignature); 257 if (image->debug != MagickFalse) 258 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 259 assert(colorspace != sRGBColorspace); 260 assert(colorspace != TransparentColorspace); 261 assert(colorspace != UndefinedColorspace); 262 status=MagickTrue; 263 progress=0; 264 switch (colorspace) 265 { 266 case CMYKColorspace: 267 { 268 PixelInfo 269 zero; 270 271 /* 272 Convert RGB to CMYK colorspace. 273 */ 274 if (image->storage_class == PseudoClass) 275 { 276 if (SyncImage(image,exception) == MagickFalse) 277 return(MagickFalse); 278 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 279 return(MagickFalse); 280 } 281 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 282 return(MagickFalse); 283 GetPixelInfo(image,&zero); 284 image_view=AcquireAuthenticCacheView(image,exception); 285 #if defined(MAGICKCORE_OPENMP_SUPPORT) 286 #pragma omp parallel for schedule(static,4) shared(status) \ 287 magick_threads(image,image,image->rows,1) 288 #endif 289 for (y=0; y < (ssize_t) image->rows; y++) 290 { 291 MagickBooleanType 292 sync; 293 294 PixelInfo 295 pixel; 296 297 register ssize_t 298 x; 299 300 register Quantum 301 *magick_restrict q; 302 303 if (status == MagickFalse) 304 continue; 305 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 306 exception); 307 if (q == (Quantum *) NULL) 308 { 309 status=MagickFalse; 310 continue; 311 } 312 pixel=zero; 313 for (x=0; x < (ssize_t) image->columns; x++) 314 { 315 GetPixelInfoPixel(image,q,&pixel); 316 ConvertRGBToCMYK(&pixel); 317 SetPixelViaPixelInfo(image,&pixel,q); 318 q+=GetPixelChannels(image); 319 } 320 sync=SyncCacheViewAuthenticPixels(image_view,exception); 321 if (sync == MagickFalse) 322 status=MagickFalse; 323 } 324 image_view=DestroyCacheView(image_view); 325 image->type=image->alpha_trait == UndefinedPixelTrait ? ColorSeparationType : 326 ColorSeparationAlphaType; 327 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 328 return(MagickFalse); 329 return(status); 330 } 331 case GRAYColorspace: 332 { 333 /* 334 Transform image from sRGB to GRAY. 335 */ 336 if (image->storage_class == PseudoClass) 337 { 338 if (SyncImage(image,exception) == MagickFalse) 339 return(MagickFalse); 340 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 341 return(MagickFalse); 342 } 343 image_view=AcquireAuthenticCacheView(image,exception); 344 #if defined(MAGICKCORE_OPENMP_SUPPORT) 345 #pragma omp parallel for schedule(static,4) shared(status) \ 346 magick_threads(image,image,image->rows,1) 347 #endif 348 for (y=0; y < (ssize_t) image->rows; y++) 349 { 350 MagickBooleanType 351 sync; 352 353 register ssize_t 354 x; 355 356 register Quantum 357 *magick_restrict q; 358 359 if (status == MagickFalse) 360 continue; 361 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 362 exception); 363 if (q == (Quantum *) NULL) 364 { 365 status=MagickFalse; 366 continue; 367 } 368 for (x=0; x < (ssize_t) image->columns; x++) 369 { 370 SetPixelGray(image,ClampToQuantum(GetPixelIntensity(image,q)),q); 371 q+=GetPixelChannels(image); 372 } 373 sync=SyncCacheViewAuthenticPixels(image_view,exception); 374 if (sync == MagickFalse) 375 status=MagickFalse; 376 } 377 image_view=DestroyCacheView(image_view); 378 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 379 return(MagickFalse); 380 image->type=GrayscaleType; 381 return(status); 382 } 383 case CMYColorspace: 384 case HCLColorspace: 385 case HCLpColorspace: 386 case HSBColorspace: 387 case HSIColorspace: 388 case HSLColorspace: 389 case HSVColorspace: 390 case HWBColorspace: 391 case LabColorspace: 392 case LCHColorspace: 393 case LCHabColorspace: 394 case LCHuvColorspace: 395 case LMSColorspace: 396 case LuvColorspace: 397 case xyYColorspace: 398 case XYZColorspace: 399 case YCbCrColorspace: 400 case YDbDrColorspace: 401 case YIQColorspace: 402 case YPbPrColorspace: 403 case YUVColorspace: 404 { 405 /* 406 Transform image from sRGB to target colorspace. 407 */ 408 if (image->storage_class == PseudoClass) 409 { 410 if (SyncImage(image,exception) == MagickFalse) 411 return(MagickFalse); 412 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 413 return(MagickFalse); 414 } 415 image_view=AcquireAuthenticCacheView(image,exception); 416 #if defined(MAGICKCORE_OPENMP_SUPPORT) 417 #pragma omp parallel for schedule(static,4) shared(status) \ 418 magick_threads(image,image,image->rows,1) 419 #endif 420 for (y=0; y < (ssize_t) image->rows; y++) 421 { 422 MagickBooleanType 423 sync; 424 425 register ssize_t 426 x; 427 428 register Quantum 429 *magick_restrict q; 430 431 if (status == MagickFalse) 432 continue; 433 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 434 exception); 435 if (q == (Quantum *) NULL) 436 { 437 status=MagickFalse; 438 continue; 439 } 440 for (x=0; x < (ssize_t) image->columns; x++) 441 { 442 double 443 blue, 444 green, 445 red, 446 X, 447 Y, 448 Z; 449 450 red=(double) GetPixelRed(image,q); 451 green=(double) GetPixelGreen(image,q); 452 blue=(double) GetPixelBlue(image,q); 453 switch (colorspace) 454 { 455 case CMYColorspace: 456 { 457 ConvertRGBToCMY(red,green,blue,&X,&Y,&Z); 458 break; 459 } 460 case HCLColorspace: 461 { 462 ConvertRGBToHCL(red,green,blue,&X,&Y,&Z); 463 break; 464 } 465 case HCLpColorspace: 466 { 467 ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z); 468 break; 469 } 470 case HSBColorspace: 471 { 472 ConvertRGBToHSB(red,green,blue,&X,&Y,&Z); 473 break; 474 } 475 case HSIColorspace: 476 { 477 ConvertRGBToHSI(red,green,blue,&X,&Y,&Z); 478 break; 479 } 480 case HSLColorspace: 481 { 482 ConvertRGBToHSL(red,green,blue,&X,&Y,&Z); 483 break; 484 } 485 case HSVColorspace: 486 { 487 ConvertRGBToHSV(red,green,blue,&X,&Y,&Z); 488 break; 489 } 490 case HWBColorspace: 491 { 492 ConvertRGBToHWB(red,green,blue,&X,&Y,&Z); 493 break; 494 } 495 case LabColorspace: 496 { 497 ConvertRGBToLab(red,green,blue,&X,&Y,&Z); 498 break; 499 } 500 case LCHColorspace: 501 case LCHabColorspace: 502 { 503 ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z); 504 break; 505 } 506 case LCHuvColorspace: 507 { 508 ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z); 509 break; 510 } 511 case LMSColorspace: 512 { 513 ConvertRGBToLMS(red,green,blue,&X,&Y,&Z); 514 break; 515 } 516 case LuvColorspace: 517 { 518 ConvertRGBToLuv(red,green,blue,&X,&Y,&Z); 519 break; 520 } 521 case xyYColorspace: 522 { 523 ConvertRGBToxyY(red,green,blue,&X,&Y,&Z); 524 break; 525 } 526 case XYZColorspace: 527 { 528 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 529 break; 530 } 531 case YCbCrColorspace: 532 { 533 ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z); 534 break; 535 } 536 case YDbDrColorspace: 537 { 538 ConvertRGBToYDbDr(red,green,blue,&X,&Y,&Z); 539 break; 540 } 541 case YIQColorspace: 542 { 543 ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z); 544 break; 545 } 546 case YPbPrColorspace: 547 { 548 ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z); 549 break; 550 } 551 case YUVColorspace: 552 { 553 ConvertRGBToYUV(red,green,blue,&X,&Y,&Z); 554 break; 555 } 556 default: 557 { 558 X=QuantumScale*red; 559 Y=QuantumScale*green; 560 Z=QuantumScale*blue; 561 break; 562 } 563 } 564 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q); 565 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q); 566 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q); 567 q+=GetPixelChannels(image); 568 } 569 sync=SyncCacheViewAuthenticPixels(image_view,exception); 570 if (sync == MagickFalse) 571 status=MagickFalse; 572 } 573 image_view=DestroyCacheView(image_view); 574 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 575 return(MagickFalse); 576 return(status); 577 } 578 case LogColorspace: 579 { 580 #define DisplayGamma (1.0/1.7) 581 #define FilmGamma 0.6 582 #define ReferenceBlack 95.0 583 #define ReferenceWhite 685.0 584 585 const char 586 *value; 587 588 double 589 black, 590 density, 591 film_gamma, 592 gamma, 593 reference_black, 594 reference_white; 595 596 Quantum 597 *logmap; 598 599 /* 600 Transform RGB to Log colorspace. 601 */ 602 density=DisplayGamma; 603 gamma=DisplayGamma; 604 value=GetImageProperty(image,"gamma",exception); 605 if (value != (const char *) NULL) 606 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL)); 607 film_gamma=FilmGamma; 608 value=GetImageProperty(image,"film-gamma",exception); 609 if (value != (const char *) NULL) 610 film_gamma=StringToDouble(value,(char **) NULL); 611 reference_black=ReferenceBlack; 612 value=GetImageProperty(image,"reference-black",exception); 613 if (value != (const char *) NULL) 614 reference_black=StringToDouble(value,(char **) NULL); 615 reference_white=ReferenceWhite; 616 value=GetImageProperty(image,"reference-white",exception); 617 if (value != (const char *) NULL) 618 reference_white=StringToDouble(value,(char **) NULL); 619 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL, 620 sizeof(*logmap)); 621 if (logmap == (Quantum *) NULL) 622 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 623 image->filename); 624 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/ 625 film_gamma); 626 #if defined(MAGICKCORE_OPENMP_SUPPORT) 627 #pragma omp parallel for schedule(static,4) \ 628 magick_threads(image,image,1,1) 629 #endif 630 for (i=0; i <= (ssize_t) MaxMap; i++) 631 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+ 632 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/ 633 film_gamma))/1024.0)); 634 image_view=AcquireAuthenticCacheView(image,exception); 635 #if defined(MAGICKCORE_OPENMP_SUPPORT) 636 #pragma omp parallel for schedule(static,4) shared(status) \ 637 magick_threads(image,image,image->rows,1) 638 #endif 639 for (y=0; y < (ssize_t) image->rows; y++) 640 { 641 MagickBooleanType 642 sync; 643 644 register ssize_t 645 x; 646 647 register Quantum 648 *magick_restrict q; 649 650 if (status == MagickFalse) 651 continue; 652 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 653 exception); 654 if (q == (Quantum *) NULL) 655 { 656 status=MagickFalse; 657 continue; 658 } 659 for (x=(ssize_t) image->columns; x != 0; x--) 660 { 661 double 662 blue, 663 green, 664 red; 665 666 red=(double) DecodePixelGamma((MagickRealType) 667 GetPixelRed(image,q)); 668 green=(double) DecodePixelGamma((MagickRealType) 669 GetPixelGreen(image,q)); 670 blue=(double) DecodePixelGamma((MagickRealType) 671 GetPixelBlue(image,q)); 672 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q); 673 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))], 674 q); 675 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q); 676 q+=GetPixelChannels(image); 677 } 678 sync=SyncCacheViewAuthenticPixels(image_view,exception); 679 if (sync == MagickFalse) 680 status=MagickFalse; 681 } 682 image_view=DestroyCacheView(image_view); 683 logmap=(Quantum *) RelinquishMagickMemory(logmap); 684 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 685 return(MagickFalse); 686 return(status); 687 } 688 case RGBColorspace: 689 case scRGBColorspace: 690 { 691 /* 692 Transform image from sRGB to linear RGB. 693 */ 694 if (image->storage_class == PseudoClass) 695 { 696 if (SyncImage(image,exception) == MagickFalse) 697 return(MagickFalse); 698 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 699 return(MagickFalse); 700 } 701 image_view=AcquireAuthenticCacheView(image,exception); 702 #if defined(MAGICKCORE_OPENMP_SUPPORT) 703 #pragma omp parallel for schedule(static,4) shared(status) \ 704 magick_threads(image,image,image->rows,1) 705 #endif 706 for (y=0; y < (ssize_t) image->rows; y++) 707 { 708 MagickBooleanType 709 sync; 710 711 register ssize_t 712 x; 713 714 register Quantum 715 *magick_restrict q; 716 717 if (status == MagickFalse) 718 continue; 719 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 720 exception); 721 if (q == (Quantum *) NULL) 722 { 723 status=MagickFalse; 724 continue; 725 } 726 for (x=0; x < (ssize_t) image->columns; x++) 727 { 728 double 729 blue, 730 green, 731 red; 732 733 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q)); 734 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q)); 735 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q)); 736 SetPixelRed(image,ClampToQuantum(red),q); 737 SetPixelGreen(image,ClampToQuantum(green),q); 738 SetPixelBlue(image,ClampToQuantum(blue),q); 739 q+=GetPixelChannels(image); 740 } 741 sync=SyncCacheViewAuthenticPixels(image_view,exception); 742 if (sync == MagickFalse) 743 status=MagickFalse; 744 } 745 image_view=DestroyCacheView(image_view); 746 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 747 return(MagickFalse); 748 return(status); 749 } 750 default: 751 break; 752 } 753 /* 754 Allocate the tables. 755 */ 756 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 757 sizeof(*x_map)); 758 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 759 sizeof(*y_map)); 760 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 761 sizeof(*z_map)); 762 if ((x_map == (TransformPacket *) NULL) || 763 (y_map == (TransformPacket *) NULL) || 764 (z_map == (TransformPacket *) NULL)) 765 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 766 image->filename); 767 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info)); 768 switch (colorspace) 769 { 770 case OHTAColorspace: 771 { 772 /* 773 Initialize OHTA tables: 774 775 I1 = 0.33333*R+0.33334*G+0.33333*B 776 I2 = 0.50000*R+0.00000*G-0.50000*B 777 I3 =-0.25000*R+0.50000*G-0.25000*B 778 779 I and Q, normally -0.5 through 0.5, are normalized to the range 0 780 through QuantumRange. 781 */ 782 primary_info.y=(double) (MaxMap+1.0)/2.0; 783 primary_info.z=(double) (MaxMap+1.0)/2.0; 784 #if defined(MAGICKCORE_OPENMP_SUPPORT) 785 #pragma omp parallel for schedule(static,4) \ 786 magick_threads(image,image,1,1) 787 #endif 788 for (i=0; i <= (ssize_t) MaxMap; i++) 789 { 790 x_map[i].x=(MagickRealType) (0.33333*(double) i); 791 y_map[i].x=(MagickRealType) (0.33334*(double) i); 792 z_map[i].x=(MagickRealType) (0.33333*(double) i); 793 x_map[i].y=(MagickRealType) (0.50000*(double) i); 794 y_map[i].y=(MagickRealType) (0.00000*(double) i); 795 z_map[i].y=(MagickRealType) (-0.50000*(double) i); 796 x_map[i].z=(MagickRealType) (-0.25000*(double) i); 797 y_map[i].z=(MagickRealType) (0.50000*(double) i); 798 z_map[i].z=(MagickRealType) (-0.25000*(double) i); 799 } 800 break; 801 } 802 case Rec601YCbCrColorspace: 803 { 804 /* 805 Initialize YCbCr tables (ITU-R BT.601): 806 807 Y = 0.2988390*R+0.5868110*G+0.1143500*B 808 Cb= -0.1687367*R-0.3312640*G+0.5000000*B 809 Cr= 0.5000000*R-0.4186880*G-0.0813120*B 810 811 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0 812 through QuantumRange. 813 */ 814 primary_info.y=(double) (MaxMap+1.0)/2.0; 815 primary_info.z=(double) (MaxMap+1.0)/2.0; 816 #if defined(MAGICKCORE_OPENMP_SUPPORT) 817 #pragma omp parallel for schedule(static,4) \ 818 magick_threads(image,image,1,1) 819 #endif 820 for (i=0; i <= (ssize_t) MaxMap; i++) 821 { 822 x_map[i].x=(MagickRealType) (0.298839*(double) i); 823 y_map[i].x=(MagickRealType) (0.586811*(double) i); 824 z_map[i].x=(MagickRealType) (0.114350*(double) i); 825 x_map[i].y=(MagickRealType) (-0.1687367*(double) i); 826 y_map[i].y=(MagickRealType) (-0.331264*(double) i); 827 z_map[i].y=(MagickRealType) (0.500000*(double) i); 828 x_map[i].z=(MagickRealType) (0.500000*(double) i); 829 y_map[i].z=(MagickRealType) (-0.418688*(double) i); 830 z_map[i].z=(MagickRealType) (-0.081312*(double) i); 831 } 832 break; 833 } 834 case Rec709YCbCrColorspace: 835 { 836 /* 837 Initialize YCbCr tables (ITU-R BT.709): 838 839 Y = 0.212656*R+0.715158*G+0.072186*B 840 Cb= -0.114572*R-0.385428*G+0.500000*B 841 Cr= 0.500000*R-0.454153*G-0.045847*B 842 843 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0 844 through QuantumRange. 845 */ 846 primary_info.y=(double) (MaxMap+1.0)/2.0; 847 primary_info.z=(double) (MaxMap+1.0)/2.0; 848 #if defined(MAGICKCORE_OPENMP_SUPPORT) 849 #pragma omp parallel for schedule(static,4) \ 850 magick_threads(image,image,1,1) 851 #endif 852 for (i=0; i <= (ssize_t) MaxMap; i++) 853 { 854 x_map[i].x=(MagickRealType) (0.212656*(double) i); 855 y_map[i].x=(MagickRealType) (0.715158*(double) i); 856 z_map[i].x=(MagickRealType) (0.072186*(double) i); 857 x_map[i].y=(MagickRealType) (-0.114572*(double) i); 858 y_map[i].y=(MagickRealType) (-0.385428*(double) i); 859 z_map[i].y=(MagickRealType) (0.500000*(double) i); 860 x_map[i].z=(MagickRealType) (0.500000*(double) i); 861 y_map[i].z=(MagickRealType) (-0.454153*(double) i); 862 z_map[i].z=(MagickRealType) (-0.045847*(double) i); 863 } 864 break; 865 } 866 case YCCColorspace: 867 { 868 /* 869 Initialize YCC tables: 870 871 Y = 0.298839*R+0.586811*G+0.114350*B 872 C1= -0.298839*R-0.586811*G+0.88600*B 873 C2= 0.70100*R-0.586811*G-0.114350*B 874 875 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137. 876 */ 877 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156)); 878 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137)); 879 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++) 880 { 881 x_map[i].x=0.003962014134275617*i; 882 y_map[i].x=0.007778268551236748*i; 883 z_map[i].x=0.001510600706713781*i; 884 x_map[i].y=(-0.002426619775463276)*i; 885 y_map[i].y=(-0.004763965913702149)*i; 886 z_map[i].y=0.007190585689165425*i; 887 x_map[i].z=0.006927257754597858*i; 888 y_map[i].z=(-0.005800713697502058)*i; 889 z_map[i].z=(-0.0011265440570958)*i; 890 } 891 for ( ; i <= (ssize_t) MaxMap; i++) 892 { 893 x_map[i].x=0.2201118963486454*(1.099*i-0.099); 894 y_map[i].x=0.4321260306242638*(1.099*i-0.099); 895 z_map[i].x=0.08392226148409894*(1.099*i-0.099); 896 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099); 897 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099); 898 z_map[i].y=0.3994769827314126*(1.099*i-0.099); 899 x_map[i].z=0.3848476530332144*(1.099*i-0.099); 900 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099); 901 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099); 902 } 903 break; 904 } 905 default: 906 { 907 /* 908 Linear conversion tables. 909 */ 910 #if defined(MAGICKCORE_OPENMP_SUPPORT) 911 #pragma omp parallel for schedule(static,4) \ 912 magick_threads(image,image,1,1) 913 #endif 914 for (i=0; i <= (ssize_t) MaxMap; i++) 915 { 916 x_map[i].x=(MagickRealType) (1.0*(double) i); 917 y_map[i].x=(MagickRealType) 0.0; 918 z_map[i].x=(MagickRealType) 0.0; 919 x_map[i].y=(MagickRealType) 0.0; 920 y_map[i].y=(MagickRealType) (1.0*(double) i); 921 z_map[i].y=(MagickRealType) 0.0; 922 x_map[i].z=(MagickRealType) 0.0; 923 y_map[i].z=(MagickRealType) 0.0; 924 z_map[i].z=(MagickRealType) (1.0*(double) i); 925 } 926 break; 927 } 928 } 929 /* 930 Convert from sRGB. 931 */ 932 switch (image->storage_class) 933 { 934 case DirectClass: 935 default: 936 { 937 /* 938 Convert DirectClass image. 939 */ 940 image_view=AcquireAuthenticCacheView(image,exception); 941 #if defined(MAGICKCORE_OPENMP_SUPPORT) 942 #pragma omp parallel for schedule(static,4) shared(status) \ 943 magick_threads(image,image,image->rows,1) 944 #endif 945 for (y=0; y < (ssize_t) image->rows; y++) 946 { 947 MagickBooleanType 948 sync; 949 950 PixelInfo 951 pixel; 952 953 register Quantum 954 *magick_restrict q; 955 956 register ssize_t 957 x; 958 959 register unsigned int 960 blue, 961 green, 962 red; 963 964 if (status == MagickFalse) 965 continue; 966 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 967 exception); 968 if (q == (Quantum *) NULL) 969 { 970 status=MagickFalse; 971 continue; 972 } 973 for (x=0; x < (ssize_t) image->columns; x++) 974 { 975 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType) 976 GetPixelRed(image,q))); 977 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType) 978 GetPixelGreen(image,q))); 979 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType) 980 GetPixelBlue(image,q))); 981 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+ 982 primary_info.x; 983 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+ 984 primary_info.y; 985 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+ 986 primary_info.z; 987 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q); 988 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q); 989 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q); 990 q+=GetPixelChannels(image); 991 } 992 sync=SyncCacheViewAuthenticPixels(image_view,exception); 993 if (sync == MagickFalse) 994 status=MagickFalse; 995 if (image->progress_monitor != (MagickProgressMonitor) NULL) 996 { 997 MagickBooleanType 998 proceed; 999 1000 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1001 #pragma omp critical (MagickCore_sRGBTransformImage) 1002 #endif 1003 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++, 1004 image->rows); 1005 if (proceed == MagickFalse) 1006 status=MagickFalse; 1007 } 1008 } 1009 image_view=DestroyCacheView(image_view); 1010 break; 1011 } 1012 case PseudoClass: 1013 { 1014 register unsigned int 1015 blue, 1016 green, 1017 red; 1018 1019 /* 1020 Convert PseudoClass image. 1021 */ 1022 for (i=0; i < (ssize_t) image->colors; i++) 1023 { 1024 PixelInfo 1025 pixel; 1026 1027 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red)); 1028 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green)); 1029 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue)); 1030 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x; 1031 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y; 1032 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z; 1033 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red); 1034 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green); 1035 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue); 1036 } 1037 (void) SyncImage(image,exception); 1038 break; 1039 } 1040 } 1041 /* 1042 Relinquish resources. 1043 */ 1044 z_map=(TransformPacket *) RelinquishMagickMemory(z_map); 1045 y_map=(TransformPacket *) RelinquishMagickMemory(y_map); 1046 x_map=(TransformPacket *) RelinquishMagickMemory(x_map); 1047 if (SetImageColorspace(image,colorspace,exception) == MagickFalse) 1048 return(MagickFalse); 1049 return(status); 1050 } 1051 1052 /* 1054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1055 % % 1056 % % 1057 % % 1058 % S e t I m a g e C o l o r s p a c e % 1059 % % 1060 % % 1061 % % 1062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1063 % 1064 % SetImageColorspace() sets the colorspace member of the Image structure. 1065 % 1066 % The format of the SetImageColorspace method is: 1067 % 1068 % MagickBooleanType SetImageColorspace(Image *image, 1069 % const ColorspaceType colorspace,ExceptiionInfo *exception) 1070 % 1071 % A description of each parameter follows: 1072 % 1073 % o image: the image. 1074 % 1075 % o colorspace: the colorspace. 1076 % 1077 % o exception: return any errors or warnings in this structure. 1078 % 1079 */ 1080 MagickExport MagickBooleanType SetImageColorspace(Image *image, 1081 const ColorspaceType colorspace,ExceptionInfo *exception) 1082 { 1083 ImageType 1084 type; 1085 1086 MagickBooleanType 1087 status; 1088 1089 if (image->colorspace == colorspace) 1090 return(MagickTrue); 1091 image->colorspace=colorspace; 1092 image->rendering_intent=UndefinedIntent; 1093 image->gamma=1.000/2.200; 1094 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity)); 1095 type=image->type; 1096 if (IsGrayColorspace(colorspace) != MagickFalse) 1097 { 1098 if ((image->intensity == Rec601LuminancePixelIntensityMethod) || 1099 (image->intensity == Rec709LuminancePixelIntensityMethod)) 1100 image->gamma=1.000; 1101 type=GrayscaleType; 1102 } 1103 else 1104 if ((IsRGBColorspace(colorspace) != MagickFalse) || 1105 (colorspace == XYZColorspace) || (colorspace == xyYColorspace)) 1106 image->gamma=1.000; 1107 else 1108 { 1109 image->rendering_intent=PerceptualIntent; 1110 image->chromaticity.red_primary.x=0.6400; 1111 image->chromaticity.red_primary.y=0.3300; 1112 image->chromaticity.red_primary.z=0.0300; 1113 image->chromaticity.green_primary.x=0.3000; 1114 image->chromaticity.green_primary.y=0.6000; 1115 image->chromaticity.green_primary.z=0.1000; 1116 image->chromaticity.blue_primary.x=0.1500; 1117 image->chromaticity.blue_primary.y=0.0600; 1118 image->chromaticity.blue_primary.z=0.7900; 1119 image->chromaticity.white_point.x=0.3127; 1120 image->chromaticity.white_point.y=0.3290; 1121 image->chromaticity.white_point.z=0.3583; 1122 } 1123 status=SyncImagePixelCache(image,exception); 1124 image->type=type; 1125 return(status); 1126 } 1127 1128 /* 1129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1130 % % 1131 % % 1132 % % 1133 % S e t I m a g e G r a y % 1134 % % 1135 % % 1136 % % 1137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1138 % 1139 % SetImageGray() returns MagickTrue if all the pixels in the image have the 1140 % same red, green, and blue intensities and changes the type of the image to 1141 % bi-level or grayscale. 1142 % 1143 % The format of the SetImageGray method is: 1144 % 1145 % MagickBooleanType SetImageGray(const Image *image, 1146 % ExceptionInfo *exception) 1147 % 1148 % A description of each parameter follows: 1149 % 1150 % o image: the image. 1151 % 1152 % o exception: return any errors or warnings in this structure. 1153 % 1154 */ 1155 MagickExport MagickBooleanType SetImageGray(Image *image, 1156 ExceptionInfo *exception) 1157 { 1158 const char 1159 *value; 1160 1161 ImageType 1162 type; 1163 1164 assert(image != (Image *) NULL); 1165 assert(image->signature == MagickCoreSignature); 1166 if (image->debug != MagickFalse) 1167 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1168 if (IsImageGray(image)) 1169 return(MagickTrue); 1170 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1171 return(MagickFalse); 1172 value=GetImageProperty(image,"colorspace:auto-grayscale",exception); 1173 if (IsStringFalse(value) != MagickFalse) 1174 return(MagickFalse); 1175 type=IdentifyImageGray(image,exception); 1176 if (type == UndefinedType) 1177 return(MagickFalse); 1178 image->colorspace=GRAYColorspace; 1179 if (SyncImagePixelCache((Image *) image,exception) == MagickFalse) 1180 return(MagickFalse); 1181 image->type=type; 1182 return(MagickTrue); 1183 } 1184 1185 /* 1186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1187 % % 1188 % % 1189 % % 1190 % S e t I m a g e M o n o c h r o m e % 1191 % % 1192 % % 1193 % % 1194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1195 % 1196 % SetImageMonochrome() returns MagickTrue if all the pixels in the image have 1197 % the same red, green, and blue intensities and the intensity is either 1198 % 0 or QuantumRange and changes the type of the image to bi-level. 1199 % 1200 % The format of the SetImageMonochrome method is: 1201 % 1202 % MagickBooleanType SetImageMonochrome(Image *image, 1203 % ExceptionInfo *exception) 1204 % 1205 % A description of each parameter follows: 1206 % 1207 % o image: the image. 1208 % 1209 % o exception: return any errors or warnings in this structure. 1210 % 1211 */ 1212 MagickExport MagickBooleanType SetImageMonochrome(Image *image, 1213 ExceptionInfo *exception) 1214 { 1215 const char 1216 *value; 1217 1218 assert(image != (Image *) NULL); 1219 assert(image->signature == MagickCoreSignature); 1220 if (image->debug != MagickFalse) 1221 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1222 if (image->type == BilevelType) 1223 return(MagickTrue); 1224 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1225 return(MagickFalse); 1226 value=GetImageProperty(image,"colorspace:auto-grayscale",exception); 1227 if (IsStringFalse(value) != MagickFalse) 1228 return(MagickFalse); 1229 if (IdentifyImageMonochrome(image,exception) == MagickFalse) 1230 return(MagickFalse); 1231 image->colorspace=GRAYColorspace; 1232 if (SyncImagePixelCache((Image *) image,exception) == MagickFalse) 1233 return(MagickFalse); 1234 image->type=BilevelType; 1235 return(MagickTrue); 1236 } 1237 1238 /* 1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1240 % % 1241 % % 1242 % % 1243 % T r a n s f o r m I m a g e C o l o r s p a c e % 1244 % % 1245 % % 1246 % % 1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1248 % 1249 % TransformImageColorspace() transforms an image colorspace, changing the 1250 % image data to reflect the new colorspace. 1251 % 1252 % The format of the TransformImageColorspace method is: 1253 % 1254 % MagickBooleanType TransformImageColorspace(Image *image, 1255 % const ColorspaceType colorspace,ExceptionInfo *exception) 1256 % 1257 % A description of each parameter follows: 1258 % 1259 % o image: the image. 1260 % 1261 % o colorspace: the colorspace. 1262 % 1263 % o exception: return any errors or warnings in this structure. 1264 % 1265 */ 1266 MagickExport MagickBooleanType TransformImageColorspace(Image *image, 1267 const ColorspaceType colorspace,ExceptionInfo *exception) 1268 { 1269 MagickBooleanType 1270 status; 1271 1272 assert(image != (Image *) NULL); 1273 assert(image->signature == MagickCoreSignature); 1274 if (image->debug != MagickFalse) 1275 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1276 if (image->colorspace == colorspace) 1277 return(SetImageColorspace(image,colorspace,exception)); 1278 if ((image->colorspace == GRAYColorspace) && (image->gamma != 1.0) && 1279 (colorspace == sRGBColorspace)) 1280 return(SetImageColorspace(image,colorspace,exception)); 1281 if (colorspace == UndefinedColorspace) 1282 return(SetImageColorspace(image,colorspace,exception)); 1283 /* 1284 Convert the reference image from an alternate colorspace to sRGB. 1285 */ 1286 (void) DeleteImageProfile(image,"icc"); 1287 (void) DeleteImageProfile(image,"icm"); 1288 if (IssRGBColorspace(colorspace) != MagickFalse) 1289 return(TransformsRGBImage(image,exception)); 1290 status=MagickTrue; 1291 if (IssRGBColorspace(image->colorspace) == MagickFalse) 1292 status=TransformsRGBImage(image,exception); 1293 if (status == MagickFalse) 1294 return(status); 1295 /* 1296 Convert the reference image from sRGB to an alternate colorspace. 1297 */ 1298 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse) 1299 status=MagickFalse; 1300 return(status); 1301 } 1302 1303 /* 1305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1306 % % 1307 % % 1308 % % 1309 + T r a n s f o r m s R G B I m a g e % 1310 % % 1311 % % 1312 % % 1313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1314 % 1315 % TransformsRGBImage() converts the reference image from an alternate 1316 % colorspace to sRGB. The transformation matrices are not the standard ones: 1317 % the weights are rescaled to normalize the range of the transformed values 1318 % to be [0..QuantumRange]. 1319 % 1320 % The format of the TransformsRGBImage method is: 1321 % 1322 % MagickBooleanType TransformsRGBImage(Image *image, 1323 % ExceptionInfo *exception) 1324 % 1325 % A description of each parameter follows: 1326 % 1327 % o image: the image. 1328 % 1329 % o exception: return any errors or warnings in this structure. 1330 % 1331 */ 1332 1333 static inline void ConvertCMYToRGB(const double cyan,const double magenta, 1334 const double yellow,double *red,double *green,double *blue) 1335 { 1336 *red=QuantumRange*(1.0-cyan); 1337 *green=QuantumRange*(1.0-magenta); 1338 *blue=QuantumRange*(1.0-yellow); 1339 } 1340 1341 static inline void ConvertLMSToXYZ(const double L,const double M,const double S, 1342 double *X,double *Y,double *Z) 1343 { 1344 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S; 1345 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S; 1346 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S; 1347 } 1348 1349 static inline void ConvertLMSToRGB(const double L,const double M, 1350 const double S,double *red,double *green,double *blue) 1351 { 1352 double 1353 X, 1354 Y, 1355 Z; 1356 1357 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z); 1358 ConvertXYZToRGB(X,Y,Z,red,green,blue); 1359 } 1360 1361 static inline void ConvertLuvToRGB(const double L,const double u, 1362 const double v,double *red,double *green,double *blue) 1363 { 1364 double 1365 X, 1366 Y, 1367 Z; 1368 1369 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z); 1370 ConvertXYZToRGB(X,Y,Z,red,green,blue); 1371 } 1372 1373 static inline ssize_t RoundToYCC(const double value) 1374 { 1375 if (value <= 0.0) 1376 return(0); 1377 if (value >= 1388.0) 1378 return(1388); 1379 return((ssize_t) (value+0.5)); 1380 } 1381 1382 static inline void ConvertLabToRGB(const double L,const double a, 1383 const double b,double *red,double *green,double *blue) 1384 { 1385 double 1386 X, 1387 Y, 1388 Z; 1389 1390 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z); 1391 ConvertXYZToRGB(X,Y,Z,red,green,blue); 1392 } 1393 1394 static inline void ConvertxyYToRGB(const double low_x,const double low_y, 1395 const double cap_Y,double *red,double *green,double *blue) 1396 { 1397 double 1398 X, 1399 Y, 1400 Z; 1401 1402 X=cap_Y/low_y*low_x; 1403 Y=cap_Y; 1404 Z=cap_Y/low_y*(1.0-low_x-low_y); 1405 ConvertXYZToRGB(X,Y,Z,red,green,blue); 1406 } 1407 1408 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr, 1409 double *red,double *green,double *blue) 1410 { 1411 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+ 1412 1.4019995886561440468*(Pr-0.5)); 1413 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)- 1414 0.71413649331646789076*(Pr-0.5)); 1415 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+ 1416 2.1453384174593273e-06*(Pr-0.5)); 1417 } 1418 1419 static void ConvertYCbCrToRGB(const double Y,const double Cb, 1420 const double Cr,double *red,double *green,double *blue) 1421 { 1422 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue); 1423 } 1424 1425 static void ConvertYIQToRGB(const double Y,const double I,const double Q, 1426 double *red,double *green,double *blue) 1427 { 1428 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754* 1429 (Q-0.5)); 1430 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427* 1431 (Q-0.5)); 1432 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374* 1433 (Q-0.5)); 1434 } 1435 1436 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr, 1437 double *red,double *green,double *blue) 1438 { 1439 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)- 1440 0.52591263066186533*(Dr-0.5)); 1441 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+ 1442 0.26789932820759876*(Dr-0.5)); 1443 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)- 1444 7.9202543533108e-05*(Dr-0.5)); 1445 } 1446 1447 static void ConvertYUVToRGB(const double Y,const double U,const double V, 1448 double *red,double *green,double *blue) 1449 { 1450 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825* 1451 (V-0.5)); 1452 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797* 1453 (V-0.5)); 1454 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04* 1455 (V-0.5)); 1456 } 1457 1458 static MagickBooleanType TransformsRGBImage(Image *image, 1459 ExceptionInfo *exception) 1460 { 1461 #define TransformsRGBImageTag "Transform/Image" 1462 1463 static const float 1464 YCCMap[1389] = 1465 { 1466 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f, 1467 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f, 1468 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f, 1469 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f, 1470 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f, 1471 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f, 1472 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f, 1473 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f, 1474 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f, 1475 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f, 1476 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f, 1477 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f, 1478 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f, 1479 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f, 1480 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f, 1481 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f, 1482 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f, 1483 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f, 1484 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f, 1485 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f, 1486 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f, 1487 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f, 1488 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f, 1489 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f, 1490 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f, 1491 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f, 1492 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f, 1493 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f, 1494 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f, 1495 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f, 1496 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f, 1497 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f, 1498 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f, 1499 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f, 1500 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f, 1501 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f, 1502 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f, 1503 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f, 1504 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f, 1505 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f, 1506 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f, 1507 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f, 1508 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f, 1509 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f, 1510 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f, 1511 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f, 1512 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f, 1513 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f, 1514 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f, 1515 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f, 1516 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f, 1517 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f, 1518 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f, 1519 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f, 1520 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f, 1521 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f, 1522 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f, 1523 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f, 1524 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f, 1525 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f, 1526 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f, 1527 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f, 1528 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f, 1529 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f, 1530 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f, 1531 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f, 1532 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f, 1533 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f, 1534 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f, 1535 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f, 1536 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f, 1537 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f, 1538 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f, 1539 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f, 1540 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f, 1541 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f, 1542 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f, 1543 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f, 1544 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f, 1545 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f, 1546 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f, 1547 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f, 1548 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f, 1549 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f, 1550 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f, 1551 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f, 1552 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f, 1553 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f, 1554 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f, 1555 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f, 1556 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f, 1557 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f, 1558 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f, 1559 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f, 1560 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f, 1561 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f, 1562 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f, 1563 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f, 1564 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f, 1565 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f, 1566 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f, 1567 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f, 1568 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f, 1569 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f, 1570 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f, 1571 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f, 1572 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f, 1573 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f, 1574 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f, 1575 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f, 1576 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f, 1577 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f, 1578 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f, 1579 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f, 1580 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f, 1581 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f, 1582 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f, 1583 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f, 1584 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f, 1585 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f, 1586 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f, 1587 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f, 1588 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f, 1589 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f, 1590 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f, 1591 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f, 1592 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f, 1593 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f, 1594 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f, 1595 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f, 1596 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f, 1597 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f, 1598 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f, 1599 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f, 1600 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f, 1601 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f, 1602 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f, 1603 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f, 1604 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f, 1605 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f, 1606 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f, 1607 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f, 1608 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f, 1609 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f, 1610 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f, 1611 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f, 1612 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f, 1613 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f, 1614 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f, 1615 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f, 1616 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f, 1617 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f, 1618 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f, 1619 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f, 1620 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f, 1621 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f, 1622 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f, 1623 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f, 1624 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f, 1625 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f, 1626 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f, 1627 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f, 1628 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f, 1629 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f, 1630 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f, 1631 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f, 1632 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f, 1633 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f, 1634 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f, 1635 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f, 1636 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f, 1637 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f, 1638 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f, 1639 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f, 1640 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f, 1641 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f, 1642 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f, 1643 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f, 1644 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f, 1645 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f, 1646 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f, 1647 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f, 1648 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f, 1649 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f, 1650 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f, 1651 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f, 1652 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f, 1653 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f, 1654 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f, 1655 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f, 1656 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f, 1657 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f, 1658 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f, 1659 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f, 1660 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f, 1661 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f, 1662 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f, 1663 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f, 1664 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f, 1665 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f, 1666 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f, 1667 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f, 1668 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f, 1669 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f, 1670 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f, 1671 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f, 1672 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f, 1673 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f, 1674 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f, 1675 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f, 1676 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f, 1677 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f, 1678 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f, 1679 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f, 1680 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f, 1681 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f, 1682 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f, 1683 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f, 1684 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f, 1685 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f, 1686 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f, 1687 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f, 1688 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f, 1689 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f, 1690 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f, 1691 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f, 1692 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f, 1693 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f, 1694 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f, 1695 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f, 1696 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f, 1697 0.998559f, 0.999280f, 1.000000f 1698 }; 1699 1700 CacheView 1701 *image_view; 1702 1703 MagickBooleanType 1704 status; 1705 1706 MagickOffsetType 1707 progress; 1708 1709 register ssize_t 1710 i; 1711 1712 ssize_t 1713 y; 1714 1715 TransformPacket 1716 *y_map, 1717 *x_map, 1718 *z_map; 1719 1720 assert(image != (Image *) NULL); 1721 assert(image->signature == MagickCoreSignature); 1722 if (image->debug != MagickFalse) 1723 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1724 status=MagickTrue; 1725 progress=0; 1726 switch (image->colorspace) 1727 { 1728 case CMYKColorspace: 1729 { 1730 PixelInfo 1731 zero; 1732 1733 /* 1734 Transform image from CMYK to sRGB. 1735 */ 1736 if (image->storage_class == PseudoClass) 1737 { 1738 if (SyncImage(image,exception) == MagickFalse) 1739 return(MagickFalse); 1740 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 1741 return(MagickFalse); 1742 } 1743 GetPixelInfo(image,&zero); 1744 image_view=AcquireAuthenticCacheView(image,exception); 1745 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1746 #pragma omp parallel for schedule(static,4) shared(status) \ 1747 magick_threads(image,image,image->rows,1) 1748 #endif 1749 for (y=0; y < (ssize_t) image->rows; y++) 1750 { 1751 MagickBooleanType 1752 sync; 1753 1754 PixelInfo 1755 pixel; 1756 1757 register ssize_t 1758 x; 1759 1760 register Quantum 1761 *magick_restrict q; 1762 1763 if (status == MagickFalse) 1764 continue; 1765 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 1766 exception); 1767 if (q == (Quantum *) NULL) 1768 { 1769 status=MagickFalse; 1770 continue; 1771 } 1772 pixel=zero; 1773 for (x=0; x < (ssize_t) image->columns; x++) 1774 { 1775 GetPixelInfoPixel(image,q,&pixel); 1776 ConvertCMYKToRGB(&pixel); 1777 SetPixelViaPixelInfo(image,&pixel,q); 1778 q+=GetPixelChannels(image); 1779 } 1780 sync=SyncCacheViewAuthenticPixels(image_view,exception); 1781 if (sync == MagickFalse) 1782 status=MagickFalse; 1783 } 1784 image_view=DestroyCacheView(image_view); 1785 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 1786 return(MagickFalse); 1787 return(status); 1788 } 1789 case GRAYColorspace: 1790 { 1791 /* 1792 Transform linear GRAY to sRGB colorspace. 1793 */ 1794 if (image->storage_class == PseudoClass) 1795 { 1796 if (SyncImage(image,exception) == MagickFalse) 1797 return(MagickFalse); 1798 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 1799 return(MagickFalse); 1800 } 1801 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 1802 return(MagickFalse); 1803 image_view=AcquireAuthenticCacheView(image,exception); 1804 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1805 #pragma omp parallel for schedule(static,4) shared(status) \ 1806 magick_threads(image,image,image->rows,1) 1807 #endif 1808 for (y=0; y < (ssize_t) image->rows; y++) 1809 { 1810 MagickBooleanType 1811 sync; 1812 1813 register ssize_t 1814 x; 1815 1816 register Quantum 1817 *magick_restrict q; 1818 1819 if (status == MagickFalse) 1820 continue; 1821 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 1822 exception); 1823 if (q == (Quantum *) NULL) 1824 { 1825 status=MagickFalse; 1826 continue; 1827 } 1828 for (x=(ssize_t) image->columns; x != 0; x--) 1829 { 1830 MagickRealType 1831 gray; 1832 1833 gray=(MagickRealType) GetPixelGray(image,q); 1834 if ((image->intensity == Rec601LuminancePixelIntensityMethod) || 1835 (image->intensity == Rec709LuminancePixelIntensityMethod)) 1836 gray=EncodePixelGamma(gray); 1837 SetPixelRed(image,ClampToQuantum(gray),q); 1838 SetPixelGreen(image,ClampToQuantum(gray),q); 1839 SetPixelBlue(image,ClampToQuantum(gray),q); 1840 q+=GetPixelChannels(image); 1841 } 1842 sync=SyncCacheViewAuthenticPixels(image_view,exception); 1843 if (sync == MagickFalse) 1844 status=MagickFalse; 1845 } 1846 image_view=DestroyCacheView(image_view); 1847 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 1848 return(MagickFalse); 1849 return(status); 1850 } 1851 case CMYColorspace: 1852 case HCLColorspace: 1853 case HCLpColorspace: 1854 case HSBColorspace: 1855 case HSIColorspace: 1856 case HSLColorspace: 1857 case HSVColorspace: 1858 case HWBColorspace: 1859 case LabColorspace: 1860 case LCHColorspace: 1861 case LCHabColorspace: 1862 case LCHuvColorspace: 1863 case LMSColorspace: 1864 case LuvColorspace: 1865 case xyYColorspace: 1866 case XYZColorspace: 1867 case YCbCrColorspace: 1868 case YDbDrColorspace: 1869 case YIQColorspace: 1870 case YPbPrColorspace: 1871 case YUVColorspace: 1872 { 1873 /* 1874 Transform image from source colorspace to sRGB. 1875 */ 1876 if (image->storage_class == PseudoClass) 1877 { 1878 if (SyncImage(image,exception) == MagickFalse) 1879 return(MagickFalse); 1880 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 1881 return(MagickFalse); 1882 } 1883 image_view=AcquireAuthenticCacheView(image,exception); 1884 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1885 #pragma omp parallel for schedule(static,4) shared(status) \ 1886 magick_threads(image,image,image->rows,1) 1887 #endif 1888 for (y=0; y < (ssize_t) image->rows; y++) 1889 { 1890 MagickBooleanType 1891 sync; 1892 1893 register ssize_t 1894 x; 1895 1896 register Quantum 1897 *magick_restrict q; 1898 1899 if (status == MagickFalse) 1900 continue; 1901 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 1902 exception); 1903 if (q == (Quantum *) NULL) 1904 { 1905 status=MagickFalse; 1906 continue; 1907 } 1908 for (x=0; x < (ssize_t) image->columns; x++) 1909 { 1910 double 1911 blue, 1912 green, 1913 red, 1914 X, 1915 Y, 1916 Z; 1917 1918 X=QuantumScale*GetPixelRed(image,q); 1919 Y=QuantumScale*GetPixelGreen(image,q); 1920 Z=QuantumScale*GetPixelBlue(image,q); 1921 switch (image->colorspace) 1922 { 1923 case CMYColorspace: 1924 { 1925 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue); 1926 break; 1927 } 1928 case HCLColorspace: 1929 { 1930 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue); 1931 break; 1932 } 1933 case HCLpColorspace: 1934 { 1935 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue); 1936 break; 1937 } 1938 case HSBColorspace: 1939 { 1940 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue); 1941 break; 1942 } 1943 case HSIColorspace: 1944 { 1945 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue); 1946 break; 1947 } 1948 case HSLColorspace: 1949 { 1950 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue); 1951 break; 1952 } 1953 case HSVColorspace: 1954 { 1955 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue); 1956 break; 1957 } 1958 case HWBColorspace: 1959 { 1960 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue); 1961 break; 1962 } 1963 case LabColorspace: 1964 { 1965 ConvertLabToRGB(X,Y,Z,&red,&green,&blue); 1966 break; 1967 } 1968 case LCHColorspace: 1969 case LCHabColorspace: 1970 { 1971 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue); 1972 break; 1973 } 1974 case LCHuvColorspace: 1975 { 1976 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue); 1977 break; 1978 } 1979 case LMSColorspace: 1980 { 1981 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue); 1982 break; 1983 } 1984 case LuvColorspace: 1985 { 1986 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue); 1987 break; 1988 } 1989 case xyYColorspace: 1990 { 1991 ConvertxyYToRGB(X,Y,Z,&red,&green,&blue); 1992 break; 1993 } 1994 case XYZColorspace: 1995 { 1996 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue); 1997 break; 1998 } 1999 case YCbCrColorspace: 2000 { 2001 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue); 2002 break; 2003 } 2004 case YDbDrColorspace: 2005 { 2006 ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue); 2007 break; 2008 } 2009 case YIQColorspace: 2010 { 2011 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue); 2012 break; 2013 } 2014 case YPbPrColorspace: 2015 { 2016 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue); 2017 break; 2018 } 2019 case YUVColorspace: 2020 { 2021 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue); 2022 break; 2023 } 2024 default: 2025 { 2026 red=QuantumRange*X; 2027 green=QuantumRange*Y; 2028 blue=QuantumRange*Z; 2029 break; 2030 } 2031 } 2032 SetPixelRed(image,ClampToQuantum(red),q); 2033 SetPixelGreen(image,ClampToQuantum(green),q); 2034 SetPixelBlue(image,ClampToQuantum(blue),q); 2035 q+=GetPixelChannels(image); 2036 } 2037 sync=SyncCacheViewAuthenticPixels(image_view,exception); 2038 if (sync == MagickFalse) 2039 status=MagickFalse; 2040 } 2041 image_view=DestroyCacheView(image_view); 2042 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 2043 return(MagickFalse); 2044 return(status); 2045 } 2046 case LogColorspace: 2047 { 2048 const char 2049 *value; 2050 2051 double 2052 black, 2053 density, 2054 film_gamma, 2055 gamma, 2056 reference_black, 2057 reference_white; 2058 2059 Quantum 2060 *logmap; 2061 2062 /* 2063 Transform Log to sRGB colorspace. 2064 */ 2065 density=DisplayGamma; 2066 gamma=DisplayGamma; 2067 value=GetImageProperty(image,"gamma",exception); 2068 if (value != (const char *) NULL) 2069 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL)); 2070 film_gamma=FilmGamma; 2071 value=GetImageProperty(image,"film-gamma",exception); 2072 if (value != (const char *) NULL) 2073 film_gamma=StringToDouble(value,(char **) NULL); 2074 reference_black=ReferenceBlack; 2075 value=GetImageProperty(image,"reference-black",exception); 2076 if (value != (const char *) NULL) 2077 reference_black=StringToDouble(value,(char **) NULL); 2078 reference_white=ReferenceWhite; 2079 value=GetImageProperty(image,"reference-white",exception); 2080 if (value != (const char *) NULL) 2081 reference_white=StringToDouble(value,(char **) NULL); 2082 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL, 2083 sizeof(*logmap)); 2084 if (logmap == (Quantum *) NULL) 2085 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 2086 image->filename); 2087 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/ 2088 film_gamma); 2089 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++) 2090 logmap[i]=(Quantum) 0; 2091 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++) 2092 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)* 2093 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/ 2094 film_gamma)-black)); 2095 for ( ; i <= (ssize_t) MaxMap; i++) 2096 logmap[i]=QuantumRange; 2097 if (image->storage_class == PseudoClass) 2098 { 2099 if (SyncImage(image,exception) == MagickFalse) 2100 return(MagickFalse); 2101 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 2102 return(MagickFalse); 2103 } 2104 image_view=AcquireAuthenticCacheView(image,exception); 2105 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2106 #pragma omp parallel for schedule(static,4) shared(status) \ 2107 magick_threads(image,image,image->rows,1) 2108 #endif 2109 for (y=0; y < (ssize_t) image->rows; y++) 2110 { 2111 MagickBooleanType 2112 sync; 2113 2114 register ssize_t 2115 x; 2116 2117 register Quantum 2118 *magick_restrict q; 2119 2120 if (status == MagickFalse) 2121 continue; 2122 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 2123 exception); 2124 if (q == (Quantum *) NULL) 2125 { 2126 status=MagickFalse; 2127 continue; 2128 } 2129 for (x=(ssize_t) image->columns; x != 0; x--) 2130 { 2131 double 2132 blue, 2133 green, 2134 red; 2135 2136 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))]; 2137 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))]; 2138 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))]; 2139 SetPixelRed(image,ClampToQuantum(EncodePixelGamma((MagickRealType) 2140 red)),q); 2141 SetPixelGreen(image,ClampToQuantum(EncodePixelGamma((MagickRealType) 2142 green)),q); 2143 SetPixelBlue(image,ClampToQuantum(EncodePixelGamma((MagickRealType) 2144 blue)),q); 2145 q+=GetPixelChannels(image); 2146 } 2147 sync=SyncCacheViewAuthenticPixels(image_view,exception); 2148 if (sync == MagickFalse) 2149 status=MagickFalse; 2150 } 2151 image_view=DestroyCacheView(image_view); 2152 logmap=(Quantum *) RelinquishMagickMemory(logmap); 2153 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 2154 return(MagickFalse); 2155 return(status); 2156 } 2157 case RGBColorspace: 2158 case scRGBColorspace: 2159 { 2160 /* 2161 Transform linear RGB to sRGB colorspace. 2162 */ 2163 if (image->storage_class == PseudoClass) 2164 { 2165 if (SyncImage(image,exception) == MagickFalse) 2166 return(MagickFalse); 2167 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 2168 return(MagickFalse); 2169 } 2170 image_view=AcquireAuthenticCacheView(image,exception); 2171 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2172 #pragma omp parallel for schedule(static,4) shared(status) \ 2173 magick_threads(image,image,image->rows,1) 2174 #endif 2175 for (y=0; y < (ssize_t) image->rows; y++) 2176 { 2177 MagickBooleanType 2178 sync; 2179 2180 register ssize_t 2181 x; 2182 2183 register Quantum 2184 *magick_restrict q; 2185 2186 if (status == MagickFalse) 2187 continue; 2188 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 2189 exception); 2190 if (q == (Quantum *) NULL) 2191 { 2192 status=MagickFalse; 2193 continue; 2194 } 2195 for (x=(ssize_t) image->columns; x != 0; x--) 2196 { 2197 double 2198 blue, 2199 green, 2200 red; 2201 2202 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q)); 2203 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q)); 2204 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q)); 2205 SetPixelRed(image,ClampToQuantum(red),q); 2206 SetPixelGreen(image,ClampToQuantum(green),q); 2207 SetPixelBlue(image,ClampToQuantum(blue),q); 2208 q+=GetPixelChannels(image); 2209 } 2210 sync=SyncCacheViewAuthenticPixels(image_view,exception); 2211 if (sync == MagickFalse) 2212 status=MagickFalse; 2213 } 2214 image_view=DestroyCacheView(image_view); 2215 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 2216 return(MagickFalse); 2217 return(status); 2218 } 2219 default: 2220 break; 2221 } 2222 /* 2223 Allocate the tables. 2224 */ 2225 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 2226 sizeof(*x_map)); 2227 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 2228 sizeof(*y_map)); 2229 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL, 2230 sizeof(*z_map)); 2231 if ((x_map == (TransformPacket *) NULL) || 2232 (y_map == (TransformPacket *) NULL) || 2233 (z_map == (TransformPacket *) NULL)) 2234 { 2235 if (z_map != (TransformPacket *) NULL) 2236 z_map=(TransformPacket *) RelinquishMagickMemory(z_map); 2237 if (y_map != (TransformPacket *) NULL) 2238 y_map=(TransformPacket *) RelinquishMagickMemory(y_map); 2239 if (x_map != (TransformPacket *) NULL) 2240 x_map=(TransformPacket *) RelinquishMagickMemory(x_map); 2241 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 2242 image->filename); 2243 } 2244 switch (image->colorspace) 2245 { 2246 case OHTAColorspace: 2247 { 2248 /* 2249 Initialize OHTA tables: 2250 2251 I1 = 0.33333*R+0.33334*G+0.33333*B 2252 I2 = 0.50000*R+0.00000*G-0.50000*B 2253 I3 =-0.25000*R+0.50000*G-0.25000*B 2254 R = I1+1.00000*I2-0.66668*I3 2255 G = I1+0.00000*I2+1.33333*I3 2256 B = I1-1.00000*I2-0.66668*I3 2257 2258 I and Q, normally -0.5 through 0.5, must be normalized to the range 0 2259 through QuantumRange. 2260 */ 2261 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2262 #pragma omp parallel for schedule(static,4) \ 2263 magick_threads(image,image,1,1) 2264 #endif 2265 for (i=0; i <= (ssize_t) MaxMap; i++) 2266 { 2267 x_map[i].x=(MagickRealType) (1.0*(double) i); 2268 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap)); 2269 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap)); 2270 x_map[i].y=(MagickRealType) (1.0*(double) i); 2271 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap)); 2272 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap)); 2273 x_map[i].z=(MagickRealType) (1.0*(double) i); 2274 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap)); 2275 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap)); 2276 } 2277 break; 2278 } 2279 case Rec601YCbCrColorspace: 2280 { 2281 /* 2282 Initialize YCbCr tables: 2283 2284 R = Y +1.402000*Cr 2285 G = Y-0.344136*Cb-0.714136*Cr 2286 B = Y+1.772000*Cb 2287 2288 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0 2289 through QuantumRange. 2290 */ 2291 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2292 #pragma omp parallel for schedule(static,4) \ 2293 magick_threads(image,image,1,1) 2294 #endif 2295 for (i=0; i <= (ssize_t) MaxMap; i++) 2296 { 2297 x_map[i].x=0.99999999999914679361*(double) i; 2298 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap); 2299 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap); 2300 x_map[i].y=0.99999975910502514331*(double) i; 2301 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap); 2302 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap); 2303 x_map[i].z=1.00000124040004623180*(double) i; 2304 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap); 2305 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap); 2306 } 2307 break; 2308 } 2309 case Rec709YCbCrColorspace: 2310 { 2311 /* 2312 Initialize YCbCr tables: 2313 2314 R = Y +1.574800*Cr 2315 G = Y-0.187324*Cb-0.468124*Cr 2316 B = Y+1.855600*Cb 2317 2318 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0 2319 through QuantumRange. 2320 */ 2321 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2322 #pragma omp parallel for schedule(static,4) \ 2323 magick_threads(image,image,1,1) 2324 #endif 2325 for (i=0; i <= (ssize_t) MaxMap; i++) 2326 { 2327 x_map[i].x=(MagickRealType) (1.0*i); 2328 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap)); 2329 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap)); 2330 x_map[i].y=(MagickRealType) (1.0*i); 2331 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap)); 2332 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap)); 2333 x_map[i].z=(MagickRealType) (1.0*i); 2334 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap)); 2335 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap)); 2336 } 2337 break; 2338 } 2339 case YCCColorspace: 2340 { 2341 /* 2342 Initialize YCC tables: 2343 2344 R = Y +1.340762*C2 2345 G = Y-0.317038*C1-0.682243*C2 2346 B = Y+1.632639*C1 2347 2348 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137. 2349 */ 2350 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2351 #pragma omp parallel for schedule(static,4) \ 2352 magick_threads(image,image,1,1) 2353 #endif 2354 for (i=0; i <= (ssize_t) MaxMap; i++) 2355 { 2356 x_map[i].x=(MagickRealType) (1.3584000*(double) i); 2357 y_map[i].x=(MagickRealType) 0.0000000; 2358 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double) 2359 ScaleQuantumToMap(ScaleCharToQuantum(137)))); 2360 x_map[i].y=(MagickRealType) (1.3584000*(double) i); 2361 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double) 2362 ScaleQuantumToMap(ScaleCharToQuantum(156)))); 2363 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double) 2364 ScaleQuantumToMap(ScaleCharToQuantum(137)))); 2365 x_map[i].z=(MagickRealType) (1.3584000*(double) i); 2366 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double) 2367 ScaleQuantumToMap(ScaleCharToQuantum(156)))); 2368 z_map[i].z=(MagickRealType) 0.0000000; 2369 } 2370 break; 2371 } 2372 default: 2373 { 2374 /* 2375 Linear conversion tables. 2376 */ 2377 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2378 #pragma omp parallel for schedule(static,4) \ 2379 magick_threads(image,image,1,1) 2380 #endif 2381 for (i=0; i <= (ssize_t) MaxMap; i++) 2382 { 2383 x_map[i].x=(MagickRealType) (1.0*(double) i); 2384 y_map[i].x=(MagickRealType) 0.0; 2385 z_map[i].x=(MagickRealType) 0.0; 2386 x_map[i].y=(MagickRealType) 0.0; 2387 y_map[i].y=(MagickRealType) (1.0*(double) i); 2388 z_map[i].y=(MagickRealType) 0.0; 2389 x_map[i].z=(MagickRealType) 0.0; 2390 y_map[i].z=(MagickRealType) 0.0; 2391 z_map[i].z=(MagickRealType) (1.0*(double) i); 2392 } 2393 break; 2394 } 2395 } 2396 /* 2397 Convert to sRGB. 2398 */ 2399 switch (image->storage_class) 2400 { 2401 case DirectClass: 2402 default: 2403 { 2404 /* 2405 Convert DirectClass image. 2406 */ 2407 image_view=AcquireAuthenticCacheView(image,exception); 2408 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2409 #pragma omp parallel for schedule(static,4) shared(status) \ 2410 magick_threads(image,image,image->rows,1) 2411 #endif 2412 for (y=0; y < (ssize_t) image->rows; y++) 2413 { 2414 MagickBooleanType 2415 sync; 2416 2417 PixelInfo 2418 pixel; 2419 2420 register ssize_t 2421 x; 2422 2423 register Quantum 2424 *magick_restrict q; 2425 2426 if (status == MagickFalse) 2427 continue; 2428 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 2429 exception); 2430 if (q == (Quantum *) NULL) 2431 { 2432 status=MagickFalse; 2433 continue; 2434 } 2435 for (x=0; x < (ssize_t) image->columns; x++) 2436 { 2437 register size_t 2438 blue, 2439 green, 2440 red; 2441 2442 red=ScaleQuantumToMap(GetPixelRed(image,q)); 2443 green=ScaleQuantumToMap(GetPixelGreen(image,q)); 2444 blue=ScaleQuantumToMap(GetPixelBlue(image,q)); 2445 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x; 2446 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y; 2447 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z; 2448 if (image->colorspace == YCCColorspace) 2449 { 2450 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/ 2451 (double) MaxMap)]; 2452 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/ 2453 (double) MaxMap)]; 2454 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/ 2455 (double) MaxMap)]; 2456 } 2457 else 2458 { 2459 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red); 2460 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green); 2461 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue); 2462 } 2463 SetPixelRed(image,ClampToQuantum(pixel.red),q); 2464 SetPixelGreen(image,ClampToQuantum(pixel.green),q); 2465 SetPixelBlue(image,ClampToQuantum(pixel.blue),q); 2466 q+=GetPixelChannels(image); 2467 } 2468 sync=SyncCacheViewAuthenticPixels(image_view,exception); 2469 if (sync == MagickFalse) 2470 status=MagickFalse; 2471 if (image->progress_monitor != (MagickProgressMonitor) NULL) 2472 { 2473 MagickBooleanType 2474 proceed; 2475 2476 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2477 #pragma omp critical (MagickCore_TransformsRGBImage) 2478 #endif 2479 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++, 2480 image->rows); 2481 if (proceed == MagickFalse) 2482 status=MagickFalse; 2483 } 2484 } 2485 image_view=DestroyCacheView(image_view); 2486 break; 2487 } 2488 case PseudoClass: 2489 { 2490 /* 2491 Convert PseudoClass image. 2492 */ 2493 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2494 #pragma omp parallel for schedule(static,4) shared(status) \ 2495 magick_threads(image,image,1,1) 2496 #endif 2497 for (i=0; i < (ssize_t) image->colors; i++) 2498 { 2499 PixelInfo 2500 pixel; 2501 2502 register size_t 2503 blue, 2504 green, 2505 red; 2506 2507 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red)); 2508 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green)); 2509 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue)); 2510 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x; 2511 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y; 2512 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z; 2513 if (image->colorspace == YCCColorspace) 2514 { 2515 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/ 2516 (double) MaxMap)]; 2517 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/ 2518 (double) MaxMap)]; 2519 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/ 2520 (double) MaxMap)]; 2521 } 2522 else 2523 { 2524 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red); 2525 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green); 2526 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue); 2527 } 2528 image->colormap[i].red=(double) ClampToQuantum(pixel.red); 2529 image->colormap[i].green=(double) ClampToQuantum(pixel.green); 2530 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue); 2531 } 2532 (void) SyncImage(image,exception); 2533 break; 2534 } 2535 } 2536 /* 2537 Relinquish resources. 2538 */ 2539 z_map=(TransformPacket *) RelinquishMagickMemory(z_map); 2540 y_map=(TransformPacket *) RelinquishMagickMemory(y_map); 2541 x_map=(TransformPacket *) RelinquishMagickMemory(x_map); 2542 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse) 2543 return(MagickFalse); 2544 return(MagickTrue); 2545 } 2546