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