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