1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% AAA TTTTT TTTTT RRRR IIIII BBBB U U TTTTT EEEEE % 7% A A T T R R I B B U U T E % 8% AAAAA T T RRRR I BBBB U U T EEE % 9% A A T T R R I B B U U T E % 10% A A T T R R IIIII BBBB UUU T EEEEE % 11% % 12% % 13% MagickCore Get / Set Image Attributes % 14% % 15% Software Design % 16% Cristy % 17% October 2002 % 18% % 19% % 20% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37% 38*/ 39 40/* 41 Include declarations. 42*/ 43#include "MagickCore/studio.h" 44#include "MagickCore/artifact.h" 45#include "MagickCore/attribute.h" 46#include "MagickCore/blob.h" 47#include "MagickCore/blob-private.h" 48#include "MagickCore/cache.h" 49#include "MagickCore/cache-private.h" 50#include "MagickCore/cache-view.h" 51#include "MagickCore/channel.h" 52#include "MagickCore/client.h" 53#include "MagickCore/color.h" 54#include "MagickCore/color-private.h" 55#include "MagickCore/colormap.h" 56#include "MagickCore/colormap-private.h" 57#include "MagickCore/colorspace.h" 58#include "MagickCore/colorspace-private.h" 59#include "MagickCore/composite.h" 60#include "MagickCore/composite-private.h" 61#include "MagickCore/constitute.h" 62#include "MagickCore/draw.h" 63#include "MagickCore/draw-private.h" 64#include "MagickCore/effect.h" 65#include "MagickCore/enhance.h" 66#include "MagickCore/exception.h" 67#include "MagickCore/exception-private.h" 68#include "MagickCore/geometry.h" 69#include "MagickCore/histogram.h" 70#include "MagickCore/identify.h" 71#include "MagickCore/image.h" 72#include "MagickCore/image-private.h" 73#include "MagickCore/list.h" 74#include "MagickCore/log.h" 75#include "MagickCore/memory_.h" 76#include "MagickCore/magick.h" 77#include "MagickCore/monitor.h" 78#include "MagickCore/monitor-private.h" 79#include "MagickCore/option.h" 80#include "MagickCore/paint.h" 81#include "MagickCore/pixel.h" 82#include "MagickCore/pixel-accessor.h" 83#include "MagickCore/property.h" 84#include "MagickCore/quantize.h" 85#include "MagickCore/quantum-private.h" 86#include "MagickCore/random_.h" 87#include "MagickCore/resource_.h" 88#include "MagickCore/semaphore.h" 89#include "MagickCore/segment.h" 90#include "MagickCore/splay-tree.h" 91#include "MagickCore/string_.h" 92#include "MagickCore/thread-private.h" 93#include "MagickCore/threshold.h" 94#include "MagickCore/transform.h" 95#include "MagickCore/utility.h" 96 97/* 98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 99% % 100% % 101% % 102+ G e t I m a g e B o u n d i n g B o x % 103% % 104% % 105% % 106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 107% 108% GetImageBoundingBox() returns the bounding box of an image canvas. 109% 110% The format of the GetImageBoundingBox method is: 111% 112% RectangleInfo GetImageBoundingBox(const Image *image, 113% ExceptionInfo *exception) 114% 115% A description of each parameter follows: 116% 117% o bounds: Method GetImageBoundingBox returns the bounding box of an 118% image canvas. 119% 120% o image: the image. 121% 122% o exception: return any errors or warnings in this structure. 123% 124*/ 125MagickExport RectangleInfo GetImageBoundingBox(const Image *image, 126 ExceptionInfo *exception) 127{ 128 CacheView 129 *image_view; 130 131 MagickBooleanType 132 status; 133 134 PixelInfo 135 target[3], 136 zero; 137 138 RectangleInfo 139 bounds; 140 141 register const Quantum 142 *r; 143 144 ssize_t 145 y; 146 147 assert(image != (Image *) NULL); 148 assert(image->signature == MagickCoreSignature); 149 if (image->debug != MagickFalse) 150 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 151 bounds.width=0; 152 bounds.height=0; 153 bounds.x=(ssize_t) image->columns; 154 bounds.y=(ssize_t) image->rows; 155 GetPixelInfo(image,&target[0]); 156 image_view=AcquireVirtualCacheView(image,exception); 157 r=GetCacheViewVirtualPixels(image_view,0,0,1,1,exception); 158 if (r == (const Quantum *) NULL) 159 { 160 image_view=DestroyCacheView(image_view); 161 return(bounds); 162 } 163 GetPixelInfoPixel(image,r,&target[0]); 164 GetPixelInfo(image,&target[1]); 165 r=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1, 166 exception); 167 if (r != (const Quantum *) NULL) 168 GetPixelInfoPixel(image,r,&target[1]); 169 GetPixelInfo(image,&target[2]); 170 r=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1, 171 exception); 172 if (r != (const Quantum *) NULL) 173 GetPixelInfoPixel(image,r,&target[2]); 174 status=MagickTrue; 175 GetPixelInfo(image,&zero); 176#if defined(MAGICKCORE_OPENMP_SUPPORT) 177 #pragma omp parallel for schedule(static,4) shared(status) \ 178 magick_threads(image,image,image->rows,1) 179#endif 180 for (y=0; y < (ssize_t) image->rows; y++) 181 { 182 PixelInfo 183 pixel; 184 185 RectangleInfo 186 bounding_box; 187 188 register const Quantum 189 *magick_restrict p; 190 191 register ssize_t 192 x; 193 194 if (status == MagickFalse) 195 continue; 196#if defined(MAGICKCORE_OPENMP_SUPPORT) 197# pragma omp critical (MagickCore_GetImageBoundingBox) 198#endif 199 bounding_box=bounds; 200 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 201 if (p == (const Quantum *) NULL) 202 { 203 status=MagickFalse; 204 continue; 205 } 206 pixel=zero; 207 for (x=0; x < (ssize_t) image->columns; x++) 208 { 209 GetPixelInfoPixel(image,p,&pixel); 210 if ((x < bounding_box.x) && 211 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse)) 212 bounding_box.x=x; 213 if ((x > (ssize_t) bounding_box.width) && 214 (IsFuzzyEquivalencePixelInfo(&pixel,&target[1]) == MagickFalse)) 215 bounding_box.width=(size_t) x; 216 if ((y < bounding_box.y) && 217 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse)) 218 bounding_box.y=y; 219 if ((y > (ssize_t) bounding_box.height) && 220 (IsFuzzyEquivalencePixelInfo(&pixel,&target[2]) == MagickFalse)) 221 bounding_box.height=(size_t) y; 222 p+=GetPixelChannels(image); 223 } 224#if defined(MAGICKCORE_OPENMP_SUPPORT) 225# pragma omp critical (MagickCore_GetImageBoundingBox) 226#endif 227 { 228 if (bounding_box.x < bounds.x) 229 bounds.x=bounding_box.x; 230 if (bounding_box.y < bounds.y) 231 bounds.y=bounding_box.y; 232 if (bounding_box.width > bounds.width) 233 bounds.width=bounding_box.width; 234 if (bounding_box.height > bounds.height) 235 bounds.height=bounding_box.height; 236 } 237 } 238 image_view=DestroyCacheView(image_view); 239 if ((bounds.width == 0) && (bounds.height == 0)) 240 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning, 241 "GeometryDoesNotContainImage","`%s'",image->filename); 242 else 243 { 244 bounds.width-=(bounds.x-1); 245 bounds.height-=(bounds.y-1); 246 } 247 return(bounds); 248} 249 250/* 251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 252% % 253% % 254% % 255% G e t I m a g e D e p t h % 256% % 257% % 258% % 259%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 260% 261% GetImageDepth() returns the depth of a particular image channel. 262% 263% The format of the GetImageDepth method is: 264% 265% size_t GetImageDepth(const Image *image,ExceptionInfo *exception) 266% 267% A description of each parameter follows: 268% 269% o image: the image. 270% 271% o exception: return any errors or warnings in this structure. 272% 273*/ 274MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception) 275{ 276 CacheView 277 *image_view; 278 279 MagickBooleanType 280 status; 281 282 register ssize_t 283 i; 284 285 size_t 286 *current_depth, 287 depth, 288 number_threads; 289 290 ssize_t 291 y; 292 293 /* 294 Compute image depth. 295 */ 296 assert(image != (Image *) NULL); 297 assert(image->signature == MagickCoreSignature); 298 if (image->debug != MagickFalse) 299 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 300 number_threads=(size_t) GetMagickResourceLimit(ThreadResource); 301 current_depth=(size_t *) AcquireQuantumMemory(number_threads, 302 sizeof(*current_depth)); 303 if (current_depth == (size_t *) NULL) 304 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 305 status=MagickTrue; 306 for (i=0; i < (ssize_t) number_threads; i++) 307 current_depth[i]=1; 308 if ((image->storage_class == PseudoClass) && 309 (image->alpha_trait == UndefinedPixelTrait)) 310 { 311#if defined(MAGICKCORE_OPENMP_SUPPORT) 312 #pragma omp parallel for schedule(static,4) shared(status) \ 313 if ((image->colors) > 256) \ 314 num_threads(GetMagickResourceLimit(ThreadResource)) 315#endif 316 for (i=0; i < (ssize_t) image->colors; i++) 317 { 318 const int 319 id = GetOpenMPThreadId(); 320 321 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH) 322 { 323 MagickBooleanType 324 atDepth; 325 326 QuantumAny 327 range; 328 329 atDepth=MagickTrue; 330 range=GetQuantumRange(current_depth[id]); 331 if ((atDepth != MagickFalse) && 332 (GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 333 if (IsPixelAtDepth(image->colormap[i].red,range) == MagickFalse) 334 atDepth=MagickFalse; 335 if ((atDepth != MagickFalse) && 336 (GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 337 if (IsPixelAtDepth(image->colormap[i].green,range) == MagickFalse) 338 atDepth=MagickFalse; 339 if ((atDepth != MagickFalse) && 340 (GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 341 if (IsPixelAtDepth(image->colormap[i].blue,range) == MagickFalse) 342 atDepth=MagickFalse; 343 if ((atDepth != MagickFalse)) 344 break; 345 current_depth[id]++; 346 } 347 } 348 depth=current_depth[0]; 349 for (i=1; i < (ssize_t) number_threads; i++) 350 if (depth < current_depth[i]) 351 depth=current_depth[i]; 352 current_depth=(size_t *) RelinquishMagickMemory(current_depth); 353 return(depth); 354 } 355 image_view=AcquireVirtualCacheView(image,exception); 356#if !defined(MAGICKCORE_HDRI_SUPPORT) 357 if (QuantumRange <= MaxMap) 358 { 359 size_t 360 *depth_map; 361 362 /* 363 Scale pixels to desired (optimized with depth map). 364 */ 365 depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map)); 366 if (depth_map == (size_t *) NULL) 367 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 368 for (i=0; i <= (ssize_t) MaxMap; i++) 369 { 370 unsigned int 371 depth; 372 373 for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++) 374 { 375 Quantum 376 pixel; 377 378 QuantumAny 379 range; 380 381 range=GetQuantumRange(depth); 382 pixel=(Quantum) i; 383 if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range)) 384 break; 385 } 386 depth_map[i]=depth; 387 } 388#if defined(MAGICKCORE_OPENMP_SUPPORT) 389 #pragma omp parallel for schedule(static,4) shared(status) \ 390 magick_threads(image,image,image->rows,1) 391#endif 392 for (y=0; y < (ssize_t) image->rows; y++) 393 { 394 const int 395 id = GetOpenMPThreadId(); 396 397 register const Quantum 398 *magick_restrict p; 399 400 register ssize_t 401 x; 402 403 if (status == MagickFalse) 404 continue; 405 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 406 if (p == (const Quantum *) NULL) 407 continue; 408 for (x=0; x < (ssize_t) image->columns; x++) 409 { 410 if (GetPixelReadMask(image,p) == 0) 411 { 412 p+=GetPixelChannels(image); 413 continue; 414 } 415 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 416 { 417 PixelChannel channel=GetPixelChannelChannel(image,i); 418 PixelTrait traits=GetPixelChannelTraits(image,channel); 419 if ((traits == UndefinedPixelTrait) || 420 (channel == IndexPixelChannel) || 421 (channel == ReadMaskPixelChannel) || 422 (channel == MetaPixelChannel)) 423 continue; 424 if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id]) 425 current_depth[id]=depth_map[ScaleQuantumToMap(p[i])]; 426 } 427 p+=GetPixelChannels(image); 428 } 429 if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH) 430 status=MagickFalse; 431 } 432 image_view=DestroyCacheView(image_view); 433 depth=current_depth[0]; 434 for (i=1; i < (ssize_t) number_threads; i++) 435 if (depth < current_depth[i]) 436 depth=current_depth[i]; 437 depth_map=(size_t *) RelinquishMagickMemory(depth_map); 438 current_depth=(size_t *) RelinquishMagickMemory(current_depth); 439 return(depth); 440 } 441#endif 442 /* 443 Compute pixel depth. 444 */ 445#if defined(MAGICKCORE_OPENMP_SUPPORT) 446 #pragma omp parallel for schedule(static,4) shared(status) \ 447 magick_threads(image,image,image->rows,1) 448#endif 449 for (y=0; y < (ssize_t) image->rows; y++) 450 { 451 const int 452 id = GetOpenMPThreadId(); 453 454 register const Quantum 455 *magick_restrict p; 456 457 register ssize_t 458 x; 459 460 if (status == MagickFalse) 461 continue; 462 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 463 if (p == (const Quantum *) NULL) 464 continue; 465 for (x=0; x < (ssize_t) image->columns; x++) 466 { 467 if (GetPixelReadMask(image,p) == 0) 468 { 469 p+=GetPixelChannels(image); 470 continue; 471 } 472 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 473 { 474 PixelChannel 475 channel; 476 477 PixelTrait 478 traits; 479 480 channel=GetPixelChannelChannel(image,i); 481 traits=GetPixelChannelTraits(image,channel); 482 if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) || 483 (channel == ReadMaskPixelChannel)) 484 continue; 485 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH) 486 { 487 QuantumAny 488 range; 489 490 range=GetQuantumRange(current_depth[id]); 491 if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range)) 492 break; 493 current_depth[id]++; 494 } 495 } 496 p+=GetPixelChannels(image); 497 } 498 if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH) 499 status=MagickFalse; 500 } 501 image_view=DestroyCacheView(image_view); 502 depth=current_depth[0]; 503 for (i=1; i < (ssize_t) number_threads; i++) 504 if (depth < current_depth[i]) 505 depth=current_depth[i]; 506 current_depth=(size_t *) RelinquishMagickMemory(current_depth); 507 return(depth); 508} 509 510/* 511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 512% % 513% % 514% % 515% G e t I m a g e Q u a n t u m D e p t h % 516% % 517% % 518% % 519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 520% 521% GetImageQuantumDepth() returns the depth of the image rounded to a legal 522% quantum depth: 8, 16, or 32. 523% 524% The format of the GetImageQuantumDepth method is: 525% 526% size_t GetImageQuantumDepth(const Image *image, 527% const MagickBooleanType constrain) 528% 529% A description of each parameter follows: 530% 531% o image: the image. 532% 533% o constrain: A value other than MagickFalse, constrains the depth to 534% a maximum of MAGICKCORE_QUANTUM_DEPTH. 535% 536*/ 537MagickExport size_t GetImageQuantumDepth(const Image *image, 538 const MagickBooleanType constrain) 539{ 540 size_t 541 depth; 542 543 depth=image->depth; 544 if (depth <= 8) 545 depth=8; 546 else 547 if (depth <= 16) 548 depth=16; 549 else 550 if (depth <= 32) 551 depth=32; 552 else 553 if (depth <= 64) 554 depth=64; 555 if (constrain != MagickFalse) 556 depth=(size_t) MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH); 557 return(depth); 558} 559 560/* 561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 562% % 563% % 564% % 565% G e t I m a g e T y p e % 566% % 567% % 568% % 569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 570% 571% GetImageType() returns the type of image: 572% 573% Bilevel Grayscale GrayscaleMatte 574% Palette PaletteMatte TrueColor 575% TrueColorMatte ColorSeparation ColorSeparationMatte 576% 577% The format of the GetImageType method is: 578% 579% ImageType GetImageType(const Image *image) 580% 581% A description of each parameter follows: 582% 583% o image: the image. 584% 585*/ 586MagickExport ImageType GetImageType(const Image *image) 587{ 588 assert(image != (Image *) NULL); 589 assert(image->signature == MagickCoreSignature); 590 if (image->colorspace == CMYKColorspace) 591 { 592 if (image->alpha_trait == UndefinedPixelTrait) 593 return(ColorSeparationType); 594 return(ColorSeparationAlphaType); 595 } 596 if (IsImageMonochrome(image) != MagickFalse) 597 return(BilevelType); 598 if (IsImageGray(image) != MagickFalse) 599 { 600 if (image->alpha_trait != UndefinedPixelTrait) 601 return(GrayscaleAlphaType); 602 return(GrayscaleType); 603 } 604 if (IsPaletteImage(image) != MagickFalse) 605 { 606 if (image->alpha_trait != UndefinedPixelTrait) 607 return(PaletteAlphaType); 608 return(PaletteType); 609 } 610 if (image->alpha_trait != UndefinedPixelTrait) 611 return(TrueColorAlphaType); 612 return(TrueColorType); 613} 614 615/* 616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 617% % 618% % 619% % 620% I d e n t i f y I m a g e G r a y % 621% % 622% % 623% % 624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 625% 626% IdentifyImageGray() returns grayscale if all the pixels in the image have 627% the same red, green, and blue intensities, and bi-level is the intensity is 628% either 0 or QuantumRange. Otherwise undefined is returned. 629% 630% The format of the IdentifyImageGray method is: 631% 632% ImageType IdentifyImageGray(const Image *image,ExceptionInfo *exception) 633% 634% A description of each parameter follows: 635% 636% o image: the image. 637% 638% o exception: return any errors or warnings in this structure. 639% 640*/ 641MagickExport ImageType IdentifyImageGray(const Image *image, 642 ExceptionInfo *exception) 643{ 644 CacheView 645 *image_view; 646 647 ImageType 648 type; 649 650 register const Quantum 651 *p; 652 653 register ssize_t 654 x; 655 656 ssize_t 657 y; 658 659 assert(image != (Image *) NULL); 660 assert(image->signature == MagickCoreSignature); 661 if (image->debug != MagickFalse) 662 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 663 if ((image->type == BilevelType) || (image->type == GrayscaleType) || 664 (image->type == GrayscaleAlphaType)) 665 return(image->type); 666 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 667 return(UndefinedType); 668 type=BilevelType; 669 image_view=AcquireVirtualCacheView(image,exception); 670 for (y=0; y < (ssize_t) image->rows; y++) 671 { 672 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 673 if (p == (const Quantum *) NULL) 674 break; 675 for (x=0; x < (ssize_t) image->columns; x++) 676 { 677 if (IsPixelGray(image,p) == MagickFalse) 678 { 679 type=UndefinedType; 680 break; 681 } 682 if ((type == BilevelType) && 683 (IsPixelMonochrome(image,p) == MagickFalse)) 684 type=GrayscaleType; 685 p+=GetPixelChannels(image); 686 } 687 if (type == UndefinedType) 688 break; 689 } 690 image_view=DestroyCacheView(image_view); 691 if ((type == GrayscaleType) && (image->alpha_trait != UndefinedPixelTrait)) 692 type=GrayscaleAlphaType; 693 return(type); 694} 695 696/* 697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 698% % 699% % 700% % 701% I d e n t i f y I m a g e M o n o c h r o m e % 702% % 703% % 704% % 705%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 706% 707% IdentifyImageMonochrome() returns MagickTrue if all the pixels in the image 708% have the same red, green, and blue intensities and the intensity is either 709% 0 or QuantumRange. 710% 711% The format of the IdentifyImageMonochrome method is: 712% 713% MagickBooleanType IdentifyImageMonochrome(const Image *image, 714% ExceptionInfo *exception) 715% 716% A description of each parameter follows: 717% 718% o image: the image. 719% 720% o exception: return any errors or warnings in this structure. 721% 722*/ 723MagickExport MagickBooleanType IdentifyImageMonochrome(const Image *image, 724 ExceptionInfo *exception) 725{ 726 CacheView 727 *image_view; 728 729 ImageType 730 type; 731 732 register ssize_t 733 x; 734 735 register const Quantum 736 *p; 737 738 ssize_t 739 y; 740 741 assert(image != (Image *) NULL); 742 assert(image->signature == MagickCoreSignature); 743 if (image->debug != MagickFalse) 744 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 745 if (image->type == BilevelType) 746 return(MagickTrue); 747 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 748 return(MagickFalse); 749 type=BilevelType; 750 image_view=AcquireVirtualCacheView(image,exception); 751 for (y=0; y < (ssize_t) image->rows; y++) 752 { 753 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 754 if (p == (const Quantum *) NULL) 755 break; 756 for (x=0; x < (ssize_t) image->columns; x++) 757 { 758 if (IsPixelMonochrome(image,p) == MagickFalse) 759 { 760 type=UndefinedType; 761 break; 762 } 763 p+=GetPixelChannels(image); 764 } 765 if (type == UndefinedType) 766 break; 767 } 768 image_view=DestroyCacheView(image_view); 769 if (type == BilevelType) 770 return(MagickTrue); 771 return(MagickFalse); 772} 773 774/* 775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 776% % 777% % 778% % 779% I d e n t i f y I m a g e T y p e % 780% % 781% % 782% % 783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 784% 785% IdentifyImageType() returns the potential type of image: 786% 787% Bilevel Grayscale GrayscaleMatte 788% Palette PaletteMatte TrueColor 789% TrueColorMatte ColorSeparation ColorSeparationMatte 790% 791% To ensure the image type matches its potential, use SetImageType(): 792% 793% (void) SetImageType(image,IdentifyImageType(image,exception),exception); 794% 795% The format of the IdentifyImageType method is: 796% 797% ImageType IdentifyImageType(const Image *image,ExceptionInfo *exception) 798% 799% A description of each parameter follows: 800% 801% o image: the image. 802% 803% o exception: return any errors or warnings in this structure. 804% 805*/ 806MagickExport ImageType IdentifyImageType(const Image *image, 807 ExceptionInfo *exception) 808{ 809 assert(image != (Image *) NULL); 810 assert(image->signature == MagickCoreSignature); 811 if (image->debug != MagickFalse) 812 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 813 if (image->colorspace == CMYKColorspace) 814 { 815 if (image->alpha_trait == UndefinedPixelTrait) 816 return(ColorSeparationType); 817 return(ColorSeparationAlphaType); 818 } 819 if (IdentifyImageMonochrome(image,exception) != MagickFalse) 820 return(BilevelType); 821 if (IdentifyImageGray(image,exception) != UndefinedType) 822 { 823 if (image->alpha_trait != UndefinedPixelTrait) 824 return(GrayscaleAlphaType); 825 return(GrayscaleType); 826 } 827 if (IdentifyPaletteImage(image,exception) != MagickFalse) 828 { 829 if (image->alpha_trait != UndefinedPixelTrait) 830 return(PaletteAlphaType); 831 return(PaletteType); 832 } 833 if (image->alpha_trait != UndefinedPixelTrait) 834 return(TrueColorAlphaType); 835 return(TrueColorType); 836} 837 838/* 839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 840% % 841% % 842% % 843% I s I m a g e G r a y % 844% % 845% % 846% % 847%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 848% 849% IsImageGray() returns MagickTrue if the type of the image is grayscale or 850% bi-level. 851% 852% The format of the IsImageGray method is: 853% 854% MagickBooleanType IsImageGray(const Image *image) 855% 856% A description of each parameter follows: 857% 858% o image: the image. 859% 860*/ 861MagickExport MagickBooleanType IsImageGray(const Image *image) 862{ 863 assert(image != (Image *) NULL); 864 assert(image->signature == MagickCoreSignature); 865 if ((image->type == BilevelType) || (image->type == GrayscaleType) || 866 (image->type == GrayscaleAlphaType)) 867 return(MagickTrue); 868 return(MagickFalse); 869} 870 871/* 872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 873% % 874% % 875% % 876% I s I m a g e M o n o c h r o m e % 877% % 878% % 879% % 880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 881% 882% IsImageMonochrome() returns MagickTrue if type of the image is bi-level. 883% 884% The format of the IsImageMonochrome method is: 885% 886% MagickBooleanType IsImageMonochrome(const Image *image) 887% 888% A description of each parameter follows: 889% 890% o image: the image. 891% 892*/ 893MagickExport MagickBooleanType IsImageMonochrome(const Image *image) 894{ 895 assert(image != (Image *) NULL); 896 assert(image->signature == MagickCoreSignature); 897 if (image->type == BilevelType) 898 return(MagickTrue); 899 return(MagickFalse); 900} 901 902/* 903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 904% % 905% % 906% % 907% I s I m a g e O p a q u e % 908% % 909% % 910% % 911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 912% 913% IsImageOpaque() returns MagickTrue if none of the pixels in the image have 914% an alpha value other than OpaqueAlpha (QuantumRange). 915% 916% Will return true immediatally is alpha channel is not available. 917% 918% The format of the IsImageOpaque method is: 919% 920% MagickBooleanType IsImageOpaque(const Image *image, 921% ExceptionInfo *exception) 922% 923% A description of each parameter follows: 924% 925% o image: the image. 926% 927% o exception: return any errors or warnings in this structure. 928% 929*/ 930MagickExport MagickBooleanType IsImageOpaque(const Image *image, 931 ExceptionInfo *exception) 932{ 933 CacheView 934 *image_view; 935 936 register const Quantum 937 *p; 938 939 register ssize_t 940 x; 941 942 ssize_t 943 y; 944 945 /* 946 Determine if image is opaque. 947 */ 948 assert(image != (Image *) NULL); 949 assert(image->signature == MagickCoreSignature); 950 if (image->debug != MagickFalse) 951 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 952 if (image->alpha_trait == UndefinedPixelTrait) 953 return(MagickTrue); 954 image_view=AcquireVirtualCacheView(image,exception); 955 for (y=0; y < (ssize_t) image->rows; y++) 956 { 957 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 958 if (p == (const Quantum *) NULL) 959 break; 960 for (x=0; x < (ssize_t) image->columns; x++) 961 { 962 if (GetPixelAlpha(image,p) != OpaqueAlpha) 963 break; 964 p+=GetPixelChannels(image); 965 } 966 if (x < (ssize_t) image->columns) 967 break; 968 } 969 image_view=DestroyCacheView(image_view); 970 return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue); 971} 972 973/* 974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 975% % 976% % 977% % 978% S e t I m a g e D e p t h % 979% % 980% % 981% % 982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 983% 984% SetImageDepth() sets the depth of the image. 985% 986% The format of the SetImageDepth method is: 987% 988% MagickBooleanType SetImageDepth(Image *image,const size_t depth, 989% ExceptionInfo *exception) 990% 991% A description of each parameter follows: 992% 993% o image: the image. 994% 995% o channel: the channel. 996% 997% o depth: the image depth. 998% 999% o exception: return any errors or warnings in this structure. 1000% 1001*/ 1002MagickExport MagickBooleanType SetImageDepth(Image *image, 1003 const size_t depth,ExceptionInfo *exception) 1004{ 1005 CacheView 1006 *image_view; 1007 1008 MagickBooleanType 1009 status; 1010 1011 QuantumAny 1012 range; 1013 1014 ssize_t 1015 y; 1016 1017 assert(image != (Image *) NULL); 1018 if (image->debug != MagickFalse) 1019 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1020 assert(image->signature == MagickCoreSignature); 1021 if (depth >= MAGICKCORE_QUANTUM_DEPTH) 1022 { 1023 image->depth=depth; 1024 return(MagickTrue); 1025 } 1026 range=GetQuantumRange(depth); 1027 if (image->storage_class == PseudoClass) 1028 { 1029 register ssize_t 1030 i; 1031 1032#if defined(MAGICKCORE_OPENMP_SUPPORT) 1033 #pragma omp parallel for schedule(static,4) shared(status) \ 1034 magick_threads(image,image,1,1) 1035#endif 1036 for (i=0; i < (ssize_t) image->colors; i++) 1037 { 1038 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 1039 image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny( 1040 ClampPixel(image->colormap[i].red),range),range); 1041 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 1042 image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny( 1043 ClampPixel(image->colormap[i].green),range),range); 1044 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 1045 image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny( 1046 ClampPixel(image->colormap[i].blue),range),range); 1047 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) 1048 image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny( 1049 ClampPixel(image->colormap[i].alpha),range),range); 1050 } 1051 } 1052 status=MagickTrue; 1053 image_view=AcquireAuthenticCacheView(image,exception); 1054#if !defined(MAGICKCORE_HDRI_SUPPORT) 1055 if (QuantumRange <= MaxMap) 1056 { 1057 Quantum 1058 *depth_map; 1059 1060 register ssize_t 1061 i; 1062 1063 /* 1064 Scale pixels to desired (optimized with depth map). 1065 */ 1066 depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map)); 1067 if (depth_map == (Quantum *) NULL) 1068 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1069 for (i=0; i <= (ssize_t) MaxMap; i++) 1070 depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range), 1071 range); 1072#if defined(MAGICKCORE_OPENMP_SUPPORT) 1073 #pragma omp parallel for schedule(static,4) shared(status) \ 1074 magick_threads(image,image,image->rows,1) 1075#endif 1076 for (y=0; y < (ssize_t) image->rows; y++) 1077 { 1078 register ssize_t 1079 x; 1080 1081 register Quantum 1082 *magick_restrict q; 1083 1084 if (status == MagickFalse) 1085 continue; 1086 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, 1087 exception); 1088 if (q == (Quantum *) NULL) 1089 { 1090 status=MagickFalse; 1091 continue; 1092 } 1093 for (x=0; x < (ssize_t) image->columns; x++) 1094 { 1095 register ssize_t 1096 i; 1097 1098 if (GetPixelReadMask(image,q) == 0) 1099 { 1100 q+=GetPixelChannels(image); 1101 continue; 1102 } 1103 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1104 { 1105 PixelChannel 1106 channel; 1107 1108 PixelTrait 1109 traits; 1110 1111 channel=GetPixelChannelChannel(image,i); 1112 traits=GetPixelChannelTraits(image,channel); 1113 if ((traits == UndefinedPixelTrait) || 1114 (channel == IndexPixelChannel) || 1115 (channel == ReadMaskPixelChannel)) 1116 continue; 1117 q[i]=depth_map[ScaleQuantumToMap(q[i])]; 1118 } 1119 q+=GetPixelChannels(image); 1120 } 1121 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 1122 { 1123 status=MagickFalse; 1124 continue; 1125 } 1126 } 1127 image_view=DestroyCacheView(image_view); 1128 depth_map=(Quantum *) RelinquishMagickMemory(depth_map); 1129 if (status != MagickFalse) 1130 image->depth=depth; 1131 return(status); 1132 } 1133#endif 1134 /* 1135 Scale pixels to desired depth. 1136 */ 1137#if defined(MAGICKCORE_OPENMP_SUPPORT) 1138 #pragma omp parallel for schedule(static,4) shared(status) \ 1139 magick_threads(image,image,image->rows,1) 1140#endif 1141 for (y=0; y < (ssize_t) image->rows; y++) 1142 { 1143 register ssize_t 1144 x; 1145 1146 register Quantum 1147 *magick_restrict q; 1148 1149 if (status == MagickFalse) 1150 continue; 1151 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 1152 if (q == (Quantum *) NULL) 1153 { 1154 status=MagickFalse; 1155 continue; 1156 } 1157 for (x=0; x < (ssize_t) image->columns; x++) 1158 { 1159 register ssize_t 1160 i; 1161 1162 if (GetPixelReadMask(image,q) == 0) 1163 { 1164 q+=GetPixelChannels(image); 1165 continue; 1166 } 1167 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1168 { 1169 PixelChannel 1170 channel; 1171 1172 PixelTrait 1173 traits; 1174 1175 channel=GetPixelChannelChannel(image,i); 1176 traits=GetPixelChannelTraits(image,channel); 1177 if ((traits == UndefinedPixelTrait) || (channel == IndexPixelChannel) || 1178 (channel == ReadMaskPixelChannel)) 1179 continue; 1180 q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(ClampPixel(q[i]),range),range); 1181 } 1182 q+=GetPixelChannels(image); 1183 } 1184 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 1185 { 1186 status=MagickFalse; 1187 continue; 1188 } 1189 } 1190 image_view=DestroyCacheView(image_view); 1191 if (status != MagickFalse) 1192 image->depth=depth; 1193 return(status); 1194} 1195 1196/* 1197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1198% % 1199% % 1200% % 1201% S e t I m a g e T y p e % 1202% % 1203% % 1204% % 1205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1206% 1207% SetImageType() sets the type of image. Choose from these types: 1208% 1209% Bilevel Grayscale GrayscaleMatte 1210% Palette PaletteMatte TrueColor 1211% TrueColorMatte ColorSeparation ColorSeparationMatte 1212% OptimizeType 1213% 1214% The format of the SetImageType method is: 1215% 1216% MagickBooleanType SetImageType(Image *image,const ImageType type, 1217% ExceptionInfo *exception) 1218% 1219% A description of each parameter follows: 1220% 1221% o image: the image. 1222% 1223% o type: Image type. 1224% 1225% o exception: return any errors or warnings in this structure. 1226% 1227*/ 1228MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type, 1229 ExceptionInfo *exception) 1230{ 1231 const char 1232 *artifact; 1233 1234 ImageInfo 1235 *image_info; 1236 1237 MagickBooleanType 1238 status; 1239 1240 QuantizeInfo 1241 *quantize_info; 1242 1243 assert(image != (Image *) NULL); 1244 if (image->debug != MagickFalse) 1245 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1246 assert(image->signature == MagickCoreSignature); 1247 status=MagickTrue; 1248 image_info=AcquireImageInfo(); 1249 image_info->dither=image->dither; 1250 artifact=GetImageArtifact(image,"dither"); 1251 if (artifact != (const char *) NULL) 1252 (void) SetImageOption(image_info,"dither",artifact); 1253 switch (type) 1254 { 1255 case BilevelType: 1256 { 1257 if (SetImageMonochrome(image,exception) == MagickFalse) 1258 { 1259 status=TransformImageColorspace(image,GRAYColorspace,exception); 1260 (void) NormalizeImage(image,exception); 1261 quantize_info=AcquireQuantizeInfo(image_info); 1262 quantize_info->number_colors=2; 1263 quantize_info->colorspace=GRAYColorspace; 1264 status=QuantizeImage(quantize_info,image,exception); 1265 quantize_info=DestroyQuantizeInfo(quantize_info); 1266 } 1267 image->colors=2; 1268 image->alpha_trait=UndefinedPixelTrait; 1269 break; 1270 } 1271 case GrayscaleType: 1272 { 1273 if (SetImageGray(image,exception) == MagickFalse) 1274 status=TransformImageColorspace(image,GRAYColorspace,exception); 1275 image->alpha_trait=UndefinedPixelTrait; 1276 break; 1277 } 1278 case GrayscaleAlphaType: 1279 { 1280 if (SetImageGray(image,exception) == MagickFalse) 1281 status=TransformImageColorspace(image,GRAYColorspace,exception); 1282 if (image->alpha_trait == UndefinedPixelTrait) 1283 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 1284 break; 1285 } 1286 case PaletteType: 1287 { 1288 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1289 status=TransformImageColorspace(image,sRGBColorspace,exception); 1290 if ((image->storage_class == DirectClass) || (image->colors > 256)) 1291 { 1292 quantize_info=AcquireQuantizeInfo(image_info); 1293 quantize_info->number_colors=256; 1294 status=QuantizeImage(quantize_info,image,exception); 1295 quantize_info=DestroyQuantizeInfo(quantize_info); 1296 } 1297 image->alpha_trait=UndefinedPixelTrait; 1298 break; 1299 } 1300 case PaletteBilevelAlphaType: 1301 { 1302 ChannelType 1303 channel_mask; 1304 1305 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1306 status=TransformImageColorspace(image,sRGBColorspace,exception); 1307 if (image->alpha_trait == UndefinedPixelTrait) 1308 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 1309 channel_mask=SetImageChannelMask(image,AlphaChannel); 1310 (void) BilevelImage(image,(double) QuantumRange/2.0,exception); 1311 (void) SetImageChannelMask(image,channel_mask); 1312 quantize_info=AcquireQuantizeInfo(image_info); 1313 status=QuantizeImage(quantize_info,image,exception); 1314 quantize_info=DestroyQuantizeInfo(quantize_info); 1315 break; 1316 } 1317 case PaletteAlphaType: 1318 { 1319 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1320 status=TransformImageColorspace(image,sRGBColorspace,exception); 1321 if (image->alpha_trait == UndefinedPixelTrait) 1322 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 1323 quantize_info=AcquireQuantizeInfo(image_info); 1324 quantize_info->colorspace=TransparentColorspace; 1325 status=QuantizeImage(quantize_info,image,exception); 1326 quantize_info=DestroyQuantizeInfo(quantize_info); 1327 break; 1328 } 1329 case TrueColorType: 1330 { 1331 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1332 status=TransformImageColorspace(image,sRGBColorspace,exception); 1333 if (image->storage_class != DirectClass) 1334 status=SetImageStorageClass(image,DirectClass,exception); 1335 image->alpha_trait=UndefinedPixelTrait; 1336 break; 1337 } 1338 case TrueColorAlphaType: 1339 { 1340 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1341 status=TransformImageColorspace(image,sRGBColorspace,exception); 1342 if (image->storage_class != DirectClass) 1343 status=SetImageStorageClass(image,DirectClass,exception); 1344 if (image->alpha_trait == UndefinedPixelTrait) 1345 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 1346 break; 1347 } 1348 case ColorSeparationType: 1349 { 1350 if (image->colorspace != CMYKColorspace) 1351 { 1352 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1353 status=TransformImageColorspace(image,sRGBColorspace,exception); 1354 status=TransformImageColorspace(image,CMYKColorspace,exception); 1355 } 1356 if (image->storage_class != DirectClass) 1357 status=SetImageStorageClass(image,DirectClass,exception); 1358 image->alpha_trait=UndefinedPixelTrait; 1359 break; 1360 } 1361 case ColorSeparationAlphaType: 1362 { 1363 if (image->colorspace != CMYKColorspace) 1364 { 1365 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) 1366 status=TransformImageColorspace(image,sRGBColorspace,exception); 1367 status=TransformImageColorspace(image,CMYKColorspace,exception); 1368 } 1369 if (image->storage_class != DirectClass) 1370 status=SetImageStorageClass(image,DirectClass,exception); 1371 if (image->alpha_trait == UndefinedPixelTrait) 1372 status=SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 1373 break; 1374 } 1375 case OptimizeType: 1376 case UndefinedType: 1377 break; 1378 } 1379 image_info=DestroyImageInfo(image_info); 1380 if (status == MagickFalse) 1381 return(status); 1382 image->type=type; 1383 return(MagickTrue); 1384} 1385