]> granicus.if.org Git - imagemagick/blob - MagickCore/attribute.c
cleanup identical conditions (#1339)
[imagemagick] / MagickCore / attribute.c
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-2018 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 %    https://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 \f
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 \f
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 */
125 MagickExport 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) shared(status) \
178     magick_number_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 \f
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 */
274 MagickExport 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       for (i=0; i < (ssize_t) image->colors; i++)
312       {
313         const int
314           id = GetOpenMPThreadId();
315
316         while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
317         {
318           MagickBooleanType
319             atDepth;
320
321           QuantumAny
322             range;
323
324           atDepth=MagickTrue;
325           range=GetQuantumRange(current_depth[id]);
326           if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
327             if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].red),range) == MagickFalse)
328               atDepth=MagickFalse;
329           if ((atDepth != MagickFalse) &&
330               (GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
331             if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].green),range) == MagickFalse)
332               atDepth=MagickFalse;
333           if ((atDepth != MagickFalse) &&
334               (GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
335             if (IsPixelAtDepth(ClampToQuantum(image->colormap[i].blue),range) == MagickFalse)
336               atDepth=MagickFalse;
337           if ((atDepth != MagickFalse))
338             break;
339           current_depth[id]++;
340         }
341       }
342       depth=current_depth[0];
343       for (i=1; i < (ssize_t) number_threads; i++)
344         if (depth < current_depth[i])
345           depth=current_depth[i];
346       current_depth=(size_t *) RelinquishMagickMemory(current_depth);
347       return(depth);
348     }
349   image_view=AcquireVirtualCacheView(image,exception);
350 #if !defined(MAGICKCORE_HDRI_SUPPORT)
351   if ((1UL*QuantumRange) <= MaxMap)
352     {
353       size_t
354         *depth_map;
355
356       /*
357         Scale pixels to desired (optimized with depth map).
358       */
359       depth_map=(size_t *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
360       if (depth_map == (size_t *) NULL)
361         ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
362       for (i=0; i <= (ssize_t) MaxMap; i++)
363       {
364         unsigned int
365           depth;
366
367         for (depth=1; depth < MAGICKCORE_QUANTUM_DEPTH; depth++)
368         {
369           Quantum
370             pixel;
371
372           QuantumAny
373             range;
374
375           range=GetQuantumRange(depth);
376           pixel=(Quantum) i;
377           if (pixel == ScaleAnyToQuantum(ScaleQuantumToAny(pixel,range),range))
378             break;
379         }
380         depth_map[i]=depth;
381       }
382 #if defined(MAGICKCORE_OPENMP_SUPPORT)
383       #pragma omp parallel for schedule(static) shared(status) \
384         magick_number_threads(image,image,image->rows,1)
385 #endif
386       for (y=0; y < (ssize_t) image->rows; y++)
387       {
388         const int
389           id = GetOpenMPThreadId();
390
391         register const Quantum
392           *magick_restrict p;
393
394         register ssize_t
395           x;
396
397         if (status == MagickFalse)
398           continue;
399         p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
400         if (p == (const Quantum *) NULL)
401           continue;
402         for (x=0; x < (ssize_t) image->columns; x++)
403         {
404           register ssize_t
405             i;
406
407           for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
408           {
409             PixelChannel channel = GetPixelChannelChannel(image,i);
410             PixelTrait traits = GetPixelChannelTraits(image,channel);
411             if ((traits & UpdatePixelTrait) == 0)
412               continue;
413             if (depth_map[ScaleQuantumToMap(p[i])] > current_depth[id])
414               current_depth[id]=depth_map[ScaleQuantumToMap(p[i])];
415           }
416           p+=GetPixelChannels(image);
417         }
418         if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
419           status=MagickFalse;
420       }
421       image_view=DestroyCacheView(image_view);
422       depth=current_depth[0];
423       for (i=1; i < (ssize_t) number_threads; i++)
424         if (depth < current_depth[i])
425           depth=current_depth[i];
426       depth_map=(size_t *) RelinquishMagickMemory(depth_map);
427       current_depth=(size_t *) RelinquishMagickMemory(current_depth);
428       return(depth);
429     }
430 #endif
431   /*
432     Compute pixel depth.
433   */
434 #if defined(MAGICKCORE_OPENMP_SUPPORT)
435   #pragma omp parallel for schedule(static) shared(status) \
436     magick_number_threads(image,image,image->rows,1)
437 #endif
438   for (y=0; y < (ssize_t) image->rows; y++)
439   {
440     const int
441       id = GetOpenMPThreadId();
442
443     register const Quantum
444       *magick_restrict p;
445
446     register ssize_t
447       x;
448
449     if (status == MagickFalse)
450       continue;
451     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
452     if (p == (const Quantum *) NULL)
453       continue;
454     for (x=0; x < (ssize_t) image->columns; x++)
455     {
456       register ssize_t
457         i;
458
459       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
460       {
461         PixelChannel
462           channel;
463
464         PixelTrait
465           traits;
466
467         channel=GetPixelChannelChannel(image,i);
468         traits=GetPixelChannelTraits(image,channel);
469         if ((traits & UpdatePixelTrait) == 0)
470           continue;
471         while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
472         {
473           QuantumAny
474             range;
475
476           range=GetQuantumRange(current_depth[id]);
477           if (p[i] == ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range),range))
478             break;
479           current_depth[id]++;
480         }
481       }
482       p+=GetPixelChannels(image);
483     }
484     if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
485       status=MagickFalse;
486   }
487   image_view=DestroyCacheView(image_view);
488   depth=current_depth[0];
489   for (i=1; i < (ssize_t) number_threads; i++)
490     if (depth < current_depth[i])
491       depth=current_depth[i];
492   current_depth=(size_t *) RelinquishMagickMemory(current_depth);
493   return(depth);
494 }
495 \f
496 /*
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498 %                                                                             %
499 %                                                                             %
500 %                                                                             %
501 %   G e t I m a g e Q u a n t u m D e p t h                                   %
502 %                                                                             %
503 %                                                                             %
504 %                                                                             %
505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 %
507 %  GetImageQuantumDepth() returns the depth of the image rounded to a legal
508 %  quantum depth: 8, 16, or 32.
509 %
510 %  The format of the GetImageQuantumDepth method is:
511 %
512 %      size_t GetImageQuantumDepth(const Image *image,
513 %        const MagickBooleanType constrain)
514 %
515 %  A description of each parameter follows:
516 %
517 %    o image: the image.
518 %
519 %    o constrain: A value other than MagickFalse, constrains the depth to
520 %      a maximum of MAGICKCORE_QUANTUM_DEPTH.
521 %
522 */
523 MagickExport size_t GetImageQuantumDepth(const Image *image,
524   const MagickBooleanType constrain)
525 {
526   size_t
527     depth;
528
529   depth=image->depth;
530   if (depth <= 8)
531     depth=8;
532   else
533     if (depth <= 16)
534       depth=16;
535     else
536       if (depth <= 32)
537         depth=32;
538       else
539         if (depth <= 64)
540           depth=64;
541   if (constrain != MagickFalse)
542     depth=(size_t) MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH);
543   return(depth);
544 }
545 \f
546 /*
547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
548 %                                                                             %
549 %                                                                             %
550 %                                                                             %
551 %   G e t I m a g e T y p e                                                   %
552 %                                                                             %
553 %                                                                             %
554 %                                                                             %
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 %
557 %  GetImageType() returns the type of image:
558 %
559 %        Bilevel         Grayscale        GrayscaleMatte
560 %        Palette         PaletteMatte     TrueColor
561 %        TrueColorMatte  ColorSeparation  ColorSeparationMatte
562 %
563 %  The format of the GetImageType method is:
564 %
565 %      ImageType GetImageType(const Image *image)
566 %
567 %  A description of each parameter follows:
568 %
569 %    o image: the image.
570 %
571 */
572 MagickExport ImageType GetImageType(const Image *image)
573 {
574   assert(image != (Image *) NULL);
575   assert(image->signature == MagickCoreSignature);
576   if (image->colorspace == CMYKColorspace)
577     {
578       if (image->alpha_trait == UndefinedPixelTrait)
579         return(ColorSeparationType);
580       return(ColorSeparationAlphaType);
581     }
582   if (IsImageMonochrome(image) != MagickFalse)
583     return(BilevelType);
584   if (IsImageGray(image) != MagickFalse)
585     {
586       if (image->alpha_trait != UndefinedPixelTrait)
587         return(GrayscaleAlphaType);
588       return(GrayscaleType);
589     }
590   if (IsPaletteImage(image) != MagickFalse)
591     {
592       if (image->alpha_trait != UndefinedPixelTrait)
593         return(PaletteAlphaType);
594       return(PaletteType);
595     }
596   if (image->alpha_trait != UndefinedPixelTrait)
597     return(TrueColorAlphaType);
598   return(TrueColorType);
599 }
600 \f
601 /*
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 %                                                                             %
604 %                                                                             %
605 %                                                                             %
606 %     I d e n t i f y I m a g e G r a y                                       %
607 %                                                                             %
608 %                                                                             %
609 %                                                                             %
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 %
612 %  IdentifyImageGray() returns grayscale if all the pixels in the image have
613 %  the same red, green, and blue intensities, and bi-level is the intensity is
614 %  either 0 or QuantumRange. Otherwise undefined is returned.
615 %
616 %  The format of the IdentifyImageGray method is:
617 %
618 %      ImageType IdentifyImageGray(const Image *image,ExceptionInfo *exception)
619 %
620 %  A description of each parameter follows:
621 %
622 %    o image: the image.
623 %
624 %    o exception: return any errors or warnings in this structure.
625 %
626 */
627 MagickExport ImageType IdentifyImageGray(const Image *image,
628   ExceptionInfo *exception)
629 {
630   CacheView
631     *image_view;
632
633   ImageType
634     type;
635
636   register const Quantum
637     *p;
638
639   register ssize_t
640     x;
641
642   ssize_t
643     y;
644
645   assert(image != (Image *) NULL);
646   assert(image->signature == MagickCoreSignature);
647   if (image->debug != MagickFalse)
648     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
649   if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
650       (image->type == GrayscaleAlphaType))
651     return(image->type);
652   if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
653     return(UndefinedType);
654   type=BilevelType;
655   image_view=AcquireVirtualCacheView(image,exception);
656   for (y=0; y < (ssize_t) image->rows; y++)
657   {
658     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
659     if (p == (const Quantum *) NULL)
660       break;
661     for (x=0; x < (ssize_t) image->columns; x++)
662     {
663       if (IsPixelGray(image,p) == MagickFalse)
664         {
665           type=UndefinedType;
666           break;
667         }
668       if ((type == BilevelType) &&
669           (IsPixelMonochrome(image,p) == MagickFalse))
670         type=GrayscaleType;
671       p+=GetPixelChannels(image);
672     }
673     if (type == UndefinedType)
674       break;
675   }
676   image_view=DestroyCacheView(image_view);
677   if ((type == GrayscaleType) && (image->alpha_trait != UndefinedPixelTrait))
678     type=GrayscaleAlphaType;
679   return(type);
680 }
681 \f
682 /*
683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684 %                                                                             %
685 %                                                                             %
686 %                                                                             %
687 %   I d e n t i f y I m a g e M o n o c h r o m e                             %
688 %                                                                             %
689 %                                                                             %
690 %                                                                             %
691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 %
693 %  IdentifyImageMonochrome() returns MagickTrue if all the pixels in the image
694 %  have the same red, green, and blue intensities and the intensity is either
695 %  0 or QuantumRange.
696 %
697 %  The format of the IdentifyImageMonochrome method is:
698 %
699 %      MagickBooleanType IdentifyImageMonochrome(const Image *image,
700 %        ExceptionInfo *exception)
701 %
702 %  A description of each parameter follows:
703 %
704 %    o image: the image.
705 %
706 %    o exception: return any errors or warnings in this structure.
707 %
708 */
709 MagickExport MagickBooleanType IdentifyImageMonochrome(const Image *image,
710   ExceptionInfo *exception)
711 {
712   CacheView
713     *image_view;
714
715   MagickBooleanType
716     bilevel;
717
718   register ssize_t
719     x;
720
721   register const Quantum
722     *p;
723
724   ssize_t
725     y;
726
727   assert(image != (Image *) NULL);
728   assert(image->signature == MagickCoreSignature);
729   if (image->debug != MagickFalse)
730     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
731   if (image->type == BilevelType)
732     return(MagickTrue);
733   if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
734     return(MagickFalse);
735   bilevel=MagickTrue;
736   image_view=AcquireVirtualCacheView(image,exception);
737   for (y=0; y < (ssize_t) image->rows; y++)
738   {
739     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
740     if (p == (const Quantum *) NULL)
741       break;
742     for (x=0; x < (ssize_t) image->columns; x++)
743     {
744       if (IsPixelMonochrome(image,p) == MagickFalse)
745         {
746           bilevel=MagickFalse;
747           break;
748         }
749       p+=GetPixelChannels(image);
750     }
751     if (bilevel == MagickFalse)
752       break;
753   }
754   image_view=DestroyCacheView(image_view);
755   return(bilevel);
756 }
757 \f
758 /*
759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 %                                                                             %
761 %                                                                             %
762 %                                                                             %
763 %   I d e n t i f y I m a g e T y p e                                         %
764 %                                                                             %
765 %                                                                             %
766 %                                                                             %
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 %
769 %  IdentifyImageType() returns the potential type of image:
770 %
771 %        Bilevel         Grayscale        GrayscaleMatte
772 %        Palette         PaletteMatte     TrueColor
773 %        TrueColorMatte  ColorSeparation  ColorSeparationMatte
774 %
775 %  To ensure the image type matches its potential, use SetImageType():
776 %
777 %    (void) SetImageType(image,IdentifyImageType(image,exception),exception);
778 %
779 %  The format of the IdentifyImageType method is:
780 %
781 %      ImageType IdentifyImageType(const Image *image,ExceptionInfo *exception)
782 %
783 %  A description of each parameter follows:
784 %
785 %    o image: the image.
786 %
787 %    o exception: return any errors or warnings in this structure.
788 %
789 */
790 MagickExport ImageType IdentifyImageType(const Image *image,
791   ExceptionInfo *exception)
792 {
793   assert(image != (Image *) NULL);
794   assert(image->signature == MagickCoreSignature);
795   if (image->debug != MagickFalse)
796     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
797   if (image->colorspace == CMYKColorspace)
798     {
799       if (image->alpha_trait == UndefinedPixelTrait)
800         return(ColorSeparationType);
801       return(ColorSeparationAlphaType);
802     }
803   if (IdentifyImageMonochrome(image,exception) != MagickFalse)
804     return(BilevelType);
805   if (IdentifyImageGray(image,exception) != UndefinedType)
806     {
807       if (image->alpha_trait != UndefinedPixelTrait)
808         return(GrayscaleAlphaType);
809       return(GrayscaleType);
810     }
811   if (IdentifyPaletteImage(image,exception) != MagickFalse)
812     {
813       if (image->alpha_trait != UndefinedPixelTrait)
814         return(PaletteAlphaType);
815       return(PaletteType);
816     }
817   if (image->alpha_trait != UndefinedPixelTrait)
818     return(TrueColorAlphaType);
819   return(TrueColorType);
820 }
821 \f
822 /*
823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 %                                                                             %
825 %                                                                             %
826 %                                                                             %
827 %     I s I m a g e G r a y                                                   %
828 %                                                                             %
829 %                                                                             %
830 %                                                                             %
831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832 %
833 %  IsImageGray() returns MagickTrue if the type of the image is grayscale or
834 %  bi-level.
835 %
836 %  The format of the IsImageGray method is:
837 %
838 %      MagickBooleanType IsImageGray(const Image *image)
839 %
840 %  A description of each parameter follows:
841 %
842 %    o image: the image.
843 %
844 */
845 MagickExport MagickBooleanType IsImageGray(const Image *image)
846 {
847   assert(image != (Image *) NULL);
848   assert(image->signature == MagickCoreSignature);
849   if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
850       (image->type == GrayscaleAlphaType))
851     return(MagickTrue);
852   return(MagickFalse);
853 }
854 \f
855 /*
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857 %                                                                             %
858 %                                                                             %
859 %                                                                             %
860 %   I s I m a g e M o n o c h r o m e                                         %
861 %                                                                             %
862 %                                                                             %
863 %                                                                             %
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 %
866 %  IsImageMonochrome() returns MagickTrue if type of the image is bi-level.
867 %
868 %  The format of the IsImageMonochrome method is:
869 %
870 %      MagickBooleanType IsImageMonochrome(const Image *image)
871 %
872 %  A description of each parameter follows:
873 %
874 %    o image: the image.
875 %
876 */
877 MagickExport MagickBooleanType IsImageMonochrome(const Image *image)
878 {
879   assert(image != (Image *) NULL);
880   assert(image->signature == MagickCoreSignature);
881   if (image->type == BilevelType)
882     return(MagickTrue);
883   return(MagickFalse);
884 }
885 \f
886 /*
887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888 %                                                                             %
889 %                                                                             %
890 %                                                                             %
891 %     I s I m a g e O p a q u e                                               %
892 %                                                                             %
893 %                                                                             %
894 %                                                                             %
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896 %
897 %  IsImageOpaque() returns MagickTrue if none of the pixels in the image have
898 %  an alpha value other than OpaqueAlpha (QuantumRange).
899 %
900 %  Will return true immediatally is alpha channel is not available.
901 %
902 %  The format of the IsImageOpaque method is:
903 %
904 %      MagickBooleanType IsImageOpaque(const Image *image,
905 %        ExceptionInfo *exception)
906 %
907 %  A description of each parameter follows:
908 %
909 %    o image: the image.
910 %
911 %    o exception: return any errors or warnings in this structure.
912 %
913 */
914 MagickExport MagickBooleanType IsImageOpaque(const Image *image,
915   ExceptionInfo *exception)
916 {
917   CacheView
918     *image_view;
919
920   register const Quantum
921     *p;
922
923   register ssize_t
924     x;
925
926   ssize_t
927     y;
928
929   /*
930     Determine if image is opaque.
931   */
932   assert(image != (Image *) NULL);
933   assert(image->signature == MagickCoreSignature);
934   if (image->debug != MagickFalse)
935     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
936   if (image->alpha_trait == UndefinedPixelTrait)
937     return(MagickTrue);
938   image_view=AcquireVirtualCacheView(image,exception);
939   for (y=0; y < (ssize_t) image->rows; y++)
940   {
941     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
942     if (p == (const Quantum *) NULL)
943       break;
944     for (x=0; x < (ssize_t) image->columns; x++)
945     {
946       if (GetPixelAlpha(image,p) != OpaqueAlpha)
947         break;
948       p+=GetPixelChannels(image);
949     }
950     if (x < (ssize_t) image->columns)
951       break;
952   }
953   image_view=DestroyCacheView(image_view);
954   return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
955 }
956 \f
957 /*
958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 %                                                                             %
960 %                                                                             %
961 %                                                                             %
962 %   S e t I m a g e D e p t h                                                 %
963 %                                                                             %
964 %                                                                             %
965 %                                                                             %
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 %
968 %  SetImageDepth() sets the depth of the image.
969 %
970 %  The format of the SetImageDepth method is:
971 %
972 %      MagickBooleanType SetImageDepth(Image *image,const size_t depth,
973 %        ExceptionInfo *exception)
974 %
975 %  A description of each parameter follows:
976 %
977 %    o image: the image.
978 %
979 %    o channel: the channel.
980 %
981 %    o depth: the image depth.
982 %
983 %    o exception: return any errors or warnings in this structure.
984 %
985 */
986 MagickExport MagickBooleanType SetImageDepth(Image *image,
987   const size_t depth,ExceptionInfo *exception)
988 {
989   CacheView
990     *image_view;
991
992   MagickBooleanType
993     status;
994
995   QuantumAny
996     range;
997
998   ssize_t
999     y;
1000
1001   assert(image != (Image *) NULL);
1002   if (image->debug != MagickFalse)
1003     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1004   assert(image->signature == MagickCoreSignature);
1005   if (depth >= MAGICKCORE_QUANTUM_DEPTH)
1006     {
1007       image->depth=depth;
1008       return(MagickTrue);
1009     }
1010   range=GetQuantumRange(depth);
1011   if (image->storage_class == PseudoClass)
1012     {
1013       register ssize_t
1014         i;
1015
1016 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1017       #pragma omp parallel for schedule(static) shared(status) \
1018         magick_number_threads(image,image,image->colors,1)
1019 #endif
1020       for (i=0; i < (ssize_t) image->colors; i++)
1021       {
1022         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
1023           image->colormap[i].red=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1024             ClampPixel(image->colormap[i].red),range),range);
1025         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
1026           image->colormap[i].green=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1027             ClampPixel(image->colormap[i].green),range),range);
1028         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
1029           image->colormap[i].blue=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1030             ClampPixel(image->colormap[i].blue),range),range);
1031         if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
1032           image->colormap[i].alpha=(double) ScaleAnyToQuantum(ScaleQuantumToAny(
1033             ClampPixel(image->colormap[i].alpha),range),range);
1034       }
1035     }
1036   status=MagickTrue;
1037   image_view=AcquireAuthenticCacheView(image,exception);
1038 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1039   if ((1UL*QuantumRange) <= MaxMap)
1040     {
1041       Quantum
1042         *depth_map;
1043
1044       register ssize_t
1045         i;
1046
1047       /*
1048         Scale pixels to desired (optimized with depth map).
1049       */
1050       depth_map=(Quantum *) AcquireQuantumMemory(MaxMap+1,sizeof(*depth_map));
1051       if (depth_map == (Quantum *) NULL)
1052         ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1053       for (i=0; i <= (ssize_t) MaxMap; i++)
1054         depth_map[i]=ScaleAnyToQuantum(ScaleQuantumToAny((Quantum) i,range),
1055           range);
1056 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1057       #pragma omp parallel for schedule(static) shared(status) \
1058         magick_number_threads(image,image,image->rows,1)
1059 #endif
1060       for (y=0; y < (ssize_t) image->rows; y++)
1061       {
1062         register ssize_t
1063           x;
1064
1065         register Quantum
1066           *magick_restrict q;
1067
1068         if (status == MagickFalse)
1069           continue;
1070         q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1071           exception);
1072         if (q == (Quantum *) NULL)
1073           {
1074             status=MagickFalse;
1075             continue;
1076           }
1077         for (x=0; x < (ssize_t) image->columns; x++)
1078         {
1079           register ssize_t
1080             i;
1081
1082           for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1083           {
1084             PixelChannel
1085               channel;
1086
1087             PixelTrait
1088               traits;
1089
1090             channel=GetPixelChannelChannel(image,i);
1091             traits=GetPixelChannelTraits(image,channel);
1092             if ((traits & UpdatePixelTrait) == 0)
1093               continue;
1094             q[i]=depth_map[ScaleQuantumToMap(q[i])];
1095           }
1096           q+=GetPixelChannels(image);
1097         }
1098         if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1099           {
1100             status=MagickFalse;
1101             continue;
1102           }
1103       }
1104       image_view=DestroyCacheView(image_view);
1105       depth_map=(Quantum *) RelinquishMagickMemory(depth_map);
1106       if (status != MagickFalse)
1107         image->depth=depth;
1108       return(status);
1109     }
1110 #endif
1111   /*
1112     Scale pixels to desired depth.
1113   */
1114 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1115   #pragma omp parallel for schedule(static) shared(status) \
1116     magick_number_threads(image,image,image->rows,1)
1117 #endif
1118   for (y=0; y < (ssize_t) image->rows; y++)
1119   {
1120     register ssize_t
1121       x;
1122
1123     register Quantum
1124       *magick_restrict q;
1125
1126     if (status == MagickFalse)
1127       continue;
1128     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1129     if (q == (Quantum *) NULL)
1130       {
1131         status=MagickFalse;
1132         continue;
1133       }
1134     for (x=0; x < (ssize_t) image->columns; x++)
1135     {
1136       register ssize_t
1137         i;
1138
1139       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1140       {
1141         PixelChannel
1142           channel;
1143
1144         PixelTrait
1145           traits;
1146
1147         channel=GetPixelChannelChannel(image,i);
1148         traits=GetPixelChannelTraits(image,channel);
1149         if ((traits & UpdatePixelTrait) == 0)
1150           continue;
1151         q[i]=ScaleAnyToQuantum(ScaleQuantumToAny(ClampPixel((MagickRealType)
1152           q[i]),range),range);
1153       }
1154       q+=GetPixelChannels(image);
1155     }
1156     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1157       {
1158         status=MagickFalse;
1159         continue;
1160       }
1161   }
1162   image_view=DestroyCacheView(image_view);
1163   if (status != MagickFalse)
1164     image->depth=depth;
1165   return(status);
1166 }
1167 \f
1168 /*
1169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1170 %                                                                             %
1171 %                                                                             %
1172 %                                                                             %
1173 %   S e t I m a g e T y p e                                                   %
1174 %                                                                             %
1175 %                                                                             %
1176 %                                                                             %
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1178 %
1179 %  SetImageType() sets the type of image.  Choose from these types:
1180 %
1181 %        Bilevel        Grayscale       GrayscaleMatte
1182 %        Palette        PaletteMatte    TrueColor
1183 %        TrueColorMatte ColorSeparation ColorSeparationMatte
1184 %        OptimizeType
1185 %
1186 %  The format of the SetImageType method is:
1187 %
1188 %      MagickBooleanType SetImageType(Image *image,const ImageType type,
1189 %        ExceptionInfo *exception)
1190 %
1191 %  A description of each parameter follows:
1192 %
1193 %    o image: the image.
1194 %
1195 %    o type: Image type.
1196 %
1197 %    o exception: return any errors or warnings in this structure.
1198 %
1199 */
1200 MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type,
1201   ExceptionInfo *exception)
1202 {
1203   const char
1204     *artifact;
1205
1206   ImageInfo
1207     *image_info;
1208
1209   MagickBooleanType
1210     status;
1211
1212   QuantizeInfo
1213     *quantize_info;
1214
1215   assert(image != (Image *) NULL);
1216   if (image->debug != MagickFalse)
1217     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1218   assert(image->signature == MagickCoreSignature);
1219   status=MagickTrue;
1220   image_info=AcquireImageInfo();
1221   image_info->dither=image->dither;
1222   artifact=GetImageArtifact(image,"dither");
1223   if (artifact != (const char *) NULL)
1224     (void) SetImageOption(image_info,"dither",artifact);
1225   switch (type)
1226   {
1227     case BilevelType:
1228     {
1229       status=TransformImageColorspace(image,GRAYColorspace,exception);
1230       (void) NormalizeImage(image,exception);
1231       quantize_info=AcquireQuantizeInfo(image_info);
1232       quantize_info->number_colors=2;
1233       quantize_info->colorspace=GRAYColorspace;
1234       status=QuantizeImage(quantize_info,image,exception);
1235       quantize_info=DestroyQuantizeInfo(quantize_info);
1236       image->alpha_trait=UndefinedPixelTrait;
1237       break;
1238     }
1239     case GrayscaleType:
1240     {
1241       status=TransformImageColorspace(image,GRAYColorspace,exception);
1242       image->alpha_trait=UndefinedPixelTrait;
1243       break;
1244     }
1245     case GrayscaleAlphaType:
1246     {
1247       status=TransformImageColorspace(image,GRAYColorspace,exception);
1248       if (image->alpha_trait == UndefinedPixelTrait)
1249         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1250       break;
1251     }
1252     case PaletteType:
1253     {
1254       status=TransformImageColorspace(image,sRGBColorspace,exception);
1255       if ((image->storage_class == DirectClass) || (image->colors > 256))
1256         {
1257           quantize_info=AcquireQuantizeInfo(image_info);
1258           quantize_info->number_colors=256;
1259           status=QuantizeImage(quantize_info,image,exception);
1260           quantize_info=DestroyQuantizeInfo(quantize_info);
1261         }
1262       image->alpha_trait=UndefinedPixelTrait;
1263       break;
1264     }
1265     case PaletteBilevelAlphaType:
1266     {
1267       ChannelType
1268         channel_mask;
1269
1270       status=TransformImageColorspace(image,sRGBColorspace,exception);
1271       if (image->alpha_trait == UndefinedPixelTrait)
1272         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1273       channel_mask=SetImageChannelMask(image,AlphaChannel);
1274       (void) BilevelImage(image,(double) QuantumRange/2.0,exception);
1275       (void) SetImageChannelMask(image,channel_mask);
1276       quantize_info=AcquireQuantizeInfo(image_info);
1277       status=QuantizeImage(quantize_info,image,exception);
1278       quantize_info=DestroyQuantizeInfo(quantize_info);
1279       break;
1280     }
1281     case PaletteAlphaType:
1282     {
1283       status=TransformImageColorspace(image,sRGBColorspace,exception);
1284       if (image->alpha_trait == UndefinedPixelTrait)
1285         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1286       quantize_info=AcquireQuantizeInfo(image_info);
1287       quantize_info->colorspace=TransparentColorspace;
1288       status=QuantizeImage(quantize_info,image,exception);
1289       quantize_info=DestroyQuantizeInfo(quantize_info);
1290       break;
1291     }
1292     case TrueColorType:
1293     {
1294       status=TransformImageColorspace(image,sRGBColorspace,exception);
1295       if (image->storage_class != DirectClass)
1296         status=SetImageStorageClass(image,DirectClass,exception);
1297       image->alpha_trait=UndefinedPixelTrait;
1298       break;
1299     }
1300     case TrueColorAlphaType:
1301     {
1302       status=TransformImageColorspace(image,sRGBColorspace,exception);
1303       if (image->storage_class != DirectClass)
1304         status=SetImageStorageClass(image,DirectClass,exception);
1305       if (image->alpha_trait == UndefinedPixelTrait)
1306         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1307       break;
1308     }
1309     case ColorSeparationType:
1310     {
1311       status=TransformImageColorspace(image,CMYKColorspace,exception);
1312       if (image->storage_class != DirectClass)
1313         status=SetImageStorageClass(image,DirectClass,exception);
1314       image->alpha_trait=UndefinedPixelTrait;
1315       break;
1316     }
1317     case ColorSeparationAlphaType:
1318     {
1319       status=TransformImageColorspace(image,CMYKColorspace,exception);
1320       if (image->storage_class != DirectClass)
1321         status=SetImageStorageClass(image,DirectClass,exception);
1322       if (image->alpha_trait == UndefinedPixelTrait)
1323         status=SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1324       break;
1325     }
1326     case OptimizeType:
1327     case UndefinedType:
1328       break;
1329   }
1330   image_info=DestroyImageInfo(image_info);
1331   if (status == MagickFalse)
1332     return(status);
1333   image->type=type;
1334   return(MagickTrue);
1335 }