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