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