1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% PPPP IIIII X X EEEEE L % 7% P P I X X E L % 8% PPPP I X EEE L % 9% P I X X E L % 10% P IIIII X X EEEEE LLLLL % 11% % 12% MagickCore Methods to Import/Export Pixels % 13% % 14% Software Design % 15% Cristy % 16% October 1998 % 17% % 18% % 19% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 20% dedicated to making software imaging solutions freely available. % 21% % 22% You may not use this file except in compliance with the License. You may % 23% obtain a copy of the License at % 24% % 25% http://www.imagemagick.org/script/license.php % 26% % 27% Unless required by applicable law or agreed to in writing, software % 28% distributed under the License is distributed on an "AS IS" BASIS, % 29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 30% See the License for the specific language governing permissions and % 31% limitations under the License. % 32% % 33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34% 35% 36*/ 37 38/* 39 Include declarations. 40*/ 41#include "MagickCore/studio.h" 42#include "MagickCore/property.h" 43#include "MagickCore/blob.h" 44#include "MagickCore/blob-private.h" 45#include "MagickCore/cache-private.h" 46#include "MagickCore/color-private.h" 47#include "MagickCore/colorspace-private.h" 48#include "MagickCore/draw.h" 49#include "MagickCore/exception.h" 50#include "MagickCore/exception-private.h" 51#include "MagickCore/cache.h" 52#include "MagickCore/constitute.h" 53#include "MagickCore/delegate.h" 54#include "MagickCore/geometry.h" 55#include "MagickCore/image-private.h" 56#include "MagickCore/list.h" 57#include "MagickCore/magick.h" 58#include "MagickCore/memory_.h" 59#include "MagickCore/memory-private.h" 60#include "MagickCore/monitor.h" 61#include "MagickCore/option.h" 62#include "MagickCore/pixel.h" 63#include "MagickCore/pixel-accessor.h" 64#include "MagickCore/pixel-private.h" 65#include "MagickCore/quantum.h" 66#include "MagickCore/quantum-private.h" 67#include "MagickCore/resource_.h" 68#include "MagickCore/semaphore.h" 69#include "MagickCore/statistic.h" 70#include "MagickCore/stream.h" 71#include "MagickCore/string_.h" 72#include "MagickCore/transform.h" 73#include "MagickCore/utility.h" 74 75/* 76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 77% % 78% % 79% % 80+ A c q u i r e P i x e l C h a n n e l M a p % 81% % 82% % 83% % 84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 85% 86% AcquirePixelChannelMap() acquires a pixel component map. 87% 88% The format of the AcquirePixelChannelMap() method is: 89% 90% PixelChannelMap *AcquirePixelChannelMap(void) 91% 92*/ 93MagickExport PixelChannelMap *AcquirePixelChannelMap(void) 94{ 95 PixelChannelMap 96 *channel_map; 97 98 register ssize_t 99 i; 100 101 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels, 102 sizeof(*channel_map)); 103 if (channel_map == (PixelChannelMap *) NULL) 104 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 105 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map)); 106 for (i=0; i < MaxPixelChannels; i++) 107 channel_map[i].channel=(PixelChannel) i; 108 return(channel_map); 109} 110 111/* 112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113% % 114% % 115% % 116+ C l o n e P i x e l C h a n n e l M a p % 117% % 118% % 119% % 120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 121% 122% ClonePixelChannelMap() clones a pixel component map. 123% 124% The format of the ClonePixelChannelMap() method is: 125% 126% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map) 127% 128% A description of each parameter follows: 129% 130% o channel_map: the pixel component map. 131% 132*/ 133MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map) 134{ 135 PixelChannelMap 136 *clone_map; 137 138 assert(channel_map != (PixelChannelMap *) NULL); 139 clone_map=AcquirePixelChannelMap(); 140 if (clone_map == (PixelChannelMap *) NULL) 141 return((PixelChannelMap *) NULL); 142 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels* 143 sizeof(*channel_map)); 144 return(clone_map); 145} 146 147/* 148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 149% % 150% % 151% % 152+ C l o n e P i x e l I n f o % 153% % 154% % 155% % 156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 157% 158% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if 159% pixel info is NULL, a new one. 160% 161% The format of the ClonePixelInfo method is: 162% 163% PixelInfo *ClonePixelInfo(const PixelInfo *pixel) 164% 165% A description of each parameter follows: 166% 167% o pixel: the pixel info. 168% 169*/ 170MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel) 171{ 172 PixelInfo 173 *pixel_info; 174 175 pixel_info=(PixelInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, 176 sizeof(*pixel_info))); 177 if (pixel_info == (PixelInfo *) NULL) 178 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 179 *pixel_info=(*pixel); 180 return(pixel_info); 181} 182 183/* 184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 185% % 186% % 187% % 188+ C o n f o r m P i x e l I n f o % 189% % 190% % 191% % 192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 193% 194% ConformPixelInfo() ensures the pixel conforms with the colorspace and alpha 195% attribute of the image. 196% 197% The format of the ConformPixelInfo method is: 198% 199% void *ConformPixelInfo((Image *image,const PixelInfo *source, 200% PixelInfo *destination,ExceptionInfo *exception) 201% 202% A description of each parameter follows: 203% 204% o image: the image. 205% 206% o source: the source pixel info. 207% 208% o destination: the destination pixel info. 209% 210% o exception: return any errors or warnings in this structure. 211% 212*/ 213MagickExport void ConformPixelInfo(Image *image,const PixelInfo *source, 214 PixelInfo *destination,ExceptionInfo *exception) 215{ 216 assert(image != (Image *) NULL); 217 assert(image->signature == MagickCoreSignature); 218 assert(destination != (const PixelInfo *) NULL); 219 *destination=(*source); 220 if (image->colorspace == CMYKColorspace) 221 { 222 if (IssRGBCompatibleColorspace(destination->colorspace)) 223 ConvertRGBToCMYK(destination); 224 } 225 else 226 if (destination->colorspace == CMYKColorspace) 227 { 228 if (IssRGBCompatibleColorspace(image->colorspace)) 229 ConvertCMYKToRGB(destination); 230 } 231 if ((IsPixelInfoGray(&image->background_color) == MagickFalse) && 232 (IsGrayColorspace(image->colorspace) != MagickFalse)) 233 (void) TransformImageColorspace(image,sRGBColorspace,exception); 234 if ((destination->alpha_trait != UndefinedPixelTrait) && 235 (image->alpha_trait == UndefinedPixelTrait)) 236 (void) SetImageAlpha(image,OpaqueAlpha,exception); 237} 238 239/* 240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 241% % 242% % 243% % 244% D e c o d e P i x e l G a m m a % 245% % 246% % 247% % 248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 249% 250% DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel. 251% 252% The format of the DecodePixelGamma method is: 253% 254% double DecodePixelGamma(const MagickRealType pixel) 255% 256% A description of each parameter follows: 257% 258% o pixel: the pixel. 259% 260*/ 261 262static inline double DecodeGamma(const double x) 263{ 264 div_t 265 quotient; 266 267 double 268 p, 269 term[9]; 270 271 int 272 exponent; 273 274 static const double coefficient[] = /* terms for x^(7/5), x=1.5 */ 275 { 276 1.7917488588043277509, 277 0.82045614371976854984, 278 0.027694100686325412819, 279 -0.00094244335181762134018, 280 0.000064355540911469709545, 281 -5.7224404636060757485e-06, 282 5.8767669437311184313e-07, 283 -6.6139920053589721168e-08, 284 7.9323242696227458163e-09 285 }; 286 287 static const double powers_of_two[] = /* (2^x)^(7/5) */ 288 { 289 1.0, 290 2.6390158215457883983, 291 6.9644045063689921093, 292 1.8379173679952558018e+01, 293 4.8502930128332728543e+01 294 }; 295 296 /* 297 Compute x^2.4 == x*x^(7/5) == pow(x,2.4). 298 */ 299 term[0]=1.0; 300 term[1]=4.0*frexp(x,&exponent)-3.0; 301 term[2]=2.0*term[1]*term[1]-term[0]; 302 term[3]=2.0*term[1]*term[2]-term[1]; 303 term[4]=2.0*term[1]*term[3]-term[2]; 304 term[5]=2.0*term[1]*term[4]-term[3]; 305 term[6]=2.0*term[1]*term[5]-term[4]; 306 term[7]=2.0*term[1]*term[6]-term[5]; 307 term[8]=2.0*term[1]*term[7]-term[6]; 308 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+ 309 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+ 310 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8]; 311 quotient=div(exponent-1,5); 312 if (quotient.rem < 0) 313 { 314 quotient.quot-=1; 315 quotient.rem+=5; 316 } 317 return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot)); 318} 319 320MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel) 321{ 322 if (pixel <= (0.0404482362771076*QuantumRange)) 323 return(pixel/12.92f); 324 return((MagickRealType) (QuantumRange*DecodeGamma((double) (QuantumScale* 325 pixel+0.055)/1.055))); 326} 327 328/* 329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 330% % 331% % 332% % 333+ D e s t r o y P i x e l C h a n n e l M a p % 334% % 335% % 336% % 337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 338% 339% DestroyPixelChannelMap() deallocates memory associated with the pixel 340% channel map. 341% 342% The format of the DestroyPixelChannelMap() method is: 343% 344% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map) 345% 346% A description of each parameter follows: 347% 348% o channel_map: the pixel component map. 349% 350*/ 351MagickExport PixelChannelMap *DestroyPixelChannelMap( 352 PixelChannelMap *channel_map) 353{ 354 assert(channel_map != (PixelChannelMap *) NULL); 355 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map); 356 return((PixelChannelMap *) RelinquishMagickMemory(channel_map)); 357} 358 359/* 360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 361% % 362% % 363% % 364+ E n c o d e P i x e l G a m m a % 365% % 366% % 367% % 368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 369% 370% EncodePixelGamma() cancels any nonlinearity in the pixel. 371% 372% The format of the EncodePixelGamma method is: 373% 374% MagickRealType EncodePixelGamma(const double MagickRealType) 375% 376% A description of each parameter follows: 377% 378% o pixel: the pixel. 379% 380*/ 381 382static inline double EncodeGamma(const double x) 383{ 384 div_t 385 quotient; 386 387 double 388 p, 389 term[9]; 390 391 int 392 exponent; 393 394 static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */ 395 { 396 1.1758200232996901923, 397 0.16665763094889061230, 398 -0.0083154894939042125035, 399 0.00075187976780420279038, 400 -0.000083240178519391795367, 401 0.000010229209410070008679, 402 -1.3400466409860246e-06, 403 1.8333422241635376682e-07, 404 -2.5878596761348859722e-08 405 }; 406 407 static const double powers_of_two[] = /* (2^N)^(5/12) */ 408 { 409 1.0, 410 1.3348398541700343678, 411 1.7817974362806785482, 412 2.3784142300054420538, 413 3.1748021039363991669, 414 4.2378523774371812394, 415 5.6568542494923805819, 416 7.5509945014535482244, 417 1.0079368399158985525e1, 418 1.3454342644059433809e1, 419 1.7959392772949968275e1, 420 2.3972913230026907883e1 421 }; 422 423 /* 424 Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4). 425 */ 426 term[0]=1.0; 427 term[1]=4.0*frexp(x,&exponent)-3.0; 428 term[2]=2.0*term[1]*term[1]-term[0]; 429 term[3]=2.0*term[1]*term[2]-term[1]; 430 term[4]=2.0*term[1]*term[3]-term[2]; 431 term[5]=2.0*term[1]*term[4]-term[3]; 432 term[6]=2.0*term[1]*term[5]-term[4]; 433 term[7]=2.0*term[1]*term[6]-term[5]; 434 term[8]=2.0*term[1]*term[7]-term[6]; 435 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+ 436 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+ 437 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8]; 438 quotient=div(exponent-1,12); 439 if (quotient.rem < 0) 440 { 441 quotient.quot-=1; 442 quotient.rem+=12; 443 } 444 return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot)); 445} 446 447MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel) 448{ 449 if (pixel <= (0.0031306684425005883*QuantumRange)) 450 return(12.92f*pixel); 451 return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale* 452 pixel)-0.055)); 453} 454 455/* 456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 457% % 458% % 459% % 460% E x p o r t I m a g e P i x e l s % 461% % 462% % 463% % 464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 465% 466% ExportImagePixels() extracts pixel data from an image and returns it to you. 467% The method returns MagickTrue on success otherwise MagickFalse if an error is 468% encountered. The data is returned as char, short int, Quantum, unsigned int, 469% unsigned long long, float, or double in the order specified by map. 470% 471% Suppose you want to extract the first scanline of a 640x480 image as 472% character data in red-green-blue order: 473% 474% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception); 475% 476% The format of the ExportImagePixels method is: 477% 478% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x, 479% const ssize_t y,const size_t width,const size_t height, 480% const char *map,const StorageType type,void *pixels, 481% ExceptionInfo *exception) 482% 483% A description of each parameter follows: 484% 485% o image: the image. 486% 487% o x,y,width,height: These values define the perimeter 488% of a region of pixels you want to extract. 489% 490% o map: This string reflects the expected ordering of the pixel array. 491% It can be any combination or order of R = red, G = green, B = blue, 492% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan, 493% Y = yellow, M = magenta, K = black, I = intensity (for grayscale), 494% P = pad. 495% 496% o type: Define the data type of the pixels. Float and double types are 497% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these 498% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *), 499% LongPixel (unsigned int *), LongLongPixel (unsigned long long *), 500% QuantumPixel (Quantum *), or ShortPixel (unsigned short *). 501% 502% o pixels: This array of values contain the pixel components as defined by 503% map and type. You must preallocate this array where the expected 504% length varies depending on the values of width, height, map, and type. 505% 506% o exception: return any errors or warnings in this structure. 507% 508*/ 509 510static void ExportCharPixel(const Image *image,const RectangleInfo *roi, 511 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 512 ExceptionInfo *exception) 513{ 514 register const Quantum 515 *magick_restrict p; 516 517 register ssize_t 518 x; 519 520 register unsigned char 521 *magick_restrict q; 522 523 size_t 524 length; 525 526 ssize_t 527 y; 528 529 q=(unsigned char *) pixels; 530 if (LocaleCompare(map,"BGR") == 0) 531 { 532 for (y=0; y < (ssize_t) roi->height; y++) 533 { 534 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 535 if (p == (const Quantum *) NULL) 536 break; 537 for (x=0; x < (ssize_t) roi->width; x++) 538 { 539 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 540 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 541 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 542 p+=GetPixelChannels(image); 543 } 544 } 545 return; 546 } 547 if (LocaleCompare(map,"BGRA") == 0) 548 { 549 for (y=0; y < (ssize_t) roi->height; y++) 550 { 551 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 552 if (p == (const Quantum *) NULL) 553 break; 554 for (x=0; x < (ssize_t) roi->width; x++) 555 { 556 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 557 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 558 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 559 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p)); 560 p+=GetPixelChannels(image); 561 } 562 } 563 return; 564 } 565 if (LocaleCompare(map,"BGRP") == 0) 566 { 567 for (y=0; y < (ssize_t) roi->height; y++) 568 { 569 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 570 if (p == (const Quantum *) NULL) 571 break; 572 for (x=0; x < (ssize_t) roi->width; x++) 573 { 574 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 575 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 576 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 577 *q++=ScaleQuantumToChar((Quantum) 0); 578 p+=GetPixelChannels(image); 579 } 580 } 581 return; 582 } 583 if (LocaleCompare(map,"I") == 0) 584 { 585 for (y=0; y < (ssize_t) roi->height; y++) 586 { 587 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 588 if (p == (const Quantum *) NULL) 589 break; 590 for (x=0; x < (ssize_t) roi->width; x++) 591 { 592 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p))); 593 p+=GetPixelChannels(image); 594 } 595 } 596 return; 597 } 598 if (LocaleCompare(map,"RGB") == 0) 599 { 600 for (y=0; y < (ssize_t) roi->height; y++) 601 { 602 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 603 if (p == (const Quantum *) NULL) 604 break; 605 for (x=0; x < (ssize_t) roi->width; x++) 606 { 607 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 608 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 609 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 610 p+=GetPixelChannels(image); 611 } 612 } 613 return; 614 } 615 if (LocaleCompare(map,"RGBA") == 0) 616 { 617 for (y=0; y < (ssize_t) roi->height; y++) 618 { 619 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 620 if (p == (const Quantum *) NULL) 621 break; 622 for (x=0; x < (ssize_t) roi->width; x++) 623 { 624 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 625 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 626 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 627 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p)); 628 p+=GetPixelChannels(image); 629 } 630 } 631 return; 632 } 633 if (LocaleCompare(map,"RGBP") == 0) 634 { 635 for (y=0; y < (ssize_t) roi->height; y++) 636 { 637 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 638 if (p == (const Quantum *) NULL) 639 break; 640 for (x=0; x < (ssize_t) roi->width; x++) 641 { 642 *q++=ScaleQuantumToChar(GetPixelRed(image,p)); 643 *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); 644 *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); 645 *q++=ScaleQuantumToChar((Quantum) 0); 646 p+=GetPixelChannels(image); 647 } 648 } 649 return; 650 } 651 length=strlen(map); 652 for (y=0; y < (ssize_t) roi->height; y++) 653 { 654 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 655 if (p == (const Quantum *) NULL) 656 break; 657 for (x=0; x < (ssize_t) roi->width; x++) 658 { 659 register ssize_t 660 i; 661 662 for (i=0; i < (ssize_t) length; i++) 663 { 664 *q=0; 665 switch (quantum_map[i]) 666 { 667 case RedQuantum: 668 case CyanQuantum: 669 { 670 *q=ScaleQuantumToChar(GetPixelRed(image,p)); 671 break; 672 } 673 case GreenQuantum: 674 case MagentaQuantum: 675 { 676 *q=ScaleQuantumToChar(GetPixelGreen(image,p)); 677 break; 678 } 679 case BlueQuantum: 680 case YellowQuantum: 681 { 682 *q=ScaleQuantumToChar(GetPixelBlue(image,p)); 683 break; 684 } 685 case AlphaQuantum: 686 { 687 *q=ScaleQuantumToChar(GetPixelAlpha(image,p)); 688 break; 689 } 690 case OpacityQuantum: 691 { 692 *q=ScaleQuantumToChar(GetPixelAlpha(image,p)); 693 break; 694 } 695 case BlackQuantum: 696 { 697 if (image->colorspace == CMYKColorspace) 698 *q=ScaleQuantumToChar(GetPixelBlack(image,p)); 699 break; 700 } 701 case IndexQuantum: 702 { 703 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p))); 704 break; 705 } 706 default: 707 break; 708 } 709 q++; 710 } 711 p+=GetPixelChannels(image); 712 } 713 } 714} 715 716static void ExportDoublePixel(const Image *image,const RectangleInfo *roi, 717 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 718 ExceptionInfo *exception) 719{ 720 register const Quantum 721 *magick_restrict p; 722 723 register double 724 *magick_restrict q; 725 726 register ssize_t 727 x; 728 729 size_t 730 length; 731 732 ssize_t 733 y; 734 735 q=(double *) pixels; 736 if (LocaleCompare(map,"BGR") == 0) 737 { 738 for (y=0; y < (ssize_t) roi->height; y++) 739 { 740 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 741 if (p == (const Quantum *) NULL) 742 break; 743 for (x=0; x < (ssize_t) roi->width; x++) 744 { 745 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 746 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 747 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 748 p+=GetPixelChannels(image); 749 } 750 } 751 return; 752 } 753 if (LocaleCompare(map,"BGRA") == 0) 754 { 755 for (y=0; y < (ssize_t) roi->height; y++) 756 { 757 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 758 if (p == (const Quantum *) NULL) 759 break; 760 for (x=0; x < (ssize_t) roi->width; x++) 761 { 762 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 763 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 764 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 765 *q++=(double) (QuantumScale*GetPixelAlpha(image,p)); 766 p+=GetPixelChannels(image); 767 } 768 } 769 return; 770 } 771 if (LocaleCompare(map,"BGRP") == 0) 772 { 773 for (y=0; y < (ssize_t) roi->height; y++) 774 { 775 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 776 if (p == (const Quantum *) NULL) 777 break; 778 for (x=0; x < (ssize_t) roi->width; x++) 779 { 780 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 781 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 782 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 783 *q++=0.0; 784 p+=GetPixelChannels(image); 785 } 786 } 787 return; 788 } 789 if (LocaleCompare(map,"I") == 0) 790 { 791 for (y=0; y < (ssize_t) roi->height; y++) 792 { 793 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 794 if (p == (const Quantum *) NULL) 795 break; 796 for (x=0; x < (ssize_t) roi->width; x++) 797 { 798 *q++=(double) (QuantumScale*GetPixelIntensity(image,p)); 799 p+=GetPixelChannels(image); 800 } 801 } 802 return; 803 } 804 if (LocaleCompare(map,"RGB") == 0) 805 { 806 for (y=0; y < (ssize_t) roi->height; y++) 807 { 808 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 809 if (p == (const Quantum *) NULL) 810 break; 811 for (x=0; x < (ssize_t) roi->width; x++) 812 { 813 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 814 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 815 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 816 p+=GetPixelChannels(image); 817 } 818 } 819 return; 820 } 821 if (LocaleCompare(map,"RGBA") == 0) 822 { 823 for (y=0; y < (ssize_t) roi->height; y++) 824 { 825 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 826 if (p == (const Quantum *) NULL) 827 break; 828 for (x=0; x < (ssize_t) roi->width; x++) 829 { 830 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 831 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 832 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 833 *q++=(double) (QuantumScale*GetPixelAlpha(image,p)); 834 p+=GetPixelChannels(image); 835 } 836 } 837 return; 838 } 839 if (LocaleCompare(map,"RGBP") == 0) 840 { 841 for (y=0; y < (ssize_t) roi->height; y++) 842 { 843 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 844 if (p == (const Quantum *) NULL) 845 break; 846 for (x=0; x < (ssize_t) roi->width; x++) 847 { 848 *q++=(double) (QuantumScale*GetPixelRed(image,p)); 849 *q++=(double) (QuantumScale*GetPixelGreen(image,p)); 850 *q++=(double) (QuantumScale*GetPixelBlue(image,p)); 851 *q++=0.0; 852 p+=GetPixelChannels(image); 853 } 854 } 855 return; 856 } 857 length=strlen(map); 858 for (y=0; y < (ssize_t) roi->height; y++) 859 { 860 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 861 if (p == (const Quantum *) NULL) 862 break; 863 for (x=0; x < (ssize_t) roi->width; x++) 864 { 865 register ssize_t 866 i; 867 868 for (i=0; i < (ssize_t) length; i++) 869 { 870 *q=0; 871 switch (quantum_map[i]) 872 { 873 case RedQuantum: 874 case CyanQuantum: 875 { 876 *q=(double) (QuantumScale*GetPixelRed(image,p)); 877 break; 878 } 879 case GreenQuantum: 880 case MagentaQuantum: 881 { 882 *q=(double) (QuantumScale*GetPixelGreen(image,p)); 883 break; 884 } 885 case BlueQuantum: 886 case YellowQuantum: 887 { 888 *q=(double) (QuantumScale*GetPixelBlue(image,p)); 889 break; 890 } 891 case AlphaQuantum: 892 { 893 *q=(double) (QuantumScale*GetPixelAlpha(image,p)); 894 break; 895 } 896 case OpacityQuantum: 897 { 898 *q=(double) (QuantumScale*GetPixelAlpha(image,p)); 899 break; 900 } 901 case BlackQuantum: 902 { 903 if (image->colorspace == CMYKColorspace) 904 *q=(double) (QuantumScale* 905 GetPixelBlack(image,p)); 906 break; 907 } 908 case IndexQuantum: 909 { 910 *q=(double) (QuantumScale*GetPixelIntensity(image,p)); 911 break; 912 } 913 default: 914 *q=0; 915 } 916 q++; 917 } 918 p+=GetPixelChannels(image); 919 } 920 } 921} 922 923static void ExportFloatPixel(const Image *image,const RectangleInfo *roi, 924 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 925 ExceptionInfo *exception) 926{ 927 register const Quantum 928 *magick_restrict p; 929 930 register float 931 *magick_restrict q; 932 933 register ssize_t 934 x; 935 936 size_t 937 length; 938 939 ssize_t 940 y; 941 942 q=(float *) pixels; 943 if (LocaleCompare(map,"BGR") == 0) 944 { 945 for (y=0; y < (ssize_t) roi->height; y++) 946 { 947 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 948 if (p == (const Quantum *) NULL) 949 break; 950 for (x=0; x < (ssize_t) roi->width; x++) 951 { 952 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 953 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 954 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 955 p+=GetPixelChannels(image); 956 } 957 } 958 return; 959 } 960 if (LocaleCompare(map,"BGRA") == 0) 961 { 962 for (y=0; y < (ssize_t) roi->height; y++) 963 { 964 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 965 if (p == (const Quantum *) NULL) 966 break; 967 for (x=0; x < (ssize_t) roi->width; x++) 968 { 969 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 970 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 971 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 972 *q++=(float) (QuantumScale*GetPixelAlpha(image,p)); 973 p+=GetPixelChannels(image); 974 } 975 } 976 return; 977 } 978 if (LocaleCompare(map,"BGRP") == 0) 979 { 980 for (y=0; y < (ssize_t) roi->height; y++) 981 { 982 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 983 if (p == (const Quantum *) NULL) 984 break; 985 for (x=0; x < (ssize_t) roi->width; x++) 986 { 987 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 988 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 989 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 990 *q++=0.0; 991 p+=GetPixelChannels(image); 992 } 993 } 994 return; 995 } 996 if (LocaleCompare(map,"I") == 0) 997 { 998 for (y=0; y < (ssize_t) roi->height; y++) 999 { 1000 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1001 if (p == (const Quantum *) NULL) 1002 break; 1003 for (x=0; x < (ssize_t) roi->width; x++) 1004 { 1005 *q++=(float) (QuantumScale*GetPixelIntensity(image,p)); 1006 p+=GetPixelChannels(image); 1007 } 1008 } 1009 return; 1010 } 1011 if (LocaleCompare(map,"RGB") == 0) 1012 { 1013 for (y=0; y < (ssize_t) roi->height; y++) 1014 { 1015 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1016 if (p == (const Quantum *) NULL) 1017 break; 1018 for (x=0; x < (ssize_t) roi->width; x++) 1019 { 1020 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 1021 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 1022 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 1023 p+=GetPixelChannels(image); 1024 } 1025 } 1026 return; 1027 } 1028 if (LocaleCompare(map,"RGBA") == 0) 1029 { 1030 for (y=0; y < (ssize_t) roi->height; y++) 1031 { 1032 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1033 if (p == (const Quantum *) NULL) 1034 break; 1035 for (x=0; x < (ssize_t) roi->width; x++) 1036 { 1037 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 1038 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 1039 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 1040 *q++=(float) (QuantumScale*GetPixelAlpha(image,p)); 1041 p+=GetPixelChannels(image); 1042 } 1043 } 1044 return; 1045 } 1046 if (LocaleCompare(map,"RGBP") == 0) 1047 { 1048 for (y=0; y < (ssize_t) roi->height; y++) 1049 { 1050 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1051 if (p == (const Quantum *) NULL) 1052 break; 1053 for (x=0; x < (ssize_t) roi->width; x++) 1054 { 1055 *q++=(float) (QuantumScale*GetPixelRed(image,p)); 1056 *q++=(float) (QuantumScale*GetPixelGreen(image,p)); 1057 *q++=(float) (QuantumScale*GetPixelBlue(image,p)); 1058 *q++=0.0; 1059 p+=GetPixelChannels(image); 1060 } 1061 } 1062 return; 1063 } 1064 length=strlen(map); 1065 for (y=0; y < (ssize_t) roi->height; y++) 1066 { 1067 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1068 if (p == (const Quantum *) NULL) 1069 break; 1070 for (x=0; x < (ssize_t) roi->width; x++) 1071 { 1072 register ssize_t 1073 i; 1074 1075 for (i=0; i < (ssize_t) length; i++) 1076 { 1077 *q=0; 1078 switch (quantum_map[i]) 1079 { 1080 case RedQuantum: 1081 case CyanQuantum: 1082 { 1083 *q=(float) (QuantumScale*GetPixelRed(image,p)); 1084 break; 1085 } 1086 case GreenQuantum: 1087 case MagentaQuantum: 1088 { 1089 *q=(float) (QuantumScale*GetPixelGreen(image,p)); 1090 break; 1091 } 1092 case BlueQuantum: 1093 case YellowQuantum: 1094 { 1095 *q=(float) (QuantumScale*GetPixelBlue(image,p)); 1096 break; 1097 } 1098 case AlphaQuantum: 1099 { 1100 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p)))); 1101 break; 1102 } 1103 case OpacityQuantum: 1104 { 1105 *q=(float) (QuantumScale*GetPixelAlpha(image,p)); 1106 break; 1107 } 1108 case BlackQuantum: 1109 { 1110 if (image->colorspace == CMYKColorspace) 1111 *q=(float) (QuantumScale* GetPixelBlack(image,p)); 1112 break; 1113 } 1114 case IndexQuantum: 1115 { 1116 *q=(float) (QuantumScale*GetPixelIntensity(image,p)); 1117 break; 1118 } 1119 default: 1120 *q=0; 1121 } 1122 q++; 1123 } 1124 p+=GetPixelChannels(image); 1125 } 1126 } 1127} 1128 1129static void ExportLongPixel(const Image *image,const RectangleInfo *roi, 1130 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 1131 ExceptionInfo *exception) 1132{ 1133 register const Quantum 1134 *magick_restrict p; 1135 1136 register ssize_t 1137 x; 1138 1139 register unsigned int 1140 *magick_restrict q; 1141 1142 size_t 1143 length; 1144 1145 ssize_t 1146 y; 1147 1148 q=(unsigned int *) pixels; 1149 if (LocaleCompare(map,"BGR") == 0) 1150 { 1151 for (y=0; y < (ssize_t) roi->height; y++) 1152 { 1153 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1154 if (p == (const Quantum *) NULL) 1155 break; 1156 for (x=0; x < (ssize_t) roi->width; x++) 1157 { 1158 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1159 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1160 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1161 p+=GetPixelChannels(image); 1162 } 1163 } 1164 return; 1165 } 1166 if (LocaleCompare(map,"BGRA") == 0) 1167 { 1168 for (y=0; y < (ssize_t) roi->height; y++) 1169 { 1170 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1171 if (p == (const Quantum *) NULL) 1172 break; 1173 for (x=0; x < (ssize_t) roi->width; x++) 1174 { 1175 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1176 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1177 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1178 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p)); 1179 p+=GetPixelChannels(image); 1180 } 1181 } 1182 return; 1183 } 1184 if (LocaleCompare(map,"BGRP") == 0) 1185 { 1186 for (y=0; y < (ssize_t) roi->height; y++) 1187 { 1188 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1189 if (p == (const Quantum *) NULL) 1190 break; 1191 for (x=0; x < (ssize_t) roi->width; x++) 1192 { 1193 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1194 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1195 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1196 *q++=0; 1197 p+=GetPixelChannels(image); 1198 } 1199 } 1200 return; 1201 } 1202 if (LocaleCompare(map,"I") == 0) 1203 { 1204 for (y=0; y < (ssize_t) roi->height; y++) 1205 { 1206 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1207 if (p == (const Quantum *) NULL) 1208 break; 1209 for (x=0; x < (ssize_t) roi->width; x++) 1210 { 1211 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p))); 1212 p+=GetPixelChannels(image); 1213 } 1214 } 1215 return; 1216 } 1217 if (LocaleCompare(map,"RGB") == 0) 1218 { 1219 for (y=0; y < (ssize_t) roi->height; y++) 1220 { 1221 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1222 if (p == (const Quantum *) NULL) 1223 break; 1224 for (x=0; x < (ssize_t) roi->width; x++) 1225 { 1226 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1227 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1228 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1229 p+=GetPixelChannels(image); 1230 } 1231 } 1232 return; 1233 } 1234 if (LocaleCompare(map,"RGBA") == 0) 1235 { 1236 for (y=0; y < (ssize_t) roi->height; y++) 1237 { 1238 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1239 if (p == (const Quantum *) NULL) 1240 break; 1241 for (x=0; x < (ssize_t) roi->width; x++) 1242 { 1243 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1244 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1245 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1246 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p)); 1247 p+=GetPixelChannels(image); 1248 } 1249 } 1250 return; 1251 } 1252 if (LocaleCompare(map,"RGBP") == 0) 1253 { 1254 for (y=0; y < (ssize_t) roi->height; y++) 1255 { 1256 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1257 if (p == (const Quantum *) NULL) 1258 break; 1259 for (x=0; x < (ssize_t) roi->width; x++) 1260 { 1261 *q++=ScaleQuantumToLong(GetPixelRed(image,p)); 1262 *q++=ScaleQuantumToLong(GetPixelGreen(image,p)); 1263 *q++=ScaleQuantumToLong(GetPixelBlue(image,p)); 1264 *q++=0; 1265 p+=GetPixelChannels(image); 1266 } 1267 } 1268 return; 1269 } 1270 length=strlen(map); 1271 for (y=0; y < (ssize_t) roi->height; y++) 1272 { 1273 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1274 if (p == (const Quantum *) NULL) 1275 break; 1276 for (x=0; x < (ssize_t) roi->width; x++) 1277 { 1278 register ssize_t 1279 i; 1280 1281 for (i=0; i < (ssize_t) length; i++) 1282 { 1283 *q=0; 1284 switch (quantum_map[i]) 1285 { 1286 case RedQuantum: 1287 case CyanQuantum: 1288 { 1289 *q=ScaleQuantumToLong(GetPixelRed(image,p)); 1290 break; 1291 } 1292 case GreenQuantum: 1293 case MagentaQuantum: 1294 { 1295 *q=ScaleQuantumToLong(GetPixelGreen(image,p)); 1296 break; 1297 } 1298 case BlueQuantum: 1299 case YellowQuantum: 1300 { 1301 *q=ScaleQuantumToLong(GetPixelBlue(image,p)); 1302 break; 1303 } 1304 case AlphaQuantum: 1305 { 1306 *q=ScaleQuantumToLong(GetPixelAlpha(image,p)); 1307 break; 1308 } 1309 case OpacityQuantum: 1310 { 1311 *q=ScaleQuantumToLong(GetPixelAlpha(image,p)); 1312 break; 1313 } 1314 case BlackQuantum: 1315 { 1316 if (image->colorspace == CMYKColorspace) 1317 *q=ScaleQuantumToLong(GetPixelBlack(image,p)); 1318 break; 1319 } 1320 case IndexQuantum: 1321 { 1322 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p))); 1323 break; 1324 } 1325 default: 1326 break; 1327 } 1328 q++; 1329 } 1330 p+=GetPixelChannels(image); 1331 } 1332 } 1333} 1334 1335static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi, 1336 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 1337 ExceptionInfo *exception) 1338{ 1339 register const Quantum 1340 *magick_restrict p; 1341 1342 register ssize_t 1343 x; 1344 1345 register MagickSizeType 1346 *magick_restrict q; 1347 1348 size_t 1349 length; 1350 1351 ssize_t 1352 y; 1353 1354 q=(MagickSizeType *) pixels; 1355 if (LocaleCompare(map,"BGR") == 0) 1356 { 1357 for (y=0; y < (ssize_t) roi->height; y++) 1358 { 1359 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1360 if (p == (const Quantum *) NULL) 1361 break; 1362 for (x=0; x < (ssize_t) roi->width; x++) 1363 { 1364 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1365 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1366 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1367 p+=GetPixelChannels(image); 1368 } 1369 } 1370 return; 1371 } 1372 if (LocaleCompare(map,"BGRA") == 0) 1373 { 1374 for (y=0; y < (ssize_t) roi->height; y++) 1375 { 1376 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1377 if (p == (const Quantum *) NULL) 1378 break; 1379 for (x=0; x < (ssize_t) roi->width; x++) 1380 { 1381 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1382 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1383 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1384 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); 1385 p+=GetPixelChannels(image); 1386 } 1387 } 1388 return; 1389 } 1390 if (LocaleCompare(map,"BGRP") == 0) 1391 { 1392 for (y=0; y < (ssize_t) roi->height; y++) 1393 { 1394 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1395 if (p == (const Quantum *) NULL) 1396 break; 1397 for (x=0; x < (ssize_t) roi->width; x++) 1398 { 1399 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1400 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1401 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1402 *q++=0; 1403 p+=GetPixelChannels(image); 1404 } 1405 } 1406 return; 1407 } 1408 if (LocaleCompare(map,"I") == 0) 1409 { 1410 for (y=0; y < (ssize_t) roi->height; y++) 1411 { 1412 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1413 if (p == (const Quantum *) NULL) 1414 break; 1415 for (x=0; x < (ssize_t) roi->width; x++) 1416 { 1417 *q++=ScaleQuantumToLongLong(ClampToQuantum( 1418 GetPixelIntensity(image,p))); 1419 p+=GetPixelChannels(image); 1420 } 1421 } 1422 return; 1423 } 1424 if (LocaleCompare(map,"RGB") == 0) 1425 { 1426 for (y=0; y < (ssize_t) roi->height; y++) 1427 { 1428 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1429 if (p == (const Quantum *) NULL) 1430 break; 1431 for (x=0; x < (ssize_t) roi->width; x++) 1432 { 1433 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1434 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1435 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1436 p+=GetPixelChannels(image); 1437 } 1438 } 1439 return; 1440 } 1441 if (LocaleCompare(map,"RGBA") == 0) 1442 { 1443 for (y=0; y < (ssize_t) roi->height; y++) 1444 { 1445 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1446 if (p == (const Quantum *) NULL) 1447 break; 1448 for (x=0; x < (ssize_t) roi->width; x++) 1449 { 1450 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1451 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1452 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1453 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); 1454 p+=GetPixelChannels(image); 1455 } 1456 } 1457 return; 1458 } 1459 if (LocaleCompare(map,"RGBP") == 0) 1460 { 1461 for (y=0; y < (ssize_t) roi->height; y++) 1462 { 1463 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1464 if (p == (const Quantum *) NULL) 1465 break; 1466 for (x=0; x < (ssize_t) roi->width; x++) 1467 { 1468 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1469 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1470 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1471 *q++=0; 1472 p+=GetPixelChannels(image); 1473 } 1474 } 1475 return; 1476 } 1477 length=strlen(map); 1478 for (y=0; y < (ssize_t) roi->height; y++) 1479 { 1480 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1481 if (p == (const Quantum *) NULL) 1482 break; 1483 for (x=0; x < (ssize_t) roi->width; x++) 1484 { 1485 register ssize_t 1486 i; 1487 1488 for (i=0; i < (ssize_t) length; i++) 1489 { 1490 *q=0; 1491 switch (quantum_map[i]) 1492 { 1493 case RedQuantum: 1494 case CyanQuantum: 1495 { 1496 *q=ScaleQuantumToLongLong(GetPixelRed(image,p)); 1497 break; 1498 } 1499 case GreenQuantum: 1500 case MagentaQuantum: 1501 { 1502 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p)); 1503 break; 1504 } 1505 case BlueQuantum: 1506 case YellowQuantum: 1507 { 1508 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p)); 1509 break; 1510 } 1511 case AlphaQuantum: 1512 { 1513 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); 1514 break; 1515 } 1516 case OpacityQuantum: 1517 { 1518 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p)); 1519 break; 1520 } 1521 case BlackQuantum: 1522 { 1523 if (image->colorspace == CMYKColorspace) 1524 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p)); 1525 break; 1526 } 1527 case IndexQuantum: 1528 { 1529 *q=ScaleQuantumToLongLong(ClampToQuantum( 1530 GetPixelIntensity(image,p))); 1531 break; 1532 } 1533 default: 1534 break; 1535 } 1536 q++; 1537 } 1538 p+=GetPixelChannels(image); 1539 } 1540 } 1541} 1542 1543static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi, 1544 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 1545 ExceptionInfo *exception) 1546{ 1547 register const Quantum 1548 *magick_restrict p; 1549 1550 register Quantum 1551 *magick_restrict q; 1552 1553 register ssize_t 1554 x; 1555 1556 size_t 1557 length; 1558 1559 ssize_t 1560 y; 1561 1562 q=(Quantum *) pixels; 1563 if (LocaleCompare(map,"BGR") == 0) 1564 { 1565 for (y=0; y < (ssize_t) roi->height; y++) 1566 { 1567 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1568 if (p == (const Quantum *) NULL) 1569 break; 1570 for (x=0; x < (ssize_t) roi->width; x++) 1571 { 1572 *q++=GetPixelBlue(image,p); 1573 *q++=GetPixelGreen(image,p); 1574 *q++=GetPixelRed(image,p); 1575 p+=GetPixelChannels(image); 1576 } 1577 } 1578 return; 1579 } 1580 if (LocaleCompare(map,"BGRA") == 0) 1581 { 1582 for (y=0; y < (ssize_t) roi->height; y++) 1583 { 1584 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1585 if (p == (const Quantum *) NULL) 1586 break; 1587 for (x=0; x < (ssize_t) roi->width; x++) 1588 { 1589 *q++=GetPixelBlue(image,p); 1590 *q++=GetPixelGreen(image,p); 1591 *q++=GetPixelRed(image,p); 1592 *q++=(Quantum) (GetPixelAlpha(image,p)); 1593 p+=GetPixelChannels(image); 1594 } 1595 } 1596 return; 1597 } 1598 if (LocaleCompare(map,"BGRP") == 0) 1599 { 1600 for (y=0; y < (ssize_t) roi->height; y++) 1601 { 1602 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1603 if (p == (const Quantum *) NULL) 1604 break; 1605 for (x=0; x < (ssize_t) roi->width; x++) 1606 { 1607 *q++=GetPixelBlue(image,p); 1608 *q++=GetPixelGreen(image,p); 1609 *q++=GetPixelRed(image,p); 1610 *q++=(Quantum) 0; 1611 p+=GetPixelChannels(image); 1612 } 1613 } 1614 return; 1615 } 1616 if (LocaleCompare(map,"I") == 0) 1617 { 1618 for (y=0; y < (ssize_t) roi->height; y++) 1619 { 1620 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1621 if (p == (const Quantum *) NULL) 1622 break; 1623 for (x=0; x < (ssize_t) roi->width; x++) 1624 { 1625 *q++=ClampToQuantum(GetPixelIntensity(image,p)); 1626 p+=GetPixelChannels(image); 1627 } 1628 } 1629 return; 1630 } 1631 if (LocaleCompare(map,"RGB") == 0) 1632 { 1633 for (y=0; y < (ssize_t) roi->height; y++) 1634 { 1635 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1636 if (p == (const Quantum *) NULL) 1637 break; 1638 for (x=0; x < (ssize_t) roi->width; x++) 1639 { 1640 *q++=GetPixelRed(image,p); 1641 *q++=GetPixelGreen(image,p); 1642 *q++=GetPixelBlue(image,p); 1643 p+=GetPixelChannels(image); 1644 } 1645 } 1646 return; 1647 } 1648 if (LocaleCompare(map,"RGBA") == 0) 1649 { 1650 for (y=0; y < (ssize_t) roi->height; y++) 1651 { 1652 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1653 if (p == (const Quantum *) NULL) 1654 break; 1655 for (x=0; x < (ssize_t) roi->width; x++) 1656 { 1657 *q++=GetPixelRed(image,p); 1658 *q++=GetPixelGreen(image,p); 1659 *q++=GetPixelBlue(image,p); 1660 *q++=(Quantum) (GetPixelAlpha(image,p)); 1661 p+=GetPixelChannels(image); 1662 } 1663 } 1664 return; 1665 } 1666 if (LocaleCompare(map,"RGBP") == 0) 1667 { 1668 for (y=0; y < (ssize_t) roi->height; y++) 1669 { 1670 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1671 if (p == (const Quantum *) NULL) 1672 break; 1673 for (x=0; x < (ssize_t) roi->width; x++) 1674 { 1675 *q++=GetPixelRed(image,p); 1676 *q++=GetPixelGreen(image,p); 1677 *q++=GetPixelBlue(image,p); 1678 *q++=(Quantum) 0; 1679 p+=GetPixelChannels(image); 1680 } 1681 } 1682 return; 1683 } 1684 length=strlen(map); 1685 for (y=0; y < (ssize_t) roi->height; y++) 1686 { 1687 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1688 if (p == (const Quantum *) NULL) 1689 break; 1690 for (x=0; x < (ssize_t) roi->width; x++) 1691 { 1692 register ssize_t 1693 i; 1694 1695 for (i=0; i < (ssize_t) length; i++) 1696 { 1697 *q=(Quantum) 0; 1698 switch (quantum_map[i]) 1699 { 1700 case RedQuantum: 1701 case CyanQuantum: 1702 { 1703 *q=GetPixelRed(image,p); 1704 break; 1705 } 1706 case GreenQuantum: 1707 case MagentaQuantum: 1708 { 1709 *q=GetPixelGreen(image,p); 1710 break; 1711 } 1712 case BlueQuantum: 1713 case YellowQuantum: 1714 { 1715 *q=GetPixelBlue(image,p); 1716 break; 1717 } 1718 case AlphaQuantum: 1719 { 1720 *q=GetPixelAlpha(image,p); 1721 break; 1722 } 1723 case OpacityQuantum: 1724 { 1725 *q=GetPixelAlpha(image,p); 1726 break; 1727 } 1728 case BlackQuantum: 1729 { 1730 if (image->colorspace == CMYKColorspace) 1731 *q=GetPixelBlack(image,p); 1732 break; 1733 } 1734 case IndexQuantum: 1735 { 1736 *q=ClampToQuantum(GetPixelIntensity(image,p)); 1737 break; 1738 } 1739 default: 1740 { 1741 *q=(Quantum) 0; 1742 break; 1743 } 1744 } 1745 q++; 1746 } 1747 p+=GetPixelChannels(image); 1748 } 1749 } 1750} 1751 1752static void ExportShortPixel(const Image *image,const RectangleInfo *roi, 1753 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels, 1754 ExceptionInfo *exception) 1755{ 1756 register const Quantum 1757 *magick_restrict p; 1758 1759 register ssize_t 1760 x; 1761 1762 register unsigned short 1763 *magick_restrict q; 1764 1765 size_t 1766 length; 1767 1768 ssize_t 1769 y; 1770 1771 q=(unsigned short *) pixels; 1772 if (LocaleCompare(map,"BGR") == 0) 1773 { 1774 for (y=0; y < (ssize_t) roi->height; y++) 1775 { 1776 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1777 if (p == (const Quantum *) NULL) 1778 break; 1779 for (x=0; x < (ssize_t) roi->width; x++) 1780 { 1781 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1782 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1783 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1784 p+=GetPixelChannels(image); 1785 } 1786 } 1787 return; 1788 } 1789 if (LocaleCompare(map,"BGRA") == 0) 1790 { 1791 for (y=0; y < (ssize_t) roi->height; y++) 1792 { 1793 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1794 if (p == (const Quantum *) NULL) 1795 break; 1796 for (x=0; x < (ssize_t) roi->width; x++) 1797 { 1798 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1799 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1800 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1801 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p)); 1802 p+=GetPixelChannels(image); 1803 } 1804 } 1805 return; 1806 } 1807 if (LocaleCompare(map,"BGRP") == 0) 1808 { 1809 for (y=0; y < (ssize_t) roi->height; y++) 1810 { 1811 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1812 if (p == (const Quantum *) NULL) 1813 break; 1814 for (x=0; x < (ssize_t) roi->width; x++) 1815 { 1816 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1817 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1818 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1819 *q++=0; 1820 p+=GetPixelChannels(image); 1821 } 1822 } 1823 return; 1824 } 1825 if (LocaleCompare(map,"I") == 0) 1826 { 1827 for (y=0; y < (ssize_t) roi->height; y++) 1828 { 1829 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1830 if (p == (const Quantum *) NULL) 1831 break; 1832 for (x=0; x < (ssize_t) roi->width; x++) 1833 { 1834 *q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p))); 1835 p+=GetPixelChannels(image); 1836 } 1837 } 1838 return; 1839 } 1840 if (LocaleCompare(map,"RGB") == 0) 1841 { 1842 for (y=0; y < (ssize_t) roi->height; y++) 1843 { 1844 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1845 if (p == (const Quantum *) NULL) 1846 break; 1847 for (x=0; x < (ssize_t) roi->width; x++) 1848 { 1849 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1850 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1851 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1852 p+=GetPixelChannels(image); 1853 } 1854 } 1855 return; 1856 } 1857 if (LocaleCompare(map,"RGBA") == 0) 1858 { 1859 for (y=0; y < (ssize_t) roi->height; y++) 1860 { 1861 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1862 if (p == (const Quantum *) NULL) 1863 break; 1864 for (x=0; x < (ssize_t) roi->width; x++) 1865 { 1866 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1867 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1868 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1869 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p)); 1870 p+=GetPixelChannels(image); 1871 } 1872 } 1873 return; 1874 } 1875 if (LocaleCompare(map,"RGBP") == 0) 1876 { 1877 for (y=0; y < (ssize_t) roi->height; y++) 1878 { 1879 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1880 if (p == (const Quantum *) NULL) 1881 break; 1882 for (x=0; x < (ssize_t) roi->width; x++) 1883 { 1884 *q++=ScaleQuantumToShort(GetPixelRed(image,p)); 1885 *q++=ScaleQuantumToShort(GetPixelGreen(image,p)); 1886 *q++=ScaleQuantumToShort(GetPixelBlue(image,p)); 1887 *q++=0; 1888 p+=GetPixelChannels(image); 1889 } 1890 } 1891 return; 1892 } 1893 length=strlen(map); 1894 for (y=0; y < (ssize_t) roi->height; y++) 1895 { 1896 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception); 1897 if (p == (const Quantum *) NULL) 1898 break; 1899 for (x=0; x < (ssize_t) roi->width; x++) 1900 { 1901 register ssize_t 1902 i; 1903 1904 for (i=0; i < (ssize_t) length; i++) 1905 { 1906 *q=0; 1907 switch (quantum_map[i]) 1908 { 1909 case RedQuantum: 1910 case CyanQuantum: 1911 { 1912 *q=ScaleQuantumToShort(GetPixelRed(image,p)); 1913 break; 1914 } 1915 case GreenQuantum: 1916 case MagentaQuantum: 1917 { 1918 *q=ScaleQuantumToShort(GetPixelGreen(image,p)); 1919 break; 1920 } 1921 case BlueQuantum: 1922 case YellowQuantum: 1923 { 1924 *q=ScaleQuantumToShort(GetPixelBlue(image,p)); 1925 break; 1926 } 1927 case AlphaQuantum: 1928 { 1929 *q=ScaleQuantumToShort(GetPixelAlpha(image,p)); 1930 break; 1931 } 1932 case OpacityQuantum: 1933 { 1934 *q=ScaleQuantumToShort(GetPixelAlpha(image,p)); 1935 break; 1936 } 1937 case BlackQuantum: 1938 { 1939 if (image->colorspace == CMYKColorspace) 1940 *q=ScaleQuantumToShort(GetPixelBlack(image,p)); 1941 break; 1942 } 1943 case IndexQuantum: 1944 { 1945 *q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p))); 1946 break; 1947 } 1948 default: 1949 break; 1950 } 1951 q++; 1952 } 1953 p+=GetPixelChannels(image); 1954 } 1955 } 1956} 1957 1958MagickExport MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x, 1959 const ssize_t y,const size_t width,const size_t height,const char *map, 1960 const StorageType type,void *pixels,ExceptionInfo *exception) 1961{ 1962 QuantumType 1963 *quantum_map; 1964 1965 RectangleInfo 1966 roi; 1967 1968 register ssize_t 1969 i; 1970 1971 size_t 1972 length; 1973 1974 assert(image != (Image *) NULL); 1975 assert(image->signature == MagickCoreSignature); 1976 if (image->debug != MagickFalse) 1977 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1978 length=strlen(map); 1979 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map)); 1980 if (quantum_map == (QuantumType *) NULL) 1981 { 1982 (void) ThrowMagickException(exception,GetMagickModule(), 1983 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); 1984 return(MagickFalse); 1985 } 1986 for (i=0; i < (ssize_t) length; i++) 1987 { 1988 switch (map[i]) 1989 { 1990 case 'A': 1991 case 'a': 1992 { 1993 quantum_map[i]=AlphaQuantum; 1994 break; 1995 } 1996 case 'B': 1997 case 'b': 1998 { 1999 quantum_map[i]=BlueQuantum; 2000 break; 2001 } 2002 case 'C': 2003 case 'c': 2004 { 2005 quantum_map[i]=CyanQuantum; 2006 if (image->colorspace == CMYKColorspace) 2007 break; 2008 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2009 (void) ThrowMagickException(exception,GetMagickModule(),ImageError, 2010 "ColorSeparatedImageRequired","`%s'",map); 2011 return(MagickFalse); 2012 } 2013 case 'g': 2014 case 'G': 2015 { 2016 quantum_map[i]=GreenQuantum; 2017 break; 2018 } 2019 case 'I': 2020 case 'i': 2021 { 2022 quantum_map[i]=IndexQuantum; 2023 break; 2024 } 2025 case 'K': 2026 case 'k': 2027 { 2028 quantum_map[i]=BlackQuantum; 2029 if (image->colorspace == CMYKColorspace) 2030 break; 2031 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2032 (void) ThrowMagickException(exception,GetMagickModule(),ImageError, 2033 "ColorSeparatedImageRequired","`%s'",map); 2034 return(MagickFalse); 2035 } 2036 case 'M': 2037 case 'm': 2038 { 2039 quantum_map[i]=MagentaQuantum; 2040 if (image->colorspace == CMYKColorspace) 2041 break; 2042 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2043 (void) ThrowMagickException(exception,GetMagickModule(),ImageError, 2044 "ColorSeparatedImageRequired","`%s'",map); 2045 return(MagickFalse); 2046 } 2047 case 'o': 2048 case 'O': 2049 { 2050 quantum_map[i]=OpacityQuantum; 2051 break; 2052 } 2053 case 'P': 2054 case 'p': 2055 { 2056 quantum_map[i]=UndefinedQuantum; 2057 break; 2058 } 2059 case 'R': 2060 case 'r': 2061 { 2062 quantum_map[i]=RedQuantum; 2063 break; 2064 } 2065 case 'Y': 2066 case 'y': 2067 { 2068 quantum_map[i]=YellowQuantum; 2069 if (image->colorspace == CMYKColorspace) 2070 break; 2071 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2072 (void) ThrowMagickException(exception,GetMagickModule(),ImageError, 2073 "ColorSeparatedImageRequired","`%s'",map); 2074 return(MagickFalse); 2075 } 2076 default: 2077 { 2078 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2079 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 2080 "UnrecognizedPixelMap","`%s'",map); 2081 return(MagickFalse); 2082 } 2083 } 2084 } 2085 roi.width=width; 2086 roi.height=height; 2087 roi.x=x; 2088 roi.y=y; 2089 switch (type) 2090 { 2091 case CharPixel: 2092 { 2093 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception); 2094 break; 2095 } 2096 case DoublePixel: 2097 { 2098 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception); 2099 break; 2100 } 2101 case FloatPixel: 2102 { 2103 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception); 2104 break; 2105 } 2106 case LongPixel: 2107 { 2108 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception); 2109 break; 2110 } 2111 case LongLongPixel: 2112 { 2113 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception); 2114 break; 2115 } 2116 case QuantumPixel: 2117 { 2118 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception); 2119 break; 2120 } 2121 case ShortPixel: 2122 { 2123 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception); 2124 break; 2125 } 2126 default: 2127 { 2128 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2129 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 2130 "UnrecognizedPixelMap","`%s'",map); 2131 break; 2132 } 2133 } 2134 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 2135 return(MagickTrue); 2136} 2137 2138/* 2139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2140% % 2141% % 2142% % 2143% G e t P i x e l I n f o % 2144% % 2145% % 2146% % 2147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2148% 2149% GetPixelInfo() initializes the PixelInfo structure. 2150% 2151% The format of the GetPixelInfo method is: 2152% 2153% GetPixelInfo(const Image *image,PixelInfo *pixel) 2154% 2155% A description of each parameter follows: 2156% 2157% o image: the image. (optional - may be NULL) 2158% 2159% o pixel: Specifies a pointer to a PixelInfo structure. 2160% 2161*/ 2162MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel) 2163{ 2164 pixel->storage_class=DirectClass; 2165 pixel->colorspace=sRGBColorspace; 2166 pixel->alpha_trait=UndefinedPixelTrait; 2167 pixel->fuzz=0.0; 2168 pixel->depth=MAGICKCORE_QUANTUM_DEPTH; 2169 pixel->red=0.0; 2170 pixel->green=0.0; 2171 pixel->blue=0.0; 2172 pixel->black=0.0; 2173 pixel->alpha=(double) OpaqueAlpha; 2174 pixel->index=0.0; 2175 pixel->count=0; 2176 pixel->fuzz=0.0; 2177 if (image == (const Image *) NULL) 2178 return; 2179 pixel->storage_class=image->storage_class; 2180 pixel->colorspace=image->colorspace; 2181 pixel->alpha_trait=image->alpha_trait; 2182 pixel->depth=image->depth; 2183 pixel->fuzz=image->fuzz; 2184} 2185 2186/* 2187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2188% % 2189% % 2190% % 2191% G e t P i x e l I n d o I n t e n s i t y % 2192% % 2193% % 2194% % 2195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2196% 2197% GetPixelInfoIntensity() returns a single sample intensity value from the red, 2198% green, and blue components of a pixel based on the selected method: 2199% 2200% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B' 2201% Rec601Luminance 0.298839R + 0.586811G + 0.114350B 2202% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B' 2203% Rec709Luminance 0.212656R + 0.715158G + 0.072186B 2204% Brightness max(R', G', B') 2205% Lightness (min(R', G', B') + max(R', G', B')) / 2.0 2206% 2207% MS (R^2 + G^2 + B^2) / 3.0 2208% RMS sqrt((R^2 + G^2 + B^2) / 3.0 2209% Average (R + G + B') / 3.0 2210% 2211% The format of the GetPixelInfoIntensity method is: 2212% 2213% MagickRealType GetPixelInfoIntensity(const Image *image, 2214% const Quantum *pixel) 2215% 2216% A description of each parameter follows: 2217% 2218% o image: the image. 2219% 2220% o pixel: Specifies a pointer to a Quantum structure. 2221% 2222*/ 2223MagickExport MagickRealType GetPixelInfoIntensity( 2224 const Image *magick_restrict image,const PixelInfo *magick_restrict pixel) 2225{ 2226 MagickRealType 2227 blue, 2228 green, 2229 red, 2230 intensity; 2231 2232 PixelIntensityMethod 2233 method; 2234 2235 method=Rec709LumaPixelIntensityMethod; 2236 if (image != (const Image *) NULL) 2237 method=image->intensity; 2238 red=pixel->red; 2239 green=pixel->green; 2240 blue=pixel->blue; 2241 switch (method) 2242 { 2243 case AveragePixelIntensityMethod: 2244 { 2245 intensity=(red+green+blue)/3.0; 2246 break; 2247 } 2248 case BrightnessPixelIntensityMethod: 2249 { 2250 intensity=MagickMax(MagickMax(red,green),blue); 2251 break; 2252 } 2253 case LightnessPixelIntensityMethod: 2254 { 2255 intensity=(MagickMin(MagickMin(red,green),blue)+ 2256 MagickMax(MagickMax(red,green),blue))/2.0; 2257 break; 2258 } 2259 case MSPixelIntensityMethod: 2260 { 2261 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/ 2262 (3.0*QuantumRange)); 2263 break; 2264 } 2265 case Rec601LumaPixelIntensityMethod: 2266 { 2267 if (pixel->colorspace == RGBColorspace) 2268 { 2269 red=EncodePixelGamma(red); 2270 green=EncodePixelGamma(green); 2271 blue=EncodePixelGamma(blue); 2272 } 2273 intensity=0.298839*red+0.586811*green+0.114350*blue; 2274 break; 2275 } 2276 case Rec601LuminancePixelIntensityMethod: 2277 { 2278 if (pixel->colorspace == sRGBColorspace) 2279 { 2280 red=DecodePixelGamma(red); 2281 green=DecodePixelGamma(green); 2282 blue=DecodePixelGamma(blue); 2283 } 2284 intensity=0.298839*red+0.586811*green+0.114350*blue; 2285 break; 2286 } 2287 case Rec709LumaPixelIntensityMethod: 2288 default: 2289 { 2290 if (pixel->colorspace == RGBColorspace) 2291 { 2292 red=EncodePixelGamma(red); 2293 green=EncodePixelGamma(green); 2294 blue=EncodePixelGamma(blue); 2295 } 2296 intensity=0.212656*red+0.715158*green+0.072186*blue; 2297 break; 2298 } 2299 case Rec709LuminancePixelIntensityMethod: 2300 { 2301 if (pixel->colorspace == sRGBColorspace) 2302 { 2303 red=DecodePixelGamma(red); 2304 green=DecodePixelGamma(green); 2305 blue=DecodePixelGamma(blue); 2306 } 2307 intensity=0.212656*red+0.715158*green+0.072186*blue; 2308 break; 2309 } 2310 case RMSPixelIntensityMethod: 2311 { 2312 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/ 2313 sqrt(3.0)); 2314 break; 2315 } 2316 } 2317 return(intensity); 2318} 2319 2320/* 2321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2322% % 2323% % 2324% % 2325% G e t P i x e l I n t e n s i t y % 2326% % 2327% % 2328% % 2329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2330% 2331% GetPixelIntensity() returns a single sample intensity value from the red, 2332% green, and blue components of a pixel based on the selected method: 2333% 2334% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B' 2335% Rec601Luminance 0.298839R + 0.586811G + 0.114350B 2336% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B' 2337% Rec709Luminance 0.212656R + 0.715158G + 0.072186B 2338% Brightness max(R', G', B') 2339% Lightness (min(R', G', B') + max(R', G', B')) / 2.0 2340% 2341% MS (R^2 + G^2 + B^2) / 3.0 2342% RMS sqrt((R^2 + G^2 + B^2) / 3.0 2343% Average (R + G + B') / 3.0 2344% 2345% The format of the GetPixelIntensity method is: 2346% 2347% MagickRealType GetPixelIntensity(const Image *image, 2348% const Quantum *pixel) 2349% 2350% A description of each parameter follows: 2351% 2352% o image: the image. 2353% 2354% o pixel: Specifies a pointer to a Quantum structure. 2355% 2356*/ 2357MagickExport MagickRealType GetPixelIntensity(const Image *magick_restrict image, 2358 const Quantum *magick_restrict pixel) 2359{ 2360 MagickRealType 2361 blue, 2362 green, 2363 red, 2364 intensity; 2365 2366 red=GetPixelRed(image,pixel); 2367 green=GetPixelGreen(image,pixel); 2368 blue=GetPixelBlue(image,pixel); 2369 switch (image->intensity) 2370 { 2371 case AveragePixelIntensityMethod: 2372 { 2373 intensity=(red+green+blue)/3.0; 2374 break; 2375 } 2376 case BrightnessPixelIntensityMethod: 2377 { 2378 intensity=MagickMax(MagickMax(red,green),blue); 2379 break; 2380 } 2381 case LightnessPixelIntensityMethod: 2382 { 2383 intensity=(MagickMin(MagickMin(red,green),blue)+ 2384 MagickMax(MagickMax(red,green),blue))/2.0; 2385 break; 2386 } 2387 case MSPixelIntensityMethod: 2388 { 2389 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/ 2390 (3.0*QuantumRange)); 2391 break; 2392 } 2393 case Rec601LumaPixelIntensityMethod: 2394 { 2395 if (image->colorspace == RGBColorspace) 2396 { 2397 red=EncodePixelGamma(red); 2398 green=EncodePixelGamma(green); 2399 blue=EncodePixelGamma(blue); 2400 } 2401 intensity=0.298839*red+0.586811*green+0.114350*blue; 2402 break; 2403 } 2404 case Rec601LuminancePixelIntensityMethod: 2405 { 2406 if (image->colorspace == sRGBColorspace) 2407 { 2408 red=DecodePixelGamma(red); 2409 green=DecodePixelGamma(green); 2410 blue=DecodePixelGamma(blue); 2411 } 2412 intensity=0.298839*red+0.586811*green+0.114350*blue; 2413 break; 2414 } 2415 case Rec709LumaPixelIntensityMethod: 2416 default: 2417 { 2418 if (image->colorspace == RGBColorspace) 2419 { 2420 red=EncodePixelGamma(red); 2421 green=EncodePixelGamma(green); 2422 blue=EncodePixelGamma(blue); 2423 } 2424 intensity=0.212656*red+0.715158*green+0.072186*blue; 2425 break; 2426 } 2427 case Rec709LuminancePixelIntensityMethod: 2428 { 2429 if (image->colorspace == sRGBColorspace) 2430 { 2431 red=DecodePixelGamma(red); 2432 green=DecodePixelGamma(green); 2433 blue=DecodePixelGamma(blue); 2434 } 2435 intensity=0.212656*red+0.715158*green+0.072186*blue; 2436 break; 2437 } 2438 case RMSPixelIntensityMethod: 2439 { 2440 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/ 2441 sqrt(3.0)); 2442 break; 2443 } 2444 } 2445 return(intensity); 2446} 2447 2448/* 2449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2450% % 2451% % 2452% % 2453% I m p o r t I m a g e P i x e l s % 2454% % 2455% % 2456% % 2457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2458% 2459% ImportImagePixels() accepts pixel data and stores in the image at the 2460% location you specify. The method returns MagickTrue on success otherwise 2461% MagickFalse if an error is encountered. The pixel data can be either char, 2462% Quantum, short int, unsigned int, unsigned long long, float, or double in 2463% the order specified by map. 2464% 2465% Suppose your want to upload the first scanline of a 640x480 image from 2466% character data in red-green-blue order: 2467% 2468% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels); 2469% 2470% The format of the ImportImagePixels method is: 2471% 2472% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x, 2473% const ssize_t y,const size_t width,const size_t height, 2474% const char *map,const StorageType type,const void *pixels, 2475% ExceptionInfo *exception) 2476% 2477% A description of each parameter follows: 2478% 2479% o image: the image. 2480% 2481% o x,y,width,height: These values define the perimeter 2482% of a region of pixels you want to define. 2483% 2484% o map: This string reflects the expected ordering of the pixel array. 2485% It can be any combination or order of R = red, G = green, B = blue, 2486% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan, 2487% Y = yellow, M = magenta, K = black, I = intensity (for grayscale), 2488% P = pad. 2489% 2490% o type: Define the data type of the pixels. Float and double types are 2491% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these 2492% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *), 2493% LongPixel (unsigned int *), LongLongPixel (unsigned long long *), 2494% QuantumPixel (Quantum *), or ShortPixel (unsigned short *). 2495% 2496% o pixels: This array of values contain the pixel components as defined by 2497% map and type. You must preallocate this array where the expected 2498% length varies depending on the values of width, height, map, and type. 2499% 2500% o exception: return any errors or warnings in this structure. 2501% 2502*/ 2503 2504static void ImportCharPixel(Image *image,const RectangleInfo *roi, 2505 const char *magick_restrict map,const QuantumType *quantum_map, 2506 const void *pixels,ExceptionInfo *exception) 2507{ 2508 register const unsigned char 2509 *magick_restrict p; 2510 2511 register Quantum 2512 *magick_restrict q; 2513 2514 register ssize_t 2515 x; 2516 2517 size_t 2518 length; 2519 2520 ssize_t 2521 y; 2522 2523 p=(const unsigned char *) pixels; 2524 if (LocaleCompare(map,"BGR") == 0) 2525 { 2526 for (y=0; y < (ssize_t) roi->height; y++) 2527 { 2528 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2529 if (q == (Quantum *) NULL) 2530 break; 2531 for (x=0; x < (ssize_t) roi->width; x++) 2532 { 2533 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2534 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2535 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2536 q+=GetPixelChannels(image); 2537 } 2538 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2539 break; 2540 } 2541 return; 2542 } 2543 if (LocaleCompare(map,"BGRA") == 0) 2544 { 2545 for (y=0; y < (ssize_t) roi->height; y++) 2546 { 2547 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2548 if (q == (Quantum *) NULL) 2549 break; 2550 for (x=0; x < (ssize_t) roi->width; x++) 2551 { 2552 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2553 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2554 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2555 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); 2556 q+=GetPixelChannels(image); 2557 } 2558 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2559 break; 2560 } 2561 return; 2562 } 2563 if (LocaleCompare(map,"BGRO") == 0) 2564 { 2565 for (y=0; y < (ssize_t) roi->height; y++) 2566 { 2567 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2568 if (q == (Quantum *) NULL) 2569 break; 2570 for (x=0; x < (ssize_t) roi->width; x++) 2571 { 2572 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2573 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2574 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2575 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); 2576 q+=GetPixelChannels(image); 2577 } 2578 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2579 break; 2580 } 2581 return; 2582 } 2583 if (LocaleCompare(map,"BGRP") == 0) 2584 { 2585 for (y=0; y < (ssize_t) roi->height; y++) 2586 { 2587 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2588 if (q == (Quantum *) NULL) 2589 break; 2590 for (x=0; x < (ssize_t) roi->width; x++) 2591 { 2592 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2593 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2594 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2595 p++; 2596 q+=GetPixelChannels(image); 2597 } 2598 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2599 break; 2600 } 2601 return; 2602 } 2603 if (LocaleCompare(map,"I") == 0) 2604 { 2605 for (y=0; y < (ssize_t) roi->height; y++) 2606 { 2607 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2608 if (q == (Quantum *) NULL) 2609 break; 2610 for (x=0; x < (ssize_t) roi->width; x++) 2611 { 2612 SetPixelGray(image,ScaleCharToQuantum(*p++),q); 2613 q+=GetPixelChannels(image); 2614 } 2615 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2616 break; 2617 } 2618 return; 2619 } 2620 if (LocaleCompare(map,"RGB") == 0) 2621 { 2622 for (y=0; y < (ssize_t) roi->height; y++) 2623 { 2624 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2625 if (q == (Quantum *) NULL) 2626 break; 2627 for (x=0; x < (ssize_t) roi->width; x++) 2628 { 2629 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2630 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2631 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2632 q+=GetPixelChannels(image); 2633 } 2634 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2635 break; 2636 } 2637 return; 2638 } 2639 if (LocaleCompare(map,"RGBA") == 0) 2640 { 2641 for (y=0; y < (ssize_t) roi->height; y++) 2642 { 2643 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2644 if (q == (Quantum *) NULL) 2645 break; 2646 for (x=0; x < (ssize_t) roi->width; x++) 2647 { 2648 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2649 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2650 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2651 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); 2652 q+=GetPixelChannels(image); 2653 } 2654 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2655 break; 2656 } 2657 return; 2658 } 2659 if (LocaleCompare(map,"RGBO") == 0) 2660 { 2661 for (y=0; y < (ssize_t) roi->height; y++) 2662 { 2663 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2664 if (q == (Quantum *) NULL) 2665 break; 2666 for (x=0; x < (ssize_t) roi->width; x++) 2667 { 2668 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2669 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2670 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2671 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); 2672 q+=GetPixelChannels(image); 2673 } 2674 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2675 break; 2676 } 2677 return; 2678 } 2679 if (LocaleCompare(map,"RGBP") == 0) 2680 { 2681 for (y=0; y < (ssize_t) roi->height; y++) 2682 { 2683 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2684 if (q == (Quantum *) NULL) 2685 break; 2686 for (x=0; x < (ssize_t) roi->width; x++) 2687 { 2688 SetPixelRed(image,ScaleCharToQuantum(*p++),q); 2689 SetPixelGreen(image,ScaleCharToQuantum(*p++),q); 2690 SetPixelBlue(image,ScaleCharToQuantum(*p++),q); 2691 p++; 2692 q+=GetPixelChannels(image); 2693 } 2694 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2695 break; 2696 } 2697 return; 2698 } 2699 length=strlen(map); 2700 for (y=0; y < (ssize_t) roi->height; y++) 2701 { 2702 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2703 if (q == (Quantum *) NULL) 2704 break; 2705 for (x=0; x < (ssize_t) roi->width; x++) 2706 { 2707 register ssize_t 2708 i; 2709 2710 for (i=0; i < (ssize_t) length; i++) 2711 { 2712 switch (quantum_map[i]) 2713 { 2714 case RedQuantum: 2715 case CyanQuantum: 2716 { 2717 SetPixelRed(image,ScaleCharToQuantum(*p),q); 2718 break; 2719 } 2720 case GreenQuantum: 2721 case MagentaQuantum: 2722 { 2723 SetPixelGreen(image,ScaleCharToQuantum(*p),q); 2724 break; 2725 } 2726 case BlueQuantum: 2727 case YellowQuantum: 2728 { 2729 SetPixelBlue(image,ScaleCharToQuantum(*p),q); 2730 break; 2731 } 2732 case AlphaQuantum: 2733 { 2734 SetPixelAlpha(image,ScaleCharToQuantum(*p),q); 2735 break; 2736 } 2737 case OpacityQuantum: 2738 { 2739 SetPixelAlpha(image,ScaleCharToQuantum(*p),q); 2740 break; 2741 } 2742 case BlackQuantum: 2743 { 2744 SetPixelBlack(image,ScaleCharToQuantum(*p),q); 2745 break; 2746 } 2747 case IndexQuantum: 2748 { 2749 SetPixelGray(image,ScaleCharToQuantum(*p),q); 2750 break; 2751 } 2752 default: 2753 break; 2754 } 2755 p++; 2756 } 2757 q+=GetPixelChannels(image); 2758 } 2759 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2760 break; 2761 } 2762} 2763 2764static void ImportDoublePixel(Image *image,const RectangleInfo *roi, 2765 const char *magick_restrict map,const QuantumType *quantum_map, 2766 const void *pixels,ExceptionInfo *exception) 2767{ 2768 register const double 2769 *magick_restrict p; 2770 2771 register Quantum 2772 *magick_restrict q; 2773 2774 register ssize_t 2775 x; 2776 2777 size_t 2778 length; 2779 2780 ssize_t 2781 y; 2782 2783 p=(const double *) pixels; 2784 if (LocaleCompare(map,"BGR") == 0) 2785 { 2786 for (y=0; y < (ssize_t) roi->height; y++) 2787 { 2788 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2789 if (q == (Quantum *) NULL) 2790 break; 2791 for (x=0; x < (ssize_t) roi->width; x++) 2792 { 2793 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2794 p++; 2795 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2796 p++; 2797 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2798 p++; 2799 q+=GetPixelChannels(image); 2800 } 2801 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2802 break; 2803 } 2804 return; 2805 } 2806 if (LocaleCompare(map,"BGRA") == 0) 2807 { 2808 for (y=0; y < (ssize_t) roi->height; y++) 2809 { 2810 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2811 if (q == (Quantum *) NULL) 2812 break; 2813 for (x=0; x < (ssize_t) roi->width; x++) 2814 { 2815 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2816 p++; 2817 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2818 p++; 2819 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2820 p++; 2821 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 2822 p++; 2823 q+=GetPixelChannels(image); 2824 } 2825 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2826 break; 2827 } 2828 return; 2829 } 2830 if (LocaleCompare(map,"BGRP") == 0) 2831 { 2832 for (y=0; y < (ssize_t) roi->height; y++) 2833 { 2834 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2835 if (q == (Quantum *) NULL) 2836 break; 2837 for (x=0; x < (ssize_t) roi->width; x++) 2838 { 2839 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2840 p++; 2841 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2842 p++; 2843 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2844 p++; 2845 p++; 2846 q+=GetPixelChannels(image); 2847 } 2848 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2849 break; 2850 } 2851 return; 2852 } 2853 if (LocaleCompare(map,"I") == 0) 2854 { 2855 for (y=0; y < (ssize_t) roi->height; y++) 2856 { 2857 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2858 if (q == (Quantum *) NULL) 2859 break; 2860 for (x=0; x < (ssize_t) roi->width; x++) 2861 { 2862 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); 2863 p++; 2864 q+=GetPixelChannels(image); 2865 } 2866 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2867 break; 2868 } 2869 return; 2870 } 2871 if (LocaleCompare(map,"RGB") == 0) 2872 { 2873 for (y=0; y < (ssize_t) roi->height; y++) 2874 { 2875 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2876 if (q == (Quantum *) NULL) 2877 break; 2878 for (x=0; x < (ssize_t) roi->width; x++) 2879 { 2880 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2881 p++; 2882 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2883 p++; 2884 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2885 p++; 2886 q+=GetPixelChannels(image); 2887 } 2888 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2889 break; 2890 } 2891 return; 2892 } 2893 if (LocaleCompare(map,"RGBA") == 0) 2894 { 2895 for (y=0; y < (ssize_t) roi->height; y++) 2896 { 2897 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2898 if (q == (Quantum *) NULL) 2899 break; 2900 for (x=0; x < (ssize_t) roi->width; x++) 2901 { 2902 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2903 p++; 2904 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2905 p++; 2906 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2907 p++; 2908 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 2909 p++; 2910 q+=GetPixelChannels(image); 2911 } 2912 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2913 break; 2914 } 2915 return; 2916 } 2917 if (LocaleCompare(map,"RGBP") == 0) 2918 { 2919 for (y=0; y < (ssize_t) roi->height; y++) 2920 { 2921 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2922 if (q == (Quantum *) NULL) 2923 break; 2924 for (x=0; x < (ssize_t) roi->width; x++) 2925 { 2926 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2927 p++; 2928 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2929 p++; 2930 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2931 p++; 2932 q+=GetPixelChannels(image); 2933 } 2934 if (SyncAuthenticPixels(image,exception) == MagickFalse) 2935 break; 2936 } 2937 return; 2938 } 2939 length=strlen(map); 2940 for (y=0; y < (ssize_t) roi->height; y++) 2941 { 2942 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 2943 if (q == (Quantum *) NULL) 2944 break; 2945 for (x=0; x < (ssize_t) roi->width; x++) 2946 { 2947 register ssize_t 2948 i; 2949 2950 for (i=0; i < (ssize_t) length; i++) 2951 { 2952 switch (quantum_map[i]) 2953 { 2954 case RedQuantum: 2955 case CyanQuantum: 2956 { 2957 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 2958 break; 2959 } 2960 case GreenQuantum: 2961 case MagentaQuantum: 2962 { 2963 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 2964 break; 2965 } 2966 case BlueQuantum: 2967 case YellowQuantum: 2968 { 2969 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 2970 break; 2971 } 2972 case AlphaQuantum: 2973 { 2974 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 2975 break; 2976 } 2977 case OpacityQuantum: 2978 { 2979 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 2980 break; 2981 } 2982 case BlackQuantum: 2983 { 2984 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q); 2985 break; 2986 } 2987 case IndexQuantum: 2988 { 2989 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); 2990 break; 2991 } 2992 default: 2993 break; 2994 } 2995 p++; 2996 } 2997 q+=GetPixelChannels(image); 2998 } 2999 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3000 break; 3001 } 3002} 3003 3004static void ImportFloatPixel(Image *image,const RectangleInfo *roi, 3005 const char *magick_restrict map,const QuantumType *quantum_map, 3006 const void *pixels,ExceptionInfo *exception) 3007{ 3008 register const float 3009 *magick_restrict p; 3010 3011 register Quantum 3012 *magick_restrict q; 3013 3014 register ssize_t 3015 x; 3016 3017 size_t 3018 length; 3019 3020 ssize_t 3021 y; 3022 3023 p=(const float *) pixels; 3024 if (LocaleCompare(map,"BGR") == 0) 3025 { 3026 for (y=0; y < (ssize_t) roi->height; y++) 3027 { 3028 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3029 if (q == (Quantum *) NULL) 3030 break; 3031 for (x=0; x < (ssize_t) roi->width; x++) 3032 { 3033 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3034 p++; 3035 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3036 p++; 3037 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3038 p++; 3039 q+=GetPixelChannels(image); 3040 } 3041 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3042 break; 3043 } 3044 return; 3045 } 3046 if (LocaleCompare(map,"BGRA") == 0) 3047 { 3048 for (y=0; y < (ssize_t) roi->height; y++) 3049 { 3050 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3051 if (q == (Quantum *) NULL) 3052 break; 3053 for (x=0; x < (ssize_t) roi->width; x++) 3054 { 3055 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3056 p++; 3057 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3058 p++; 3059 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3060 p++; 3061 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 3062 p++; 3063 q+=GetPixelChannels(image); 3064 } 3065 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3066 break; 3067 } 3068 return; 3069 } 3070 if (LocaleCompare(map,"BGRP") == 0) 3071 { 3072 for (y=0; y < (ssize_t) roi->height; y++) 3073 { 3074 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3075 if (q == (Quantum *) NULL) 3076 break; 3077 for (x=0; x < (ssize_t) roi->width; x++) 3078 { 3079 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3080 p++; 3081 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3082 p++; 3083 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3084 p++; 3085 p++; 3086 q+=GetPixelChannels(image); 3087 } 3088 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3089 break; 3090 } 3091 return; 3092 } 3093 if (LocaleCompare(map,"I") == 0) 3094 { 3095 for (y=0; y < (ssize_t) roi->height; y++) 3096 { 3097 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3098 if (q == (Quantum *) NULL) 3099 break; 3100 for (x=0; x < (ssize_t) roi->width; x++) 3101 { 3102 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); 3103 p++; 3104 q+=GetPixelChannels(image); 3105 } 3106 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3107 break; 3108 } 3109 return; 3110 } 3111 if (LocaleCompare(map,"RGB") == 0) 3112 { 3113 for (y=0; y < (ssize_t) roi->height; y++) 3114 { 3115 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3116 if (q == (Quantum *) NULL) 3117 break; 3118 for (x=0; x < (ssize_t) roi->width; x++) 3119 { 3120 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3121 p++; 3122 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3123 p++; 3124 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3125 p++; 3126 q+=GetPixelChannels(image); 3127 } 3128 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3129 break; 3130 } 3131 return; 3132 } 3133 if (LocaleCompare(map,"RGBA") == 0) 3134 { 3135 for (y=0; y < (ssize_t) roi->height; y++) 3136 { 3137 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3138 if (q == (Quantum *) NULL) 3139 break; 3140 for (x=0; x < (ssize_t) roi->width; x++) 3141 { 3142 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3143 p++; 3144 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3145 p++; 3146 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3147 p++; 3148 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 3149 p++; 3150 q+=GetPixelChannels(image); 3151 } 3152 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3153 break; 3154 } 3155 return; 3156 } 3157 if (LocaleCompare(map,"RGBP") == 0) 3158 { 3159 for (y=0; y < (ssize_t) roi->height; y++) 3160 { 3161 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3162 if (q == (Quantum *) NULL) 3163 break; 3164 for (x=0; x < (ssize_t) roi->width; x++) 3165 { 3166 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3167 p++; 3168 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3169 p++; 3170 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3171 p++; 3172 q+=GetPixelChannels(image); 3173 } 3174 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3175 break; 3176 } 3177 return; 3178 } 3179 length=strlen(map); 3180 for (y=0; y < (ssize_t) roi->height; y++) 3181 { 3182 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3183 if (q == (Quantum *) NULL) 3184 break; 3185 for (x=0; x < (ssize_t) roi->width; x++) 3186 { 3187 register ssize_t 3188 i; 3189 3190 for (i=0; i < (ssize_t) length; i++) 3191 { 3192 switch (quantum_map[i]) 3193 { 3194 case RedQuantum: 3195 case CyanQuantum: 3196 { 3197 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q); 3198 break; 3199 } 3200 case GreenQuantum: 3201 case MagentaQuantum: 3202 { 3203 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q); 3204 break; 3205 } 3206 case BlueQuantum: 3207 case YellowQuantum: 3208 { 3209 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q); 3210 break; 3211 } 3212 case AlphaQuantum: 3213 { 3214 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 3215 break; 3216 } 3217 case OpacityQuantum: 3218 { 3219 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q); 3220 break; 3221 } 3222 case BlackQuantum: 3223 { 3224 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q); 3225 break; 3226 } 3227 case IndexQuantum: 3228 { 3229 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q); 3230 break; 3231 } 3232 default: 3233 break; 3234 } 3235 p++; 3236 } 3237 q+=GetPixelChannels(image); 3238 } 3239 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3240 break; 3241 } 3242} 3243 3244static void ImportLongPixel(Image *image,const RectangleInfo *roi, 3245 const char *magick_restrict map,const QuantumType *quantum_map, 3246 const void *pixels,ExceptionInfo *exception) 3247{ 3248 register const unsigned int 3249 *magick_restrict p; 3250 3251 register Quantum 3252 *magick_restrict q; 3253 3254 register ssize_t 3255 x; 3256 3257 size_t 3258 length; 3259 3260 ssize_t 3261 y; 3262 3263 p=(const unsigned int *) pixels; 3264 if (LocaleCompare(map,"BGR") == 0) 3265 { 3266 for (y=0; y < (ssize_t) roi->height; y++) 3267 { 3268 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3269 if (q == (Quantum *) NULL) 3270 break; 3271 for (x=0; x < (ssize_t) roi->width; x++) 3272 { 3273 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3274 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3275 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3276 q+=GetPixelChannels(image); 3277 } 3278 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3279 break; 3280 } 3281 return; 3282 } 3283 if (LocaleCompare(map,"BGRA") == 0) 3284 { 3285 for (y=0; y < (ssize_t) roi->height; y++) 3286 { 3287 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3288 if (q == (Quantum *) NULL) 3289 break; 3290 for (x=0; x < (ssize_t) roi->width; x++) 3291 { 3292 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3293 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3294 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3295 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q); 3296 q+=GetPixelChannels(image); 3297 } 3298 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3299 break; 3300 } 3301 return; 3302 } 3303 if (LocaleCompare(map,"BGRP") == 0) 3304 { 3305 for (y=0; y < (ssize_t) roi->height; y++) 3306 { 3307 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3308 if (q == (Quantum *) NULL) 3309 break; 3310 for (x=0; x < (ssize_t) roi->width; x++) 3311 { 3312 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3313 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3314 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3315 p++; 3316 q+=GetPixelChannels(image); 3317 } 3318 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3319 break; 3320 } 3321 return; 3322 } 3323 if (LocaleCompare(map,"I") == 0) 3324 { 3325 for (y=0; y < (ssize_t) roi->height; y++) 3326 { 3327 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3328 if (q == (Quantum *) NULL) 3329 break; 3330 for (x=0; x < (ssize_t) roi->width; x++) 3331 { 3332 SetPixelGray(image,ScaleLongToQuantum(*p++),q); 3333 q+=GetPixelChannels(image); 3334 } 3335 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3336 break; 3337 } 3338 return; 3339 } 3340 if (LocaleCompare(map,"RGB") == 0) 3341 { 3342 for (y=0; y < (ssize_t) roi->height; y++) 3343 { 3344 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3345 if (q == (Quantum *) NULL) 3346 break; 3347 for (x=0; x < (ssize_t) roi->width; x++) 3348 { 3349 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3350 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3351 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3352 q+=GetPixelChannels(image); 3353 } 3354 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3355 break; 3356 } 3357 return; 3358 } 3359 if (LocaleCompare(map,"RGBA") == 0) 3360 { 3361 for (y=0; y < (ssize_t) roi->height; y++) 3362 { 3363 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3364 if (q == (Quantum *) NULL) 3365 break; 3366 for (x=0; x < (ssize_t) roi->width; x++) 3367 { 3368 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3369 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3370 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3371 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q); 3372 q+=GetPixelChannels(image); 3373 } 3374 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3375 break; 3376 } 3377 return; 3378 } 3379 if (LocaleCompare(map,"RGBP") == 0) 3380 { 3381 for (y=0; y < (ssize_t) roi->height; y++) 3382 { 3383 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3384 if (q == (Quantum *) NULL) 3385 break; 3386 for (x=0; x < (ssize_t) roi->width; x++) 3387 { 3388 SetPixelRed(image,ScaleLongToQuantum(*p++),q); 3389 SetPixelGreen(image,ScaleLongToQuantum(*p++),q); 3390 SetPixelBlue(image,ScaleLongToQuantum(*p++),q); 3391 p++; 3392 q+=GetPixelChannels(image); 3393 } 3394 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3395 break; 3396 } 3397 return; 3398 } 3399 length=strlen(map); 3400 for (y=0; y < (ssize_t) roi->height; y++) 3401 { 3402 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3403 if (q == (Quantum *) NULL) 3404 break; 3405 for (x=0; x < (ssize_t) roi->width; x++) 3406 { 3407 register ssize_t 3408 i; 3409 3410 for (i=0; i < (ssize_t) length; i++) 3411 { 3412 switch (quantum_map[i]) 3413 { 3414 case RedQuantum: 3415 case CyanQuantum: 3416 { 3417 SetPixelRed(image,ScaleLongToQuantum(*p),q); 3418 break; 3419 } 3420 case GreenQuantum: 3421 case MagentaQuantum: 3422 { 3423 SetPixelGreen(image,ScaleLongToQuantum(*p),q); 3424 break; 3425 } 3426 case BlueQuantum: 3427 case YellowQuantum: 3428 { 3429 SetPixelBlue(image,ScaleLongToQuantum(*p),q); 3430 break; 3431 } 3432 case AlphaQuantum: 3433 { 3434 SetPixelAlpha(image,ScaleLongToQuantum(*p),q); 3435 break; 3436 } 3437 case OpacityQuantum: 3438 { 3439 SetPixelAlpha(image,ScaleLongToQuantum(*p),q); 3440 break; 3441 } 3442 case BlackQuantum: 3443 { 3444 SetPixelBlack(image,ScaleLongToQuantum(*p),q); 3445 break; 3446 } 3447 case IndexQuantum: 3448 { 3449 SetPixelGray(image,ScaleLongToQuantum(*p),q); 3450 break; 3451 } 3452 default: 3453 break; 3454 } 3455 p++; 3456 } 3457 q+=GetPixelChannels(image); 3458 } 3459 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3460 break; 3461 } 3462} 3463 3464static void ImportLongLongPixel(Image *image,const RectangleInfo *roi, 3465 const char *magick_restrict map,const QuantumType *quantum_map, 3466 const void *pixels,ExceptionInfo *exception) 3467{ 3468 register const MagickSizeType 3469 *magick_restrict p; 3470 3471 register Quantum 3472 *magick_restrict q; 3473 3474 register ssize_t 3475 x; 3476 3477 size_t 3478 length; 3479 3480 ssize_t 3481 y; 3482 3483 p=(const MagickSizeType *) pixels; 3484 if (LocaleCompare(map,"BGR") == 0) 3485 { 3486 for (y=0; y < (ssize_t) roi->height; y++) 3487 { 3488 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3489 if (q == (Quantum *) NULL) 3490 break; 3491 for (x=0; x < (ssize_t) roi->width; x++) 3492 { 3493 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3494 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3495 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3496 q+=GetPixelChannels(image); 3497 } 3498 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3499 break; 3500 } 3501 return; 3502 } 3503 if (LocaleCompare(map,"BGRA") == 0) 3504 { 3505 for (y=0; y < (ssize_t) roi->height; y++) 3506 { 3507 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3508 if (q == (Quantum *) NULL) 3509 break; 3510 for (x=0; x < (ssize_t) roi->width; x++) 3511 { 3512 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3513 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3514 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3515 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q); 3516 q+=GetPixelChannels(image); 3517 } 3518 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3519 break; 3520 } 3521 return; 3522 } 3523 if (LocaleCompare(map,"BGRP") == 0) 3524 { 3525 for (y=0; y < (ssize_t) roi->height; y++) 3526 { 3527 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3528 if (q == (Quantum *) NULL) 3529 break; 3530 for (x=0; x < (ssize_t) roi->width; x++) 3531 { 3532 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3533 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3534 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3535 p++; 3536 q+=GetPixelChannels(image); 3537 } 3538 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3539 break; 3540 } 3541 return; 3542 } 3543 if (LocaleCompare(map,"I") == 0) 3544 { 3545 for (y=0; y < (ssize_t) roi->height; y++) 3546 { 3547 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3548 if (q == (Quantum *) NULL) 3549 break; 3550 for (x=0; x < (ssize_t) roi->width; x++) 3551 { 3552 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q); 3553 q+=GetPixelChannels(image); 3554 } 3555 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3556 break; 3557 } 3558 return; 3559 } 3560 if (LocaleCompare(map,"RGB") == 0) 3561 { 3562 for (y=0; y < (ssize_t) roi->height; y++) 3563 { 3564 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3565 if (q == (Quantum *) NULL) 3566 break; 3567 for (x=0; x < (ssize_t) roi->width; x++) 3568 { 3569 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3570 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3571 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3572 q+=GetPixelChannels(image); 3573 } 3574 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3575 break; 3576 } 3577 return; 3578 } 3579 if (LocaleCompare(map,"RGBA") == 0) 3580 { 3581 for (y=0; y < (ssize_t) roi->height; y++) 3582 { 3583 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3584 if (q == (Quantum *) NULL) 3585 break; 3586 for (x=0; x < (ssize_t) roi->width; x++) 3587 { 3588 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3589 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3590 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3591 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q); 3592 q+=GetPixelChannels(image); 3593 } 3594 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3595 break; 3596 } 3597 return; 3598 } 3599 if (LocaleCompare(map,"RGBP") == 0) 3600 { 3601 for (y=0; y < (ssize_t) roi->height; y++) 3602 { 3603 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3604 if (q == (Quantum *) NULL) 3605 break; 3606 for (x=0; x < (ssize_t) roi->width; x++) 3607 { 3608 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q); 3609 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q); 3610 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q); 3611 p++; 3612 q+=GetPixelChannels(image); 3613 } 3614 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3615 break; 3616 } 3617 return; 3618 } 3619 length=strlen(map); 3620 for (y=0; y < (ssize_t) roi->height; y++) 3621 { 3622 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3623 if (q == (Quantum *) NULL) 3624 break; 3625 for (x=0; x < (ssize_t) roi->width; x++) 3626 { 3627 register ssize_t 3628 i; 3629 3630 for (i=0; i < (ssize_t) length; i++) 3631 { 3632 switch (quantum_map[i]) 3633 { 3634 case RedQuantum: 3635 case CyanQuantum: 3636 { 3637 SetPixelRed(image,ScaleLongLongToQuantum(*p),q); 3638 break; 3639 } 3640 case GreenQuantum: 3641 case MagentaQuantum: 3642 { 3643 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q); 3644 break; 3645 } 3646 case BlueQuantum: 3647 case YellowQuantum: 3648 { 3649 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q); 3650 break; 3651 } 3652 case AlphaQuantum: 3653 { 3654 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q); 3655 break; 3656 } 3657 case OpacityQuantum: 3658 { 3659 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q); 3660 break; 3661 } 3662 case BlackQuantum: 3663 { 3664 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q); 3665 break; 3666 } 3667 case IndexQuantum: 3668 { 3669 SetPixelGray(image,ScaleLongLongToQuantum(*p),q); 3670 break; 3671 } 3672 default: 3673 break; 3674 } 3675 p++; 3676 } 3677 q+=GetPixelChannels(image); 3678 } 3679 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3680 break; 3681 } 3682} 3683 3684static void ImportQuantumPixel(Image *image,const RectangleInfo *roi, 3685 const char *magick_restrict map,const QuantumType *quantum_map, 3686 const void *pixels,ExceptionInfo *exception) 3687{ 3688 register const Quantum 3689 *magick_restrict p; 3690 3691 register Quantum 3692 *magick_restrict q; 3693 3694 register ssize_t 3695 x; 3696 3697 size_t 3698 length; 3699 3700 ssize_t 3701 y; 3702 3703 p=(const Quantum *) pixels; 3704 if (LocaleCompare(map,"BGR") == 0) 3705 { 3706 for (y=0; y < (ssize_t) roi->height; y++) 3707 { 3708 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3709 if (q == (Quantum *) NULL) 3710 break; 3711 for (x=0; x < (ssize_t) roi->width; x++) 3712 { 3713 SetPixelBlue(image,*p++,q); 3714 SetPixelGreen(image,*p++,q); 3715 SetPixelRed(image,*p++,q); 3716 q+=GetPixelChannels(image); 3717 } 3718 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3719 break; 3720 } 3721 return; 3722 } 3723 if (LocaleCompare(map,"BGRA") == 0) 3724 { 3725 for (y=0; y < (ssize_t) roi->height; y++) 3726 { 3727 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3728 if (q == (Quantum *) NULL) 3729 break; 3730 for (x=0; x < (ssize_t) roi->width; x++) 3731 { 3732 SetPixelBlue(image,*p++,q); 3733 SetPixelGreen(image,*p++,q); 3734 SetPixelRed(image,*p++,q); 3735 SetPixelAlpha(image,*p++,q); 3736 q+=GetPixelChannels(image); 3737 } 3738 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3739 break; 3740 } 3741 return; 3742 } 3743 if (LocaleCompare(map,"BGRP") == 0) 3744 { 3745 for (y=0; y < (ssize_t) roi->height; y++) 3746 { 3747 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3748 if (q == (Quantum *) NULL) 3749 break; 3750 for (x=0; x < (ssize_t) roi->width; x++) 3751 { 3752 SetPixelBlue(image,*p++,q); 3753 SetPixelGreen(image,*p++,q); 3754 SetPixelRed(image,*p++,q); 3755 p++; 3756 q+=GetPixelChannels(image); 3757 } 3758 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3759 break; 3760 } 3761 return; 3762 } 3763 if (LocaleCompare(map,"I") == 0) 3764 { 3765 for (y=0; y < (ssize_t) roi->height; y++) 3766 { 3767 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3768 if (q == (Quantum *) NULL) 3769 break; 3770 for (x=0; x < (ssize_t) roi->width; x++) 3771 { 3772 SetPixelGray(image,*p++,q); 3773 q+=GetPixelChannels(image); 3774 } 3775 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3776 break; 3777 } 3778 return; 3779 } 3780 if (LocaleCompare(map,"RGB") == 0) 3781 { 3782 for (y=0; y < (ssize_t) roi->height; y++) 3783 { 3784 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3785 if (q == (Quantum *) NULL) 3786 break; 3787 for (x=0; x < (ssize_t) roi->width; x++) 3788 { 3789 SetPixelRed(image,*p++,q); 3790 SetPixelGreen(image,*p++,q); 3791 SetPixelBlue(image,*p++,q); 3792 q+=GetPixelChannels(image); 3793 } 3794 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3795 break; 3796 } 3797 return; 3798 } 3799 if (LocaleCompare(map,"RGBA") == 0) 3800 { 3801 for (y=0; y < (ssize_t) roi->height; y++) 3802 { 3803 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3804 if (q == (Quantum *) NULL) 3805 break; 3806 for (x=0; x < (ssize_t) roi->width; x++) 3807 { 3808 SetPixelRed(image,*p++,q); 3809 SetPixelGreen(image,*p++,q); 3810 SetPixelBlue(image,*p++,q); 3811 SetPixelAlpha(image,*p++,q); 3812 q+=GetPixelChannels(image); 3813 } 3814 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3815 break; 3816 } 3817 return; 3818 } 3819 if (LocaleCompare(map,"RGBP") == 0) 3820 { 3821 for (y=0; y < (ssize_t) roi->height; y++) 3822 { 3823 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3824 if (q == (Quantum *) NULL) 3825 break; 3826 for (x=0; x < (ssize_t) roi->width; x++) 3827 { 3828 SetPixelRed(image,*p++,q); 3829 SetPixelGreen(image,*p++,q); 3830 SetPixelBlue(image,*p++,q); 3831 p++; 3832 q+=GetPixelChannels(image); 3833 } 3834 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3835 break; 3836 } 3837 return; 3838 } 3839 length=strlen(map); 3840 for (y=0; y < (ssize_t) roi->height; y++) 3841 { 3842 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3843 if (q == (Quantum *) NULL) 3844 break; 3845 for (x=0; x < (ssize_t) roi->width; x++) 3846 { 3847 register ssize_t 3848 i; 3849 3850 for (i=0; i < (ssize_t) length; i++) 3851 { 3852 switch (quantum_map[i]) 3853 { 3854 case RedQuantum: 3855 case CyanQuantum: 3856 { 3857 SetPixelRed(image,*p,q); 3858 break; 3859 } 3860 case GreenQuantum: 3861 case MagentaQuantum: 3862 { 3863 SetPixelGreen(image,*p,q); 3864 break; 3865 } 3866 case BlueQuantum: 3867 case YellowQuantum: 3868 { 3869 SetPixelBlue(image,*p,q); 3870 break; 3871 } 3872 case AlphaQuantum: 3873 { 3874 SetPixelAlpha(image,*p,q); 3875 break; 3876 } 3877 case OpacityQuantum: 3878 { 3879 SetPixelAlpha(image,*p,q); 3880 break; 3881 } 3882 case BlackQuantum: 3883 { 3884 SetPixelBlack(image,*p,q); 3885 break; 3886 } 3887 case IndexQuantum: 3888 { 3889 SetPixelGray(image,*p,q); 3890 break; 3891 } 3892 default: 3893 break; 3894 } 3895 p++; 3896 } 3897 q+=GetPixelChannels(image); 3898 } 3899 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3900 break; 3901 } 3902} 3903 3904static void ImportShortPixel(Image *image,const RectangleInfo *roi, 3905 const char *magick_restrict map,const QuantumType *quantum_map, 3906 const void *pixels,ExceptionInfo *exception) 3907{ 3908 register const unsigned short 3909 *magick_restrict p; 3910 3911 register Quantum 3912 *magick_restrict q; 3913 3914 register ssize_t 3915 x; 3916 3917 size_t 3918 length; 3919 3920 ssize_t 3921 y; 3922 3923 p=(const unsigned short *) pixels; 3924 if (LocaleCompare(map,"BGR") == 0) 3925 { 3926 for (y=0; y < (ssize_t) roi->height; y++) 3927 { 3928 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3929 if (q == (Quantum *) NULL) 3930 break; 3931 for (x=0; x < (ssize_t) roi->width; x++) 3932 { 3933 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 3934 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 3935 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 3936 q+=GetPixelChannels(image); 3937 } 3938 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3939 break; 3940 } 3941 return; 3942 } 3943 if (LocaleCompare(map,"BGRA") == 0) 3944 { 3945 for (y=0; y < (ssize_t) roi->height; y++) 3946 { 3947 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3948 if (q == (Quantum *) NULL) 3949 break; 3950 for (x=0; x < (ssize_t) roi->width; x++) 3951 { 3952 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 3953 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 3954 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 3955 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q); 3956 q+=GetPixelChannels(image); 3957 } 3958 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3959 break; 3960 } 3961 return; 3962 } 3963 if (LocaleCompare(map,"BGRP") == 0) 3964 { 3965 for (y=0; y < (ssize_t) roi->height; y++) 3966 { 3967 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3968 if (q == (Quantum *) NULL) 3969 break; 3970 for (x=0; x < (ssize_t) roi->width; x++) 3971 { 3972 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 3973 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 3974 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 3975 p++; 3976 q+=GetPixelChannels(image); 3977 } 3978 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3979 break; 3980 } 3981 return; 3982 } 3983 if (LocaleCompare(map,"I") == 0) 3984 { 3985 for (y=0; y < (ssize_t) roi->height; y++) 3986 { 3987 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 3988 if (q == (Quantum *) NULL) 3989 break; 3990 for (x=0; x < (ssize_t) roi->width; x++) 3991 { 3992 SetPixelGray(image,ScaleShortToQuantum(*p++),q); 3993 q+=GetPixelChannels(image); 3994 } 3995 if (SyncAuthenticPixels(image,exception) == MagickFalse) 3996 break; 3997 } 3998 return; 3999 } 4000 if (LocaleCompare(map,"RGB") == 0) 4001 { 4002 for (y=0; y < (ssize_t) roi->height; y++) 4003 { 4004 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 4005 if (q == (Quantum *) NULL) 4006 break; 4007 for (x=0; x < (ssize_t) roi->width; x++) 4008 { 4009 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 4010 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 4011 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 4012 q+=GetPixelChannels(image); 4013 } 4014 if (SyncAuthenticPixels(image,exception) == MagickFalse) 4015 break; 4016 } 4017 return; 4018 } 4019 if (LocaleCompare(map,"RGBA") == 0) 4020 { 4021 for (y=0; y < (ssize_t) roi->height; y++) 4022 { 4023 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 4024 if (q == (Quantum *) NULL) 4025 break; 4026 for (x=0; x < (ssize_t) roi->width; x++) 4027 { 4028 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 4029 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 4030 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 4031 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q); 4032 q+=GetPixelChannels(image); 4033 } 4034 if (SyncAuthenticPixels(image,exception) == MagickFalse) 4035 break; 4036 } 4037 return; 4038 } 4039 if (LocaleCompare(map,"RGBP") == 0) 4040 { 4041 for (y=0; y < (ssize_t) roi->height; y++) 4042 { 4043 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 4044 if (q == (Quantum *) NULL) 4045 break; 4046 for (x=0; x < (ssize_t) roi->width; x++) 4047 { 4048 SetPixelRed(image,ScaleShortToQuantum(*p++),q); 4049 SetPixelGreen(image,ScaleShortToQuantum(*p++),q); 4050 SetPixelBlue(image,ScaleShortToQuantum(*p++),q); 4051 p++; 4052 q+=GetPixelChannels(image); 4053 } 4054 if (SyncAuthenticPixels(image,exception) == MagickFalse) 4055 break; 4056 } 4057 return; 4058 } 4059 length=strlen(map); 4060 for (y=0; y < (ssize_t) roi->height; y++) 4061 { 4062 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception); 4063 if (q == (Quantum *) NULL) 4064 break; 4065 for (x=0; x < (ssize_t) roi->width; x++) 4066 { 4067 register ssize_t 4068 i; 4069 4070 for (i=0; i < (ssize_t) length; i++) 4071 { 4072 switch (quantum_map[i]) 4073 { 4074 case RedQuantum: 4075 case CyanQuantum: 4076 { 4077 SetPixelRed(image,ScaleShortToQuantum(*p),q); 4078 break; 4079 } 4080 case GreenQuantum: 4081 case MagentaQuantum: 4082 { 4083 SetPixelGreen(image,ScaleShortToQuantum(*p),q); 4084 break; 4085 } 4086 case BlueQuantum: 4087 case YellowQuantum: 4088 { 4089 SetPixelBlue(image,ScaleShortToQuantum(*p),q); 4090 break; 4091 } 4092 case AlphaQuantum: 4093 { 4094 SetPixelAlpha(image,ScaleShortToQuantum(*p),q); 4095 break; 4096 } 4097 case OpacityQuantum: 4098 { 4099 SetPixelAlpha(image,ScaleShortToQuantum(*p),q); 4100 break; 4101 } 4102 case BlackQuantum: 4103 { 4104 SetPixelBlack(image,ScaleShortToQuantum(*p),q); 4105 break; 4106 } 4107 case IndexQuantum: 4108 { 4109 SetPixelGray(image,ScaleShortToQuantum(*p),q); 4110 break; 4111 } 4112 default: 4113 break; 4114 } 4115 p++; 4116 } 4117 q+=GetPixelChannels(image); 4118 } 4119 if (SyncAuthenticPixels(image,exception) == MagickFalse) 4120 break; 4121 } 4122} 4123 4124MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x, 4125 const ssize_t y,const size_t width,const size_t height,const char *map, 4126 const StorageType type,const void *pixels,ExceptionInfo *exception) 4127{ 4128 QuantumType 4129 *quantum_map; 4130 4131 RectangleInfo 4132 roi; 4133 4134 register ssize_t 4135 i; 4136 4137 size_t 4138 length; 4139 4140 /* 4141 Allocate image structure. 4142 */ 4143 assert(image != (Image *) NULL); 4144 assert(image->signature == MagickCoreSignature); 4145 if (image->debug != MagickFalse) 4146 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 4147 length=strlen(map); 4148 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map)); 4149 if (quantum_map == (QuantumType *) NULL) 4150 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 4151 image->filename); 4152 for (i=0; i < (ssize_t) length; i++) 4153 { 4154 switch (map[i]) 4155 { 4156 case 'a': 4157 case 'A': 4158 { 4159 quantum_map[i]=AlphaQuantum; 4160 image->alpha_trait=BlendPixelTrait; 4161 break; 4162 } 4163 case 'B': 4164 case 'b': 4165 { 4166 quantum_map[i]=BlueQuantum; 4167 break; 4168 } 4169 case 'C': 4170 case 'c': 4171 { 4172 quantum_map[i]=CyanQuantum; 4173 (void) SetImageColorspace(image,CMYKColorspace,exception); 4174 break; 4175 } 4176 case 'g': 4177 case 'G': 4178 { 4179 quantum_map[i]=GreenQuantum; 4180 break; 4181 } 4182 case 'K': 4183 case 'k': 4184 { 4185 quantum_map[i]=BlackQuantum; 4186 (void) SetImageColorspace(image,CMYKColorspace,exception); 4187 break; 4188 } 4189 case 'I': 4190 case 'i': 4191 { 4192 quantum_map[i]=IndexQuantum; 4193 (void) SetImageColorspace(image,GRAYColorspace,exception); 4194 break; 4195 } 4196 case 'm': 4197 case 'M': 4198 { 4199 quantum_map[i]=MagentaQuantum; 4200 (void) SetImageColorspace(image,CMYKColorspace,exception); 4201 break; 4202 } 4203 case 'O': 4204 case 'o': 4205 { 4206 quantum_map[i]=OpacityQuantum; 4207 image->alpha_trait=BlendPixelTrait; 4208 break; 4209 } 4210 case 'P': 4211 case 'p': 4212 { 4213 quantum_map[i]=UndefinedQuantum; 4214 break; 4215 } 4216 case 'R': 4217 case 'r': 4218 { 4219 quantum_map[i]=RedQuantum; 4220 break; 4221 } 4222 case 'Y': 4223 case 'y': 4224 { 4225 quantum_map[i]=YellowQuantum; 4226 (void) SetImageColorspace(image,CMYKColorspace,exception); 4227 break; 4228 } 4229 default: 4230 { 4231 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 4232 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 4233 "UnrecognizedPixelMap","`%s'",map); 4234 return(MagickFalse); 4235 } 4236 } 4237 } 4238 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 4239 return(MagickFalse); 4240 /* 4241 Transfer the pixels from the pixel data to the image. 4242 */ 4243 roi.width=width; 4244 roi.height=height; 4245 roi.x=x; 4246 roi.y=y; 4247 switch (type) 4248 { 4249 case CharPixel: 4250 { 4251 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception); 4252 break; 4253 } 4254 case DoublePixel: 4255 { 4256 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception); 4257 break; 4258 } 4259 case FloatPixel: 4260 { 4261 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception); 4262 break; 4263 } 4264 case LongPixel: 4265 { 4266 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception); 4267 break; 4268 } 4269 case LongLongPixel: 4270 { 4271 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception); 4272 break; 4273 } 4274 case QuantumPixel: 4275 { 4276 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception); 4277 break; 4278 } 4279 case ShortPixel: 4280 { 4281 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception); 4282 break; 4283 } 4284 default: 4285 { 4286 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 4287 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, 4288 "UnrecognizedStorageType","`%d'",type); 4289 break; 4290 } 4291 } 4292 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map); 4293 return(MagickTrue); 4294} 4295 4296/* 4297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4298% % 4299% % 4300% % 4301+ I n i t i a l i z e P i x e l C h a n n e l M a p % 4302% % 4303% % 4304% % 4305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4306% 4307% InitializePixelChannelMap() defines the standard pixel component map. 4308% 4309% The format of the InitializePixelChannelMap() method is: 4310% 4311% void InitializePixelChannelMap(Image *image) 4312% 4313% A description of each parameter follows: 4314% 4315% o image: the image. 4316% 4317*/ 4318 4319static void LogPixelChannels(const Image *image) 4320{ 4321 register ssize_t 4322 i; 4323 4324 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", 4325 image->filename,(double) image->number_channels); 4326 for (i=0; i < (ssize_t) image->number_channels; i++) 4327 { 4328 char 4329 traits[MagickPathExtent]; 4330 4331 const char 4332 *name; 4333 4334 PixelChannel 4335 channel; 4336 4337 switch (GetPixelChannelChannel(image,i)) 4338 { 4339 case RedPixelChannel: 4340 { 4341 name="red"; 4342 if (image->colorspace == CMYKColorspace) 4343 name="cyan"; 4344 if (image->colorspace == GRAYColorspace) 4345 name="gray"; 4346 break; 4347 } 4348 case GreenPixelChannel: 4349 { 4350 name="green"; 4351 if (image->colorspace == CMYKColorspace) 4352 name="magenta"; 4353 break; 4354 } 4355 case BluePixelChannel: 4356 { 4357 name="blue"; 4358 if (image->colorspace == CMYKColorspace) 4359 name="yellow"; 4360 break; 4361 } 4362 case BlackPixelChannel: 4363 { 4364 name="black"; 4365 if (image->storage_class == PseudoClass) 4366 name="index"; 4367 break; 4368 } 4369 case IndexPixelChannel: 4370 { 4371 name="index"; 4372 break; 4373 } 4374 case AlphaPixelChannel: 4375 { 4376 name="alpha"; 4377 break; 4378 } 4379 case ReadMaskPixelChannel: 4380 { 4381 name="read-mask"; 4382 break; 4383 } 4384 case WriteMaskPixelChannel: 4385 { 4386 name="write-mask"; 4387 break; 4388 } 4389 case MetaPixelChannel: 4390 { 4391 name="meta"; 4392 break; 4393 } 4394 default: 4395 name="undefined"; 4396 } 4397 channel=GetPixelChannelChannel(image,i); 4398 *traits='\0'; 4399 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) 4400 (void) ConcatenateMagickString(traits,"update,",MagickPathExtent); 4401 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) 4402 (void) ConcatenateMagickString(traits,"blend,",MagickPathExtent); 4403 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) 4404 (void) ConcatenateMagickString(traits,"copy,",MagickPathExtent); 4405 if (*traits == '\0') 4406 (void) ConcatenateMagickString(traits,"undefined,",MagickPathExtent); 4407 traits[strlen(traits)-1]='\0'; 4408 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", 4409 (double) i,name,traits); 4410 } 4411} 4412 4413MagickExport void InitializePixelChannelMap(Image *image) 4414{ 4415 PixelTrait 4416 trait; 4417 4418 register ssize_t 4419 i; 4420 4421 ssize_t 4422 n; 4423 4424 assert(image != (Image *) NULL); 4425 assert(image->signature == MagickCoreSignature); 4426 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels* 4427 sizeof(*image->channel_map)); 4428 trait=UpdatePixelTrait; 4429 if (image->alpha_trait != UndefinedPixelTrait) 4430 trait=(PixelTrait) (trait | BlendPixelTrait); 4431 n=0; 4432 if (image->colorspace == GRAYColorspace) 4433 { 4434 SetPixelChannelAttributes(image,BluePixelChannel,trait,n); 4435 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n); 4436 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++); 4437 } 4438 else 4439 { 4440 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++); 4441 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++); 4442 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++); 4443 } 4444 if (image->colorspace == CMYKColorspace) 4445 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++); 4446 if (image->alpha_trait != UndefinedPixelTrait) 4447 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++); 4448 if (image->storage_class == PseudoClass) 4449 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++); 4450 if (image->read_mask != MagickFalse) 4451 SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++); 4452 if (image->write_mask != MagickFalse) 4453 SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++); 4454 assert((n+image->number_meta_channels) < MaxPixelChannels); 4455 for (i=0; i < (ssize_t) image->number_meta_channels; i++) 4456 SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i), 4457 CopyPixelTrait,n++); 4458 image->number_channels=(size_t) n; 4459 if (image->debug != MagickFalse) 4460 LogPixelChannels(image); 4461 SetImageChannelMask(image,image->channel_mask); 4462} 4463 4464/* 4465%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4466% % 4467% % 4468% % 4469% I n t e r p o l a t e P i x e l C h a n n e l % 4470% % 4471% % 4472% % 4473%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4474% 4475% InterpolatePixelChannel() applies a pixel interpolation method between a 4476% floating point coordinate and the pixels surrounding that coordinate. No 4477% pixel area resampling, or scaling of the result is performed. 4478% 4479% Interpolation is restricted to just the specified channel. 4480% 4481% The format of the InterpolatePixelChannel method is: 4482% 4483% MagickBooleanType InterpolatePixelChannel(const Image *image, 4484% const CacheView *image_view,const PixelChannel channel, 4485% const PixelInterpolateMethod method,const double x,const double y, 4486% double *pixel,ExceptionInfo *exception) 4487% 4488% A description of each parameter follows: 4489% 4490% o image: the image. 4491% 4492% o image_view: the image view. 4493% 4494% o channel: the pixel channel to interpolate. 4495% 4496% o method: the pixel color interpolation method. 4497% 4498% o x,y: A double representing the current (x,y) position of the pixel. 4499% 4500% o pixel: return the interpolated pixel here. 4501% 4502% o exception: return any errors or warnings in this structure. 4503% 4504*/ 4505 4506static inline void CatromWeights(const double x,double (*weights)[4]) 4507{ 4508 double 4509 alpha, 4510 beta, 4511 gamma; 4512 4513 /* 4514 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation 4515 of the standard four 1D Catmull-Rom weights. The sampling location is 4516 assumed between the second and third input pixel locations, and x is the 4517 position relative to the second input pixel location. Formulas originally 4518 derived for the VIPS (Virtual Image Processing System) library. 4519 */ 4520 alpha=(double) 1.0-x; 4521 beta=(double) (-0.5)*x*alpha; 4522 (*weights)[0]=alpha*beta; 4523 (*weights)[3]=x*beta; 4524 /* 4525 The following computation of the inner weights from the outer ones work 4526 for all Keys cubics. 4527 */ 4528 gamma=(*weights)[3]-(*weights)[0]; 4529 (*weights)[1]=alpha-(*weights)[0]+gamma; 4530 (*weights)[2]=x-(*weights)[3]-gamma; 4531} 4532 4533static inline void SplineWeights(const double x,double (*weights)[4]) 4534{ 4535 double 4536 alpha, 4537 beta; 4538 4539 /* 4540 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation 4541 of the standard four 1D cubic B-spline smoothing weights. The sampling 4542 location is assumed between the second and third input pixel locations, 4543 and x is the position relative to the second input pixel location. 4544 */ 4545 alpha=(double) 1.0-x; 4546 (*weights)[3]=(double) (1.0/6.0)*x*x*x; 4547 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha; 4548 beta=(*weights)[3]-(*weights)[0]; 4549 (*weights)[1]=alpha-(*weights)[0]+beta; 4550 (*weights)[2]=x-(*weights)[3]-beta; 4551} 4552 4553static inline double MeshInterpolate(const PointInfo *delta,const double p, 4554 const double x,const double y) 4555{ 4556 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p); 4557} 4558 4559/* 4560static inline ssize_t NearestNeighbor(const double x) 4561{ 4562 if (x >= 0.0) 4563 return((ssize_t) (x+0.5)); 4564 return((ssize_t) (x-0.5)); 4565} 4566*/ 4567 4568MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image, 4569 const CacheView_ *image_view,const PixelChannel channel, 4570 const PixelInterpolateMethod method,const double x,const double y, 4571 double *pixel,ExceptionInfo *exception) 4572{ 4573 double 4574 alpha[16], 4575 gamma, 4576 pixels[16]; 4577 4578 MagickBooleanType 4579 status; 4580 4581 PixelInterpolateMethod 4582 interpolate; 4583 4584 PixelTrait 4585 traits; 4586 4587 register const Quantum 4588 *p; 4589 4590 register ssize_t 4591 i; 4592 4593 ssize_t 4594 x_offset, 4595 y_offset; 4596 4597 assert(image != (Image *) NULL); 4598 assert(image->signature == MagickCoreSignature); 4599 assert(image_view != (CacheView *) NULL); 4600 status=MagickTrue; 4601 *pixel=0.0; 4602 traits=GetPixelChannelTraits(image,channel); 4603 x_offset=(ssize_t) floor(x); 4604 y_offset=(ssize_t) floor(y); 4605 interpolate=method; 4606 if (interpolate == UndefinedInterpolatePixel) 4607 interpolate=image->interpolate; 4608 switch (interpolate) 4609 { 4610 case AverageInterpolatePixel: /* nearest 4 neighbours */ 4611 case Average9InterpolatePixel: /* nearest 9 neighbours */ 4612 case Average16InterpolatePixel: /* nearest 16 neighbours */ 4613 { 4614 ssize_t 4615 count; 4616 4617 count=2; /* size of the area to average - default nearest 4 */ 4618 if (interpolate == Average9InterpolatePixel) 4619 { 4620 count=3; 4621 x_offset=(ssize_t) (floor(x+0.5)-1); 4622 y_offset=(ssize_t) (floor(y+0.5)-1); 4623 } 4624 else 4625 if (interpolate == Average16InterpolatePixel) 4626 { 4627 count=4; 4628 x_offset--; 4629 y_offset--; 4630 } 4631 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count, 4632 (size_t) count,exception); 4633 if (p == (const Quantum *) NULL) 4634 { 4635 status=MagickFalse; 4636 break; 4637 } 4638 count*=count; /* Number of pixels to average */ 4639 if ((traits & BlendPixelTrait) == 0) 4640 for (i=0; i < (ssize_t) count; i++) 4641 { 4642 alpha[i]=1.0; 4643 pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; 4644 } 4645 else 4646 for (i=0; i < (ssize_t) count; i++) 4647 { 4648 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4649 GetPixelChannels(image)); 4650 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4651 } 4652 for (i=0; i < (ssize_t) count; i++) 4653 { 4654 gamma=PerceptibleReciprocal(alpha[i])/count; 4655 *pixel+=gamma*pixels[i]; 4656 } 4657 break; 4658 } 4659 case BilinearInterpolatePixel: 4660 default: 4661 { 4662 PointInfo 4663 delta, 4664 epsilon; 4665 4666 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 4667 if (p == (const Quantum *) NULL) 4668 { 4669 status=MagickFalse; 4670 break; 4671 } 4672 if ((traits & BlendPixelTrait) == 0) 4673 for (i=0; i < 4; i++) 4674 { 4675 alpha[i]=1.0; 4676 pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; 4677 } 4678 else 4679 for (i=0; i < 4; i++) 4680 { 4681 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4682 GetPixelChannels(image)); 4683 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4684 } 4685 delta.x=x-x_offset; 4686 delta.y=y-y_offset; 4687 epsilon.x=1.0-delta.x; 4688 epsilon.y=1.0-delta.y; 4689 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y* 4690 (epsilon.x*alpha[2]+delta.x*alpha[3]))); 4691 gamma=PerceptibleReciprocal(gamma); 4692 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y* 4693 (epsilon.x*pixels[2]+delta.x*pixels[3])); 4694 break; 4695 } 4696 case BlendInterpolatePixel: 4697 { 4698 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 4699 if (p == (const Quantum *) NULL) 4700 { 4701 status=MagickFalse; 4702 break; 4703 } 4704 if ((traits & BlendPixelTrait) == 0) 4705 for (i=0; i < 4; i++) 4706 { 4707 alpha[i]=1.0; 4708 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel]; 4709 } 4710 else 4711 for (i=0; i < 4; i++) 4712 { 4713 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4714 GetPixelChannels(image)); 4715 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4716 } 4717 gamma=1.0; /* number of pixels blended together (its variable) */ 4718 for (i=0; i <= 1L; i++) { 4719 if ((y-y_offset) >= 0.75) 4720 { 4721 alpha[i]=alpha[i+2]; /* take right pixels */ 4722 pixels[i]=pixels[i+2]; 4723 } 4724 else 4725 if ((y-y_offset) > 0.25) 4726 { 4727 gamma=2.0; /* blend both pixels in row */ 4728 alpha[i]+=alpha[i+2]; /* add up alpha weights */ 4729 pixels[i]+=pixels[i+2]; 4730 } 4731 } 4732 if ((x-x_offset) >= 0.75) 4733 { 4734 alpha[0]=alpha[1]; /* take bottom row blend */ 4735 pixels[0]=pixels[1]; 4736 } 4737 else 4738 if ((x-x_offset) > 0.25) 4739 { 4740 gamma*=2.0; /* blend both rows */ 4741 alpha[0]+=alpha[1]; /* add up alpha weights */ 4742 pixels[0]+=pixels[1]; 4743 } 4744 if (channel != AlphaPixelChannel) 4745 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */ 4746 else 4747 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */ 4748 *pixel=gamma*pixels[0]; 4749 break; 4750 } 4751 case CatromInterpolatePixel: 4752 { 4753 double 4754 cx[4], 4755 cy[4]; 4756 4757 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, 4758 exception); 4759 if (p == (const Quantum *) NULL) 4760 { 4761 status=MagickFalse; 4762 break; 4763 } 4764 if ((traits & BlendPixelTrait) == 0) 4765 for (i=0; i < 16; i++) 4766 { 4767 alpha[i]=1.0; 4768 pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; 4769 } 4770 else 4771 for (i=0; i < 16; i++) 4772 { 4773 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4774 GetPixelChannels(image)); 4775 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4776 } 4777 CatromWeights((double) (x-x_offset),&cx); 4778 CatromWeights((double) (y-y_offset),&cy); 4779 gamma=(channel == AlphaPixelChannel ? (double) 1.0 : 4780 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* 4781 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* 4782 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* 4783 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ 4784 cx[2]*alpha[14]+cx[3]*alpha[15]))); 4785 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+ 4786 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]* 4787 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+ 4788 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]* 4789 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15])); 4790 break; 4791 } 4792 case IntegerInterpolatePixel: 4793 { 4794 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); 4795 if (p == (const Quantum *) NULL) 4796 { 4797 status=MagickFalse; 4798 break; 4799 } 4800 *pixel=(double) GetPixelChannel(image,channel,p); 4801 break; 4802 } 4803 case NearestInterpolatePixel: 4804 { 4805 x_offset=(ssize_t) floor(x+0.5); 4806 y_offset=(ssize_t) floor(y+0.5); 4807 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); 4808 if (p == (const Quantum *) NULL) 4809 { 4810 status=MagickFalse; 4811 break; 4812 } 4813 *pixel=(double) GetPixelChannel(image,channel,p); 4814 break; 4815 } 4816 case MeshInterpolatePixel: 4817 { 4818 PointInfo 4819 delta, 4820 luminance; 4821 4822 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 4823 if (p == (const Quantum *) NULL) 4824 { 4825 status=MagickFalse; 4826 break; 4827 } 4828 if ((traits & BlendPixelTrait) == 0) 4829 for (i=0; i < 4; i++) 4830 { 4831 alpha[i]=1.0; 4832 pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; 4833 } 4834 else 4835 for (i=0; i < 4; i++) 4836 { 4837 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4838 GetPixelChannels(image)); 4839 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4840 } 4841 delta.x=x-x_offset; 4842 delta.y=y-y_offset; 4843 luminance.x=GetPixelLuma(image,p)-(double) 4844 GetPixelLuma(image,p+3*GetPixelChannels(image)); 4845 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double) 4846 GetPixelLuma(image,p+2*GetPixelChannels(image)); 4847 if (fabs(luminance.x) < fabs(luminance.y)) 4848 { 4849 /* 4850 Diagonal 0-3 NW-SE. 4851 */ 4852 if (delta.x <= delta.y) 4853 { 4854 /* 4855 Bottom-left triangle (pixel: 2, diagonal: 0-3). 4856 */ 4857 delta.y=1.0-delta.y; 4858 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]); 4859 gamma=PerceptibleReciprocal(gamma); 4860 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3], 4861 pixels[0]); 4862 } 4863 else 4864 { 4865 /* 4866 Top-right triangle (pixel: 1, diagonal: 0-3). 4867 */ 4868 delta.x=1.0-delta.x; 4869 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]); 4870 gamma=PerceptibleReciprocal(gamma); 4871 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0], 4872 pixels[3]); 4873 } 4874 } 4875 else 4876 { 4877 /* 4878 Diagonal 1-2 NE-SW. 4879 */ 4880 if (delta.x <= (1.0-delta.y)) 4881 { 4882 /* 4883 Top-left triangle (pixel: 0, diagonal: 1-2). 4884 */ 4885 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]); 4886 gamma=PerceptibleReciprocal(gamma); 4887 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1], 4888 pixels[2]); 4889 } 4890 else 4891 { 4892 /* 4893 Bottom-right triangle (pixel: 3, diagonal: 1-2). 4894 */ 4895 delta.x=1.0-delta.x; 4896 delta.y=1.0-delta.y; 4897 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]); 4898 gamma=PerceptibleReciprocal(gamma); 4899 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2], 4900 pixels[1]); 4901 } 4902 } 4903 break; 4904 } 4905 case SplineInterpolatePixel: 4906 { 4907 double 4908 cx[4], 4909 cy[4]; 4910 4911 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, 4912 exception); 4913 if (p == (const Quantum *) NULL) 4914 { 4915 status=MagickFalse; 4916 break; 4917 } 4918 if ((traits & BlendPixelTrait) == 0) 4919 for (i=0; i < 16; i++) 4920 { 4921 alpha[i]=1.0; 4922 pixels[i]=(double) p[i*GetPixelChannels(image)+channel]; 4923 } 4924 else 4925 for (i=0; i < 16; i++) 4926 { 4927 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i* 4928 GetPixelChannels(image)); 4929 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel]; 4930 } 4931 SplineWeights((double) (x-x_offset),&cx); 4932 SplineWeights((double) (y-y_offset),&cy); 4933 gamma=(channel == AlphaPixelChannel ? (double) 1.0 : 4934 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* 4935 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* 4936 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* 4937 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ 4938 cx[2]*alpha[14]+cx[3]*alpha[15]))); 4939 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+ 4940 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]* 4941 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+ 4942 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]* 4943 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15])); 4944 break; 4945 } 4946 } 4947 return(status); 4948} 4949 4950/* 4951%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4952% % 4953% % 4954% % 4955% I n t e r p o l a t e P i x e l C h a n n e l s % 4956% % 4957% % 4958% % 4959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4960% 4961% InterpolatePixelChannels() applies a pixel interpolation method between a 4962% floating point coordinate and the pixels surrounding that coordinate. No 4963% pixel area resampling, or scaling of the result is performed. 4964% 4965% Interpolation is restricted to just the current channel setting of the 4966% destination image into which the color is to be stored 4967% 4968% The format of the InterpolatePixelChannels method is: 4969% 4970% MagickBooleanType InterpolatePixelChannels(const Image *source, 4971% const CacheView *source_view,const Image *destination, 4972% const PixelInterpolateMethod method,const double x,const double y, 4973% Quantum *pixel,ExceptionInfo *exception) 4974% 4975% A description of each parameter follows: 4976% 4977% o source: the source. 4978% 4979% o source_view: the source view. 4980% 4981% o destination: the destination image, for the interpolated color 4982% 4983% o method: the pixel color interpolation method. 4984% 4985% o x,y: A double representing the current (x,y) position of the pixel. 4986% 4987% o pixel: return the interpolated pixel here. 4988% 4989% o exception: return any errors or warnings in this structure. 4990% 4991*/ 4992MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source, 4993 const CacheView_ *source_view,const Image *destination, 4994 const PixelInterpolateMethod method,const double x,const double y, 4995 Quantum *pixel,ExceptionInfo *exception) 4996{ 4997 MagickBooleanType 4998 status; 4999 5000 double 5001 alpha[16], 5002 gamma, 5003 pixels[16]; 5004 5005 register const Quantum 5006 *p; 5007 5008 register ssize_t 5009 i; 5010 5011 ssize_t 5012 x_offset, 5013 y_offset; 5014 5015 PixelInterpolateMethod 5016 interpolate; 5017 5018 assert(source != (Image *) NULL); 5019 assert(source->signature == MagickCoreSignature); 5020 assert(source_view != (CacheView *) NULL); 5021 status=MagickTrue; 5022 x_offset=(ssize_t) floor(x); 5023 y_offset=(ssize_t) floor(y); 5024 interpolate=method; 5025 if (interpolate == UndefinedInterpolatePixel) 5026 interpolate=source->interpolate; 5027 switch (interpolate) 5028 { 5029 case AverageInterpolatePixel: /* nearest 4 neighbours */ 5030 case Average9InterpolatePixel: /* nearest 9 neighbours */ 5031 case Average16InterpolatePixel: /* nearest 16 neighbours */ 5032 { 5033 ssize_t 5034 count; 5035 5036 count=2; /* size of the area to average - default nearest 4 */ 5037 if (interpolate == Average9InterpolatePixel) 5038 { 5039 count=3; 5040 x_offset=(ssize_t) (floor(x+0.5)-1); 5041 y_offset=(ssize_t) (floor(y+0.5)-1); 5042 } 5043 else 5044 if (interpolate == Average16InterpolatePixel) 5045 { 5046 count=4; 5047 x_offset--; 5048 y_offset--; 5049 } 5050 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count, 5051 (size_t) count,exception); 5052 if (p == (const Quantum *) NULL) 5053 { 5054 status=MagickFalse; 5055 break; 5056 } 5057 count*=count; /* Number of pixels to average */ 5058 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5059 { 5060 double 5061 sum; 5062 5063 register ssize_t 5064 j; 5065 5066 PixelChannel channel=GetPixelChannelChannel(source,i); 5067 PixelTrait traits=GetPixelChannelTraits(source,channel); 5068 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5069 channel); 5070 if ((traits == UndefinedPixelTrait) || 5071 (destination_traits == UndefinedPixelTrait)) 5072 continue; 5073 for (j=0; j < (ssize_t) count; j++) 5074 pixels[j]=(double) p[j*GetPixelChannels(source)+i]; 5075 sum=0.0; 5076 if ((traits & BlendPixelTrait) == 0) 5077 { 5078 for (j=0; j < (ssize_t) count; j++) 5079 sum+=pixels[j]; 5080 sum/=count; 5081 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel); 5082 continue; 5083 } 5084 for (j=0; j < (ssize_t) count; j++) 5085 { 5086 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* 5087 GetPixelChannels(source)); 5088 pixels[j]*=alpha[j]; 5089 gamma=PerceptibleReciprocal(alpha[j]); 5090 sum+=gamma*pixels[j]; 5091 } 5092 sum/=count; 5093 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel); 5094 } 5095 break; 5096 } 5097 case BilinearInterpolatePixel: 5098 default: 5099 { 5100 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception); 5101 if (p == (const Quantum *) NULL) 5102 { 5103 status=MagickFalse; 5104 break; 5105 } 5106 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5107 { 5108 PointInfo 5109 delta, 5110 epsilon; 5111 5112 PixelChannel channel=GetPixelChannelChannel(source,i); 5113 PixelTrait traits=GetPixelChannelTraits(source,channel); 5114 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5115 channel); 5116 if ((traits == UndefinedPixelTrait) || 5117 (destination_traits == UndefinedPixelTrait)) 5118 continue; 5119 delta.x=x-x_offset; 5120 delta.y=y-y_offset; 5121 epsilon.x=1.0-delta.x; 5122 epsilon.y=1.0-delta.y; 5123 pixels[0]=(double) p[i]; 5124 pixels[1]=(double) p[GetPixelChannels(source)+i]; 5125 pixels[2]=(double) p[2*GetPixelChannels(source)+i]; 5126 pixels[3]=(double) p[3*GetPixelChannels(source)+i]; 5127 if ((traits & BlendPixelTrait) == 0) 5128 { 5129 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x))); 5130 gamma=PerceptibleReciprocal(gamma); 5131 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y* 5132 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x* 5133 pixels[2]+delta.x*pixels[3]))),pixel); 5134 continue; 5135 } 5136 alpha[0]=QuantumScale*GetPixelAlpha(source,p); 5137 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source)); 5138 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2* 5139 GetPixelChannels(source)); 5140 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3* 5141 GetPixelChannels(source)); 5142 pixels[0]*=alpha[0]; 5143 pixels[1]*=alpha[1]; 5144 pixels[2]*=alpha[2]; 5145 pixels[3]*=alpha[3]; 5146 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y* 5147 (epsilon.x*alpha[2]+delta.x*alpha[3]))); 5148 gamma=PerceptibleReciprocal(gamma); 5149 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y* 5150 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+ 5151 delta.x*pixels[3]))),pixel); 5152 } 5153 break; 5154 } 5155 case BlendInterpolatePixel: 5156 { 5157 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception); 5158 if (p == (const Quantum *) NULL) 5159 { 5160 status=MagickFalse; 5161 break; 5162 } 5163 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5164 { 5165 register ssize_t 5166 j; 5167 5168 PixelChannel channel=GetPixelChannelChannel(source,i); 5169 PixelTrait traits=GetPixelChannelTraits(source,channel); 5170 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5171 channel); 5172 if ((traits == UndefinedPixelTrait) || 5173 (destination_traits == UndefinedPixelTrait)) 5174 continue; 5175 if (source->alpha_trait != BlendPixelTrait) 5176 for (j=0; j < 4; j++) 5177 { 5178 alpha[j]=1.0; 5179 pixels[j]=(double) p[j*GetPixelChannels(source)+i]; 5180 } 5181 else 5182 for (j=0; j < 4; j++) 5183 { 5184 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* 5185 GetPixelChannels(source)); 5186 pixels[j]=(double) p[j*GetPixelChannels(source)+i]; 5187 if (channel != AlphaPixelChannel) 5188 pixels[j]*=alpha[j]; 5189 } 5190 gamma=1.0; /* number of pixels blended together (its variable) */ 5191 for (j=0; j <= 1L; j++) 5192 { 5193 if ((y-y_offset) >= 0.75) 5194 { 5195 alpha[j]=alpha[j+2]; /* take right pixels */ 5196 pixels[j]=pixels[j+2]; 5197 } 5198 else 5199 if ((y-y_offset) > 0.25) 5200 { 5201 gamma=2.0; /* blend both pixels in row */ 5202 alpha[j]+=alpha[j+2]; /* add up alpha weights */ 5203 pixels[j]+=pixels[j+2]; 5204 } 5205 } 5206 if ((x-x_offset) >= 0.75) 5207 { 5208 alpha[0]=alpha[1]; /* take bottom row blend */ 5209 pixels[0]=pixels[1]; 5210 } 5211 else 5212 if ((x-x_offset) > 0.25) 5213 { 5214 gamma*=2.0; /* blend both rows */ 5215 alpha[0]+=alpha[1]; /* add up alpha weights */ 5216 pixels[0]+=pixels[1]; 5217 } 5218 if (channel != AlphaPixelChannel) 5219 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */ 5220 else 5221 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */ 5222 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]), 5223 pixel); 5224 } 5225 break; 5226 } 5227 case CatromInterpolatePixel: 5228 { 5229 double 5230 cx[4], 5231 cy[4]; 5232 5233 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4, 5234 exception); 5235 if (p == (const Quantum *) NULL) 5236 { 5237 status=MagickFalse; 5238 break; 5239 } 5240 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5241 { 5242 register ssize_t 5243 j; 5244 5245 PixelChannel channel=GetPixelChannelChannel(source,i); 5246 PixelTrait traits=GetPixelChannelTraits(source,channel); 5247 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5248 channel); 5249 if ((traits == UndefinedPixelTrait) || 5250 (destination_traits == UndefinedPixelTrait)) 5251 continue; 5252 if ((traits & BlendPixelTrait) == 0) 5253 for (j=0; j < 16; j++) 5254 { 5255 alpha[j]=1.0; 5256 pixels[j]=(double) p[j*GetPixelChannels(source)+i]; 5257 } 5258 else 5259 for (j=0; j < 16; j++) 5260 { 5261 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* 5262 GetPixelChannels(source)); 5263 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i]; 5264 } 5265 CatromWeights((double) (x-x_offset),&cx); 5266 CatromWeights((double) (y-y_offset),&cy); 5267 gamma=((traits & BlendPixelTrait) ? (double) (1.0) : 5268 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* 5269 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* 5270 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* 5271 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ 5272 cx[2]*alpha[14]+cx[3]*alpha[15]))); 5273 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]* 5274 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]* 5275 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+ 5276 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]* 5277 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]* 5278 pixels[14]+cx[3]*pixels[15]))),pixel); 5279 } 5280 break; 5281 } 5282 case IntegerInterpolatePixel: 5283 { 5284 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception); 5285 if (p == (const Quantum *) NULL) 5286 { 5287 status=MagickFalse; 5288 break; 5289 } 5290 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5291 { 5292 PixelChannel channel=GetPixelChannelChannel(source,i); 5293 PixelTrait traits=GetPixelChannelTraits(source,channel); 5294 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5295 channel); 5296 if ((traits == UndefinedPixelTrait) || 5297 (destination_traits == UndefinedPixelTrait)) 5298 continue; 5299 SetPixelChannel(destination,channel,p[i],pixel); 5300 } 5301 break; 5302 } 5303 case NearestInterpolatePixel: 5304 { 5305 x_offset=(ssize_t) floor(x+0.5); 5306 y_offset=(ssize_t) floor(y+0.5); 5307 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception); 5308 if (p == (const Quantum *) NULL) 5309 { 5310 status=MagickFalse; 5311 break; 5312 } 5313 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5314 { 5315 PixelChannel channel=GetPixelChannelChannel(source,i); 5316 PixelTrait traits=GetPixelChannelTraits(source,channel); 5317 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5318 channel); 5319 if ((traits == UndefinedPixelTrait) || 5320 (destination_traits == UndefinedPixelTrait)) 5321 continue; 5322 SetPixelChannel(destination,channel,p[i],pixel); 5323 } 5324 break; 5325 } 5326 case MeshInterpolatePixel: 5327 { 5328 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception); 5329 if (p == (const Quantum *) NULL) 5330 { 5331 status=MagickFalse; 5332 break; 5333 } 5334 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5335 { 5336 PointInfo 5337 delta, 5338 luminance; 5339 5340 PixelChannel channel=GetPixelChannelChannel(source,i); 5341 PixelTrait traits=GetPixelChannelTraits(source,channel); 5342 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5343 channel); 5344 if ((traits == UndefinedPixelTrait) || 5345 (destination_traits == UndefinedPixelTrait)) 5346 continue; 5347 pixels[0]=(double) p[i]; 5348 pixels[1]=(double) p[GetPixelChannels(source)+i]; 5349 pixels[2]=(double) p[2*GetPixelChannels(source)+i]; 5350 pixels[3]=(double) p[3*GetPixelChannels(source)+i]; 5351 if ((traits & BlendPixelTrait) == 0) 5352 { 5353 alpha[0]=1.0; 5354 alpha[1]=1.0; 5355 alpha[2]=1.0; 5356 alpha[3]=1.0; 5357 } 5358 else 5359 { 5360 alpha[0]=QuantumScale*GetPixelAlpha(source,p); 5361 alpha[1]=QuantumScale*GetPixelAlpha(source,p+ 5362 GetPixelChannels(source)); 5363 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2* 5364 GetPixelChannels(source)); 5365 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3* 5366 GetPixelChannels(source)); 5367 } 5368 delta.x=x-x_offset; 5369 delta.y=y-y_offset; 5370 luminance.x=fabs((double) (GetPixelLuma(source,p)- 5371 GetPixelLuma(source,p+3*GetPixelChannels(source)))); 5372 luminance.y=fabs((double) (GetPixelLuma(source,p+ 5373 GetPixelChannels(source))-GetPixelLuma(source,p+2* 5374 GetPixelChannels(source)))); 5375 if (luminance.x < luminance.y) 5376 { 5377 /* 5378 Diagonal 0-3 NW-SE. 5379 */ 5380 if (delta.x <= delta.y) 5381 { 5382 /* 5383 Bottom-left triangle (pixel: 2, diagonal: 0-3). 5384 */ 5385 delta.y=1.0-delta.y; 5386 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]); 5387 gamma=PerceptibleReciprocal(gamma); 5388 SetPixelChannel(destination,channel,ClampToQuantum(gamma* 5389 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel); 5390 } 5391 else 5392 { 5393 /* 5394 Top-right triangle (pixel: 1, diagonal: 0-3). 5395 */ 5396 delta.x=1.0-delta.x; 5397 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]); 5398 gamma=PerceptibleReciprocal(gamma); 5399 SetPixelChannel(destination,channel,ClampToQuantum(gamma* 5400 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel); 5401 } 5402 } 5403 else 5404 { 5405 /* 5406 Diagonal 1-2 NE-SW. 5407 */ 5408 if (delta.x <= (1.0-delta.y)) 5409 { 5410 /* 5411 Top-left triangle (pixel: 0, diagonal: 1-2). 5412 */ 5413 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]); 5414 gamma=PerceptibleReciprocal(gamma); 5415 SetPixelChannel(destination,channel,ClampToQuantum(gamma* 5416 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel); 5417 } 5418 else 5419 { 5420 /* 5421 Bottom-right triangle (pixel: 3, diagonal: 1-2). 5422 */ 5423 delta.x=1.0-delta.x; 5424 delta.y=1.0-delta.y; 5425 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]); 5426 gamma=PerceptibleReciprocal(gamma); 5427 SetPixelChannel(destination,channel,ClampToQuantum(gamma* 5428 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel); 5429 } 5430 } 5431 } 5432 break; 5433 } 5434 case SplineInterpolatePixel: 5435 { 5436 double 5437 cx[4], 5438 cy[4]; 5439 5440 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4, 5441 exception); 5442 if (p == (const Quantum *) NULL) 5443 { 5444 status=MagickFalse; 5445 break; 5446 } 5447 for (i=0; i < (ssize_t) GetPixelChannels(source); i++) 5448 { 5449 register ssize_t 5450 j; 5451 5452 PixelChannel channel=GetPixelChannelChannel(source,i); 5453 PixelTrait traits=GetPixelChannelTraits(source,channel); 5454 PixelTrait destination_traits=GetPixelChannelTraits(destination, 5455 channel); 5456 if ((traits == UndefinedPixelTrait) || 5457 (destination_traits == UndefinedPixelTrait)) 5458 continue; 5459 if ((traits & BlendPixelTrait) == 0) 5460 for (j=0; j < 16; j++) 5461 { 5462 alpha[j]=1.0; 5463 pixels[j]=(double) p[j*GetPixelChannels(source)+i]; 5464 } 5465 else 5466 for (j=0; j < 16; j++) 5467 { 5468 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j* 5469 GetPixelChannels(source)); 5470 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i]; 5471 } 5472 SplineWeights((double) (x-x_offset),&cx); 5473 SplineWeights((double) (y-y_offset),&cy); 5474 gamma=((traits & BlendPixelTrait) ? (double) (1.0) : 5475 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]* 5476 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]* 5477 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]* 5478 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+ 5479 cx[2]*alpha[14]+cx[3]*alpha[15]))); 5480 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]* 5481 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]* 5482 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+ 5483 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]* 5484 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]* 5485 pixels[14]+cx[3]*pixels[15]))),pixel); 5486 } 5487 break; 5488 } 5489 } 5490 return(status); 5491} 5492 5493/* 5494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5495% % 5496% % 5497% % 5498% I n t e r p o l a t e P i x e l I n f o % 5499% % 5500% % 5501% % 5502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5503% 5504% InterpolatePixelInfo() applies a pixel interpolation method between a 5505% floating point coordinate and the pixels surrounding that coordinate. No 5506% pixel area resampling, or scaling of the result is performed. 5507% 5508% Interpolation is restricted to just RGBKA channels. 5509% 5510% The format of the InterpolatePixelInfo method is: 5511% 5512% MagickBooleanType InterpolatePixelInfo(const Image *image, 5513% const CacheView *image_view,const PixelInterpolateMethod method, 5514% const double x,const double y,PixelInfo *pixel, 5515% ExceptionInfo *exception) 5516% 5517% A description of each parameter follows: 5518% 5519% o image: the image. 5520% 5521% o image_view: the image view. 5522% 5523% o method: the pixel color interpolation method. 5524% 5525% o x,y: A double representing the current (x,y) position of the pixel. 5526% 5527% o pixel: return the interpolated pixel here. 5528% 5529% o exception: return any errors or warnings in this structure. 5530% 5531*/ 5532 5533static inline void AlphaBlendPixelInfo(const Image *image, 5534 const Quantum *pixel,PixelInfo *pixel_info,double *alpha) 5535{ 5536 if (image->alpha_trait == UndefinedPixelTrait) 5537 { 5538 *alpha=1.0; 5539 pixel_info->red=(double) GetPixelRed(image,pixel); 5540 pixel_info->green=(double) GetPixelGreen(image,pixel); 5541 pixel_info->blue=(double) GetPixelBlue(image,pixel); 5542 pixel_info->black=0.0; 5543 if (image->colorspace == CMYKColorspace) 5544 pixel_info->black=(double) GetPixelBlack(image,pixel); 5545 pixel_info->alpha=(double) GetPixelAlpha(image,pixel); 5546 return; 5547 } 5548 *alpha=QuantumScale*GetPixelAlpha(image,pixel); 5549 pixel_info->red=(*alpha*GetPixelRed(image,pixel)); 5550 pixel_info->green=(*alpha*GetPixelGreen(image,pixel)); 5551 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel)); 5552 pixel_info->black=0.0; 5553 if (image->colorspace == CMYKColorspace) 5554 pixel_info->black=(*alpha*GetPixelBlack(image,pixel)); 5555 pixel_info->alpha=(double) GetPixelAlpha(image,pixel); 5556} 5557 5558MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image, 5559 const CacheView_ *image_view,const PixelInterpolateMethod method, 5560 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception) 5561{ 5562 MagickBooleanType 5563 status; 5564 5565 double 5566 alpha[16], 5567 gamma; 5568 5569 PixelInfo 5570 pixels[16]; 5571 5572 register const Quantum 5573 *p; 5574 5575 register ssize_t 5576 i; 5577 5578 ssize_t 5579 x_offset, 5580 y_offset; 5581 5582 PixelInterpolateMethod 5583 interpolate; 5584 5585 assert(image != (Image *) NULL); 5586 assert(image->signature == MagickCoreSignature); 5587 assert(image_view != (CacheView *) NULL); 5588 status=MagickTrue; 5589 x_offset=(ssize_t) floor(x); 5590 y_offset=(ssize_t) floor(y); 5591 interpolate=method; 5592 if (interpolate == UndefinedInterpolatePixel) 5593 interpolate=image->interpolate; 5594 (void) ResetMagickMemory(&pixels,0,sizeof(pixels)); 5595 switch (interpolate) 5596 { 5597 case AverageInterpolatePixel: /* nearest 4 neighbours */ 5598 case Average9InterpolatePixel: /* nearest 9 neighbours */ 5599 case Average16InterpolatePixel: /* nearest 16 neighbours */ 5600 { 5601 ssize_t 5602 count; 5603 5604 count=2; /* size of the area to average - default nearest 4 */ 5605 if (interpolate == Average9InterpolatePixel) 5606 { 5607 count=3; 5608 x_offset=(ssize_t) (floor(x+0.5)-1); 5609 y_offset=(ssize_t) (floor(y+0.5)-1); 5610 } 5611 else if (interpolate == Average16InterpolatePixel) 5612 { 5613 count=4; 5614 x_offset--; 5615 y_offset--; 5616 } 5617 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count, 5618 (size_t) count,exception); 5619 if (p == (const Quantum *) NULL) 5620 { 5621 status=MagickFalse; 5622 break; 5623 } 5624 pixel->red=0.0; 5625 pixel->green=0.0; 5626 pixel->blue=0.0; 5627 pixel->black=0.0; 5628 pixel->alpha=0.0; 5629 count*=count; /* number of pixels - square of size */ 5630 for (i=0; i < (ssize_t) count; i++) 5631 { 5632 AlphaBlendPixelInfo(image,p,pixels,alpha); 5633 gamma=PerceptibleReciprocal(alpha[0]); 5634 pixel->red+=gamma*pixels[0].red; 5635 pixel->green+=gamma*pixels[0].green; 5636 pixel->blue+=gamma*pixels[0].blue; 5637 pixel->black+=gamma*pixels[0].black; 5638 pixel->alpha+=pixels[0].alpha; 5639 p += GetPixelChannels(image); 5640 } 5641 gamma=1.0/count; /* average weighting of each pixel in area */ 5642 pixel->red*=gamma; 5643 pixel->green*=gamma; 5644 pixel->blue*=gamma; 5645 pixel->black*=gamma; 5646 pixel->alpha*=gamma; 5647 break; 5648 } 5649 case BackgroundInterpolatePixel: 5650 { 5651 *pixel=image->background_color; /* Copy PixelInfo Structure */ 5652 break; 5653 } 5654 case BilinearInterpolatePixel: 5655 default: 5656 { 5657 PointInfo 5658 delta, 5659 epsilon; 5660 5661 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 5662 if (p == (const Quantum *) NULL) 5663 { 5664 status=MagickFalse; 5665 break; 5666 } 5667 for (i=0; i < 4L; i++) 5668 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); 5669 delta.x=x-x_offset; 5670 delta.y=y-y_offset; 5671 epsilon.x=1.0-delta.x; 5672 epsilon.y=1.0-delta.y; 5673 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y* 5674 (epsilon.x*alpha[2]+delta.x*alpha[3]))); 5675 gamma=PerceptibleReciprocal(gamma); 5676 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x* 5677 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red)); 5678 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x* 5679 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x* 5680 pixels[3].green)); 5681 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x* 5682 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x* 5683 pixels[3].blue)); 5684 if (image->colorspace == CMYKColorspace) 5685 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x* 5686 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x* 5687 pixels[3].black)); 5688 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x))); 5689 gamma=PerceptibleReciprocal(gamma); 5690 pixel->alpha=gamma*(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x* 5691 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x* 5692 pixels[3].alpha)); 5693 break; 5694 } 5695 case BlendInterpolatePixel: 5696 { 5697 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 5698 if (p == (const Quantum *) NULL) 5699 { 5700 status=MagickFalse; 5701 break; 5702 } 5703 for (i=0; i < 4L; i++) 5704 { 5705 GetPixelInfoPixel(image,p+i*GetPixelChannels(image),pixels+i); 5706 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); 5707 } 5708 gamma=1.0; /* number of pixels blended together (its variable) */ 5709 for (i=0; i <= 1L; i++) 5710 { 5711 if ((y-y_offset) >= 0.75) 5712 { 5713 alpha[i]=alpha[i+2]; /* take right pixels */ 5714 pixels[i]=pixels[i+2]; 5715 } 5716 else 5717 if ((y-y_offset) > 0.25) 5718 { 5719 gamma=2.0; /* blend both pixels in row */ 5720 alpha[i]+=alpha[i+2]; /* add up alpha weights */ 5721 pixels[i].red+=pixels[i+2].red; 5722 pixels[i].green+=pixels[i+2].green; 5723 pixels[i].blue+=pixels[i+2].blue; 5724 pixels[i].black+=pixels[i+2].black; 5725 pixels[i].alpha+=pixels[i+2].alpha; 5726 } 5727 } 5728 if ((x-x_offset) >= 0.75) 5729 { 5730 alpha[0]=alpha[1]; 5731 pixels[0]=pixels[1]; 5732 } 5733 else 5734 if ((x-x_offset) > 0.25) 5735 { 5736 gamma*=2.0; /* blend both rows */ 5737 alpha[0]+= alpha[1]; /* add up alpha weights */ 5738 pixels[0].red+=pixels[1].red; 5739 pixels[0].green+=pixels[1].green; 5740 pixels[0].blue+=pixels[1].blue; 5741 pixels[0].black+=pixels[1].black; 5742 pixels[0].alpha+=pixels[1].alpha; 5743 } 5744 gamma=1.0/gamma; 5745 alpha[0]=PerceptibleReciprocal(alpha[0]); 5746 pixel->red=alpha[0]*pixels[0].red; 5747 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */ 5748 pixel->blue=alpha[0]*pixels[0].blue; 5749 pixel->black=alpha[0]*pixels[0].black; 5750 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */ 5751 break; 5752 } 5753 case CatromInterpolatePixel: 5754 { 5755 double 5756 cx[4], 5757 cy[4]; 5758 5759 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, 5760 exception); 5761 if (p == (const Quantum *) NULL) 5762 { 5763 status=MagickFalse; 5764 break; 5765 } 5766 for (i=0; i < 16L; i++) 5767 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); 5768 CatromWeights((double) (x-x_offset),&cx); 5769 CatromWeights((double) (y-y_offset),&cy); 5770 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]* 5771 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]* 5772 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]* 5773 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]* 5774 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]* 5775 pixels[14].red+cx[3]*pixels[15].red)); 5776 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]* 5777 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+ 5778 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+ 5779 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]* 5780 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]* 5781 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]* 5782 pixels[15].green)); 5783 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]* 5784 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]* 5785 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]* 5786 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]* 5787 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+ 5788 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue)); 5789 if (image->colorspace == CMYKColorspace) 5790 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]* 5791 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+ 5792 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+ 5793 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]* 5794 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]* 5795 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]* 5796 pixels[15].black)); 5797 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]* 5798 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+ 5799 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+ 5800 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]* 5801 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+ 5802 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha)); 5803 break; 5804 } 5805 case IntegerInterpolatePixel: 5806 { 5807 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); 5808 if (p == (const Quantum *) NULL) 5809 { 5810 status=MagickFalse; 5811 break; 5812 } 5813 GetPixelInfoPixel(image,p,pixel); 5814 break; 5815 } 5816 case MeshInterpolatePixel: 5817 { 5818 PointInfo 5819 delta, 5820 luminance; 5821 5822 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception); 5823 if (p == (const Quantum *) NULL) 5824 { 5825 status=MagickFalse; 5826 break; 5827 } 5828 delta.x=x-x_offset; 5829 delta.y=y-y_offset; 5830 luminance.x=GetPixelLuma(image,p)-(double) 5831 GetPixelLuma(image,p+3*GetPixelChannels(image)); 5832 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double) 5833 GetPixelLuma(image,p+2*GetPixelChannels(image)); 5834 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0); 5835 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1); 5836 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2); 5837 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3); 5838 if (fabs(luminance.x) < fabs(luminance.y)) 5839 { 5840 /* 5841 Diagonal 0-3 NW-SE. 5842 */ 5843 if (delta.x <= delta.y) 5844 { 5845 /* 5846 Bottom-left triangle (pixel: 2, diagonal: 0-3). 5847 */ 5848 delta.y=1.0-delta.y; 5849 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]); 5850 gamma=PerceptibleReciprocal(gamma); 5851 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red, 5852 pixels[3].red,pixels[0].red); 5853 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green, 5854 pixels[3].green,pixels[0].green); 5855 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue, 5856 pixels[3].blue,pixels[0].blue); 5857 if (image->colorspace == CMYKColorspace) 5858 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black, 5859 pixels[3].black,pixels[0].black); 5860 gamma=MeshInterpolate(&delta,1.0,1.0,1.0); 5861 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha, 5862 pixels[3].alpha,pixels[0].alpha); 5863 } 5864 else 5865 { 5866 /* 5867 Top-right triangle (pixel:1 , diagonal: 0-3). 5868 */ 5869 delta.x=1.0-delta.x; 5870 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]); 5871 gamma=PerceptibleReciprocal(gamma); 5872 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red, 5873 pixels[0].red,pixels[3].red); 5874 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green, 5875 pixels[0].green,pixels[3].green); 5876 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue, 5877 pixels[0].blue,pixels[3].blue); 5878 if (image->colorspace == CMYKColorspace) 5879 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black, 5880 pixels[0].black,pixels[3].black); 5881 gamma=MeshInterpolate(&delta,1.0,1.0,1.0); 5882 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha, 5883 pixels[0].alpha,pixels[3].alpha); 5884 } 5885 } 5886 else 5887 { 5888 /* 5889 Diagonal 1-2 NE-SW. 5890 */ 5891 if (delta.x <= (1.0-delta.y)) 5892 { 5893 /* 5894 Top-left triangle (pixel: 0, diagonal: 1-2). 5895 */ 5896 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]); 5897 gamma=PerceptibleReciprocal(gamma); 5898 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red, 5899 pixels[1].red,pixels[2].red); 5900 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green, 5901 pixels[1].green,pixels[2].green); 5902 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue, 5903 pixels[1].blue,pixels[2].blue); 5904 if (image->colorspace == CMYKColorspace) 5905 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black, 5906 pixels[1].black,pixels[2].black); 5907 gamma=MeshInterpolate(&delta,1.0,1.0,1.0); 5908 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha, 5909 pixels[1].alpha,pixels[2].alpha); 5910 } 5911 else 5912 { 5913 /* 5914 Bottom-right triangle (pixel: 3, diagonal: 1-2). 5915 */ 5916 delta.x=1.0-delta.x; 5917 delta.y=1.0-delta.y; 5918 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]); 5919 gamma=PerceptibleReciprocal(gamma); 5920 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red, 5921 pixels[2].red,pixels[1].red); 5922 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green, 5923 pixels[2].green,pixels[1].green); 5924 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue, 5925 pixels[2].blue,pixels[1].blue); 5926 if (image->colorspace == CMYKColorspace) 5927 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black, 5928 pixels[2].black,pixels[1].black); 5929 gamma=MeshInterpolate(&delta,1.0,1.0,1.0); 5930 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha, 5931 pixels[2].alpha,pixels[1].alpha); 5932 } 5933 } 5934 break; 5935 } 5936 case NearestInterpolatePixel: 5937 { 5938 x_offset=(ssize_t) floor(x+0.5); 5939 y_offset=(ssize_t) floor(y+0.5); 5940 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception); 5941 if (p == (const Quantum *) NULL) 5942 { 5943 status=MagickFalse; 5944 break; 5945 } 5946 GetPixelInfoPixel(image,p,pixel); 5947 break; 5948 } 5949 case SplineInterpolatePixel: 5950 { 5951 double 5952 cx[4], 5953 cy[4]; 5954 5955 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4, 5956 exception); 5957 if (p == (const Quantum *) NULL) 5958 { 5959 status=MagickFalse; 5960 break; 5961 } 5962 for (i=0; i < 16L; i++) 5963 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i); 5964 SplineWeights((double) (x-x_offset),&cx); 5965 SplineWeights((double) (y-y_offset),&cy); 5966 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]* 5967 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]* 5968 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]* 5969 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]* 5970 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]* 5971 pixels[14].red+cx[3]*pixels[15].red)); 5972 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]* 5973 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+ 5974 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+ 5975 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]* 5976 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+ 5977 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green)); 5978 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]* 5979 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]* 5980 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]* 5981 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]* 5982 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+ 5983 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue)); 5984 if (image->colorspace == CMYKColorspace) 5985 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]* 5986 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+ 5987 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+ 5988 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]* 5989 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]* 5990 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]* 5991 pixels[15].black)); 5992 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]* 5993 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+ 5994 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+ 5995 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]* 5996 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+ 5997 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha)); 5998 break; 5999 } 6000 } 6001 return(status); 6002} 6003 6004/* 6005%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6006% % 6007% % 6008% % 6009+ I s F u z z y E q u i v a l e n c e P i x e l % 6010% % 6011% % 6012% % 6013%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6014% 6015% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two 6016% pixels is less than the specified distance in a linear three (or four) 6017% dimensional color space. 6018% 6019% The format of the IsFuzzyEquivalencePixel method is: 6020% 6021% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p, 6022% const Image *destination,const Quantum *q) 6023% 6024% A description of each parameter follows: 6025% 6026% o source: the source image. 6027% 6028% o p: Pixel p. 6029% 6030% o destination: the destination image. 6031% 6032% o q: Pixel q. 6033% 6034*/ 6035MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source, 6036 const Quantum *p,const Image *destination,const Quantum *q) 6037{ 6038 double 6039 fuzz, 6040 pixel; 6041 6042 register double 6043 distance, 6044 scale; 6045 6046 fuzz=GetFuzzyColorDistance(source,destination); 6047 scale=1.0; 6048 distance=0.0; 6049 if (source->alpha_trait != UndefinedPixelTrait || 6050 destination->alpha_trait != UndefinedPixelTrait) 6051 { 6052 /* 6053 Transparencies are involved - set alpha distance 6054 */ 6055 pixel=GetPixelAlpha(source,p)-(double) GetPixelAlpha(destination,q); 6056 distance=pixel*pixel; 6057 if (distance > fuzz) 6058 return(MagickFalse); 6059 /* 6060 Generate a alpha scaling factor to generate a 4D cone on colorspace 6061 Note that if one color is transparent, distance has no color component. 6062 */ 6063 if (source->alpha_trait != UndefinedPixelTrait) 6064 scale=QuantumScale*GetPixelAlpha(source,p); 6065 if (destination->alpha_trait != UndefinedPixelTrait) 6066 scale*=QuantumScale*GetPixelAlpha(destination,q); 6067 if (scale <= MagickEpsilon) 6068 return(MagickTrue); 6069 } 6070 /* 6071 RGB or CMY color cube 6072 */ 6073 distance*=3.0; /* rescale appropriately */ 6074 fuzz*=3.0; 6075 pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q); 6076 if ((source->colorspace == HSLColorspace) || 6077 (source->colorspace == HSBColorspace) || 6078 (source->colorspace == HWBColorspace)) 6079 { 6080 /* 6081 Compute an arc distance for hue. It should be a vector angle of 6082 'S'/'W' length with 'L'/'B' forming appropriate cones. 6083 */ 6084 if (fabs((double) pixel) > (QuantumRange/2)) 6085 pixel-=QuantumRange; 6086 pixel*=2; 6087 } 6088 distance+=scale*pixel*pixel; 6089 if (distance > fuzz) 6090 return(MagickFalse); 6091 pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q); 6092 distance+=scale*pixel*pixel; 6093 if (distance > fuzz) 6094 return(MagickFalse); 6095 pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q); 6096 distance+=scale*pixel*pixel; 6097 if (distance > fuzz) 6098 return(MagickFalse); 6099 return(MagickTrue); 6100} 6101 6102/* 6103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6104% % 6105% % 6106% % 6107+ I s F u z z y E q u i v a l e n c e P i x e l I n f o % 6108% % 6109% % 6110% % 6111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6112% 6113% IsFuzzyEquivalencePixelInfo() returns true if the distance between two 6114% colors is less than the specified distance in a linear three (or four) 6115% dimensional color space. 6116% 6117% This implements the equivalent of: 6118% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2) 6119% 6120% Which produces a multi-dimensional cone for that colorspace along the 6121% transparency vector. 6122% 6123% For example for an RGB: 6124% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3 6125% 6126% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/ 6127% 6128% Hue colorspace distances need more work. Hue is not a distance, it is an 6129% angle! 6130% 6131% A check that q is in the same color space as p should be made and the 6132% appropriate mapping made. -- Anthony Thyssen 8 December 2010 6133% 6134% The format of the IsFuzzyEquivalencePixelInfo method is: 6135% 6136% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, 6137% const PixelInfo *q) 6138% 6139% A description of each parameter follows: 6140% 6141% o p: Pixel p. 6142% 6143% o q: Pixel q. 6144% 6145*/ 6146MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p, 6147 const PixelInfo *q) 6148{ 6149 double 6150 fuzz, 6151 pixel; 6152 6153 register double 6154 scale, 6155 distance; 6156 6157 fuzz=(double) MagickMax(MagickMax(p->fuzz,q->fuzz),(MagickRealType) 6158 MagickSQ1_2); 6159 fuzz*=fuzz; 6160 scale=1.0; 6161 distance=0.0; 6162 if ((p->alpha_trait != UndefinedPixelTrait) || 6163 (q->alpha_trait != UndefinedPixelTrait)) 6164 { 6165 /* 6166 Transparencies are involved - set alpha distance. 6167 */ 6168 pixel=(p->alpha_trait != UndefinedPixelTrait ? p->alpha : OpaqueAlpha)- 6169 (q->alpha_trait != UndefinedPixelTrait ? q->alpha : OpaqueAlpha); 6170 distance=pixel*pixel; 6171 if (distance > fuzz) 6172 return(MagickFalse); 6173 /* 6174 Generate a alpha scaling factor to generate a 4D cone on colorspace. 6175 If one color is transparent, distance has no color component. 6176 */ 6177 if (p->alpha_trait != UndefinedPixelTrait) 6178 scale=(QuantumScale*p->alpha); 6179 if (q->alpha_trait != UndefinedPixelTrait) 6180 scale*=(QuantumScale*q->alpha); 6181 if (scale <= MagickEpsilon ) 6182 return(MagickTrue); 6183 } 6184 /* 6185 CMYK create a CMY cube with a multi-dimensional cone toward black. 6186 */ 6187 if (p->colorspace == CMYKColorspace) 6188 { 6189 pixel=p->black-q->black; 6190 distance+=pixel*pixel*scale; 6191 if (distance > fuzz) 6192 return(MagickFalse); 6193 scale*=(double) (QuantumScale*(QuantumRange-p->black)); 6194 scale*=(double) (QuantumScale*(QuantumRange-q->black)); 6195 } 6196 /* 6197 RGB or CMY color cube. 6198 */ 6199 distance*=3.0; /* rescale appropriately */ 6200 fuzz*=3.0; 6201 pixel=p->red-q->red; 6202 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) || 6203 (p->colorspace == HWBColorspace)) 6204 { 6205 /* 6206 This calculates a arc distance for hue-- it should be a vector 6207 angle of 'S'/'W' length with 'L'/'B' forming appropriate cones. 6208 In other words this is a hack - Anthony. 6209 */ 6210 if (fabs((double) pixel) > (QuantumRange/2)) 6211 pixel-=QuantumRange; 6212 pixel*=2; 6213 } 6214 distance+=pixel*pixel*scale; 6215 if (distance > fuzz) 6216 return(MagickFalse); 6217 pixel=p->green-q->green; 6218 distance+=pixel*pixel*scale; 6219 if (distance > fuzz) 6220 return(MagickFalse); 6221 pixel=p->blue-q->blue; 6222 distance+=pixel*pixel*scale; 6223 if (distance > fuzz) 6224 return(MagickFalse); 6225 return(MagickTrue); 6226} 6227 6228/* 6229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6230% % 6231% % 6232% % 6233% S e t P i x e l C h a n n e l M a s k % 6234% % 6235% % 6236% % 6237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6238% 6239% SetPixelChannelMask() sets the pixel channel map from the specified channel 6240% mask. 6241% 6242% The format of the SetPixelChannelMask method is: 6243% 6244% ChannelType SetPixelChannelMask(Image *image, 6245% const ChannelType channel_mask) 6246% 6247% A description of each parameter follows: 6248% 6249% o image: the image. 6250% 6251% o channel_mask: the channel mask. 6252% 6253*/ 6254MagickExport ChannelType SetPixelChannelMask(Image *image, 6255 const ChannelType channel_mask) 6256{ 6257#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01) 6258 6259 ChannelType 6260 mask; 6261 6262 register ssize_t 6263 i; 6264 6265 assert(image != (Image *) NULL); 6266 assert(image->signature == MagickCoreSignature); 6267 if (image->debug != MagickFalse) 6268 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", 6269 image->filename,channel_mask); 6270 mask=image->channel_mask; 6271 image->channel_mask=channel_mask; 6272 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 6273 { 6274 PixelChannel channel=GetPixelChannelChannel(image,i); 6275 if (GetChannelBit(channel_mask,channel) == 0) 6276 { 6277 SetPixelChannelTraits(image,channel,CopyPixelTrait); 6278 continue; 6279 } 6280 if (channel == AlphaPixelChannel) 6281 { 6282 if ((image->alpha_trait & CopyPixelTrait) != 0) 6283 { 6284 SetPixelChannelTraits(image,channel,CopyPixelTrait); 6285 continue; 6286 } 6287 SetPixelChannelTraits(image,channel,UpdatePixelTrait); 6288 continue; 6289 } 6290 if (image->alpha_trait != UndefinedPixelTrait) 6291 { 6292 SetPixelChannelTraits(image,channel,(const PixelTrait) 6293 (UpdatePixelTrait | BlendPixelTrait)); 6294 continue; 6295 } 6296 SetPixelChannelTraits(image,channel,UpdatePixelTrait); 6297 } 6298 if (image->storage_class == PseudoClass) 6299 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait); 6300 if (image->read_mask != MagickFalse) 6301 SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait); 6302 if (image->write_mask != MagickFalse) 6303 SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait); 6304 if (image->debug != MagickFalse) 6305 LogPixelChannels(image); 6306 return(mask); 6307} 6308 6309/* 6310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6311% % 6312% % 6313% % 6314% S e t P i x e l M e t a C h a n n e l s % 6315% % 6316% % 6317% % 6318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6319% 6320% SetPixelMetaChannels() sets the image meta channels. 6321% 6322% The format of the SetPixelMetaChannels method is: 6323% 6324% MagickBooleanType SetPixelMetaChannels(Image *image, 6325% const size_t number_meta_channels,ExceptionInfo *exception) 6326% 6327% A description of each parameter follows: 6328% 6329% o image: the image. 6330% 6331% o number_meta_channels: the number of meta channels. 6332% 6333% o exception: return any errors or warnings in this structure. 6334% 6335*/ 6336MagickExport MagickBooleanType SetPixelMetaChannels(Image *image, 6337 const size_t number_meta_channels,ExceptionInfo *exception) 6338{ 6339 image->number_meta_channels=number_meta_channels; 6340 return(SyncImagePixelCache(image,exception)); 6341} 6342