image.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                     IIIII  M   M   AAA    GGGG  EEEEE                       %
00007 %                       I    MM MM  A   A  G      E                           %
00008 %                       I    M M M  AAAAA  G  GG  EEE                         %
00009 %                       I    M   M  A   A  G   G  E                           %
00010 %                     IIIII  M   M  A   A   GGGG  EEEEE                       %
00011 %                                                                             %
00012 %                                                                             %
00013 %                           MagickCore Image Methods                          %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 July 1992                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "magick/studio.h"
00044 #include "magick/animate.h"
00045 #include "magick/artifact.h"
00046 #include "magick/blob.h"
00047 #include "magick/blob-private.h"
00048 #include "magick/cache.h"
00049 #include "magick/cache-private.h"
00050 #include "magick/cache-view.h"
00051 #include "magick/client.h"
00052 #include "magick/color.h"
00053 #include "magick/color-private.h"
00054 #include "magick/colormap.h"
00055 #include "magick/colorspace.h"
00056 #include "magick/colorspace-private.h"
00057 #include "magick/composite.h"
00058 #include "magick/composite-private.h"
00059 #include "magick/compress.h"
00060 #include "magick/constitute.h"
00061 #include "magick/deprecate.h"
00062 #include "magick/display.h"
00063 #include "magick/draw.h"
00064 #include "magick/enhance.h"
00065 #include "magick/exception.h"
00066 #include "magick/exception-private.h"
00067 #include "magick/gem.h"
00068 #include "magick/geometry.h"
00069 #include "magick/histogram.h"
00070 #include "magick/image-private.h"
00071 #include "magick/list.h"
00072 #include "magick/magic.h"
00073 #include "magick/magick.h"
00074 #include "magick/memory_.h"
00075 #include "magick/module.h"
00076 #include "magick/monitor.h"
00077 #include "magick/monitor-private.h"
00078 #include "magick/option.h"
00079 #include "magick/paint.h"
00080 #include "magick/pixel-private.h"
00081 #include "magick/profile.h"
00082 #include "magick/property.h"
00083 #include "magick/quantize.h"
00084 #include "magick/random_.h"
00085 #include "magick/segment.h"
00086 #include "magick/semaphore.h"
00087 #include "magick/signature-private.h"
00088 #include "magick/statistic.h"
00089 #include "magick/string_.h"
00090 #include "magick/string-private.h"
00091 #include "magick/thread-private.h"
00092 #include "magick/threshold.h"
00093 #include "magick/timer.h"
00094 #include "magick/utility.h"
00095 #include "magick/version.h"
00096 #include "magick/xwindow-private.h"
00097 
00098 /*
00099   Constant declaration.
00100 */
00101 const char
00102   BackgroundColor[] = "#ffffff",  /* white */
00103   BorderColor[] = "#dfdfdf",  /* gray */
00104   DefaultTileFrame[] = "15x15+3+3",
00105   DefaultTileGeometry[] = "120x120+4+3>",
00106   DefaultTileLabel[] = "%f\n%G\n%b",
00107   ForegroundColor[] = "#000",  /* black */
00108   LoadImageTag[] = "Load/Image",
00109   LoadImagesTag[] = "Load/Images",
00110   MatteColor[] = "#bdbdbd",  /* gray */
00111   PSDensityGeometry[] = "72.0x72.0",
00112   PSPageGeometry[] = "612x792",
00113   SaveImageTag[] = "Save/Image",
00114   SaveImagesTag[] = "Save/Images",
00115   TransparentColor[] = "#00000000";  /* transparent black */
00116 
00117 const double
00118   DefaultResolution = 72.0;
00119 
00120 /*
00121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00122 %                                                                             %
00123 %                                                                             %
00124 %                                                                             %
00125 %   A c q u i r e I m a g e                                                   %
00126 %                                                                             %
00127 %                                                                             %
00128 %                                                                             %
00129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00130 %
00131 %  AcquireImage() returns a pointer to an image structure initialized to
00132 %  default values.
00133 %
00134 %  The format of the AcquireImage method is:
00135 %
00136 %      Image *AcquireImage(const ImageInfo *image_info)
00137 %
00138 %  A description of each parameter follows:
00139 %
00140 %    o image_info: Many of the image default values are set from this
00141 %      structure.  For example, filename, compression, depth, background color,
00142 %      and others.
00143 %
00144 */
00145 MagickExport Image *AcquireImage(const ImageInfo *image_info)
00146 {
00147   Image
00148     *image;
00149 
00150   MagickStatusType
00151     flags;
00152 
00153   /*
00154     Allocate image structure.
00155   */
00156   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00157   image=(Image *) AcquireAlignedMemory(1,sizeof(*image));
00158   if (image == (Image *) NULL)
00159     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00160   (void) ResetMagickMemory(image,0,sizeof(*image));
00161   /*
00162     Initialize Image structure.
00163   */
00164   (void) CopyMagickString(image->magick,"MIFF",MaxTextExtent);
00165   image->storage_class=DirectClass;
00166   image->depth=MAGICKCORE_QUANTUM_DEPTH;
00167   image->colorspace=RGBColorspace;
00168   image->interlace=NoInterlace;
00169   image->ticks_per_second=UndefinedTicksPerSecond;
00170   image->compose=OverCompositeOp;
00171   image->blur=1.0;
00172   GetExceptionInfo(&image->exception);
00173   (void) QueryColorDatabase(BackgroundColor,&image->background_color,
00174     &image->exception);
00175   (void) QueryColorDatabase(BorderColor,&image->border_color,&image->exception);
00176   (void) QueryColorDatabase(MatteColor,&image->matte_color,&image->exception);
00177   (void) QueryColorDatabase(TransparentColor,&image->transparent_color,
00178     &image->exception);
00179   image->x_resolution=DefaultResolution;
00180   image->y_resolution=DefaultResolution;
00181   image->units=PixelsPerInchResolution;
00182   GetTimerInfo(&image->timer);
00183   image->cache=AcquirePixelCache(0);
00184   image->blob=CloneBlobInfo((BlobInfo *) NULL);
00185   image->debug=IsEventLogging();
00186   image->reference_count=1;
00187   image->semaphore=AllocateSemaphoreInfo();
00188   image->signature=MagickSignature;
00189   if (image_info == (ImageInfo *) NULL)
00190     return(image);
00191   /*
00192     Transfer image info.
00193   */
00194   SetBlobExempt(image,image_info->file != (FILE *) NULL ? MagickTrue :
00195     MagickFalse);
00196   (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
00197   (void) CopyMagickString(image->magick_filename,image_info->filename,
00198     MaxTextExtent);
00199   (void) CopyMagickString(image->magick,image_info->magick,MaxTextExtent);
00200   if (image_info->size != (char *) NULL)
00201     {
00202       (void) ParseAbsoluteGeometry(image_info->size,&image->extract_info);
00203       image->columns=image->extract_info.width;
00204       image->rows=image->extract_info.height;
00205       image->offset=image->extract_info.x;
00206       image->extract_info.x=0;
00207       image->extract_info.y=0;
00208     }
00209   if (image_info->extract != (char *) NULL)
00210     {
00211       RectangleInfo
00212         geometry;
00213 
00214       flags=ParseAbsoluteGeometry(image_info->extract,&geometry);
00215       if (((flags & XValue) != 0) || ((flags & YValue) != 0))
00216         {
00217           image->extract_info=geometry;
00218           Swap(image->columns,image->extract_info.width);
00219           Swap(image->rows,image->extract_info.height);
00220         }
00221     }
00222   image->compression=image_info->compression;
00223   image->quality=image_info->quality;
00224   image->endian=image_info->endian;
00225   image->interlace=image_info->interlace;
00226   image->units=image_info->units;
00227   if (image_info->density != (char *) NULL)
00228     {
00229       GeometryInfo
00230         geometry_info;
00231 
00232       flags=ParseGeometry(image_info->density,&geometry_info);
00233       image->x_resolution=geometry_info.rho;
00234       image->y_resolution=geometry_info.sigma;
00235       if ((flags & SigmaValue) == 0)
00236         image->y_resolution=image->x_resolution;
00237     }
00238   if (image_info->page != (char *) NULL)
00239     {
00240       char
00241         *geometry;
00242 
00243       image->page=image->extract_info;
00244       geometry=GetPageGeometry(image_info->page);
00245       (void) ParseAbsoluteGeometry(geometry,&image->page);
00246       geometry=DestroyString(geometry);
00247     }
00248   if (image_info->depth != 0)
00249     image->depth=image_info->depth;
00250   image->dither=image_info->dither;
00251   image->background_color=image_info->background_color;
00252   image->border_color=image_info->border_color;
00253   image->matte_color=image_info->matte_color;
00254   image->transparent_color=image_info->transparent_color;
00255   image->progress_monitor=image_info->progress_monitor;
00256   image->client_data=image_info->client_data;
00257   if (image_info->cache != (void *) NULL)
00258     ClonePixelCacheMethods(image->cache,image_info->cache);
00259   (void) SetImageVirtualPixelMethod(image,image_info->virtual_pixel_method);
00260   (void) SyncImageSettings(image_info,image);
00261   return(image);
00262 }
00263 
00264 /*
00265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00266 %                                                                             %
00267 %                                                                             %
00268 %                                                                             %
00269 %   A c q u i r e I m a g e C o l o r m a p                                   %
00270 %                                                                             %
00271 %                                                                             %
00272 %                                                                             %
00273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00274 %
00275 %  AcquireImageColormap() allocates an image colormap and initializes
00276 %  it to a linear gray colorspace.  If the image already has a colormap,
00277 %  it is replaced.  AcquireImageColormap() returns MagickTrue if successful,
00278 %  otherwise MagickFalse if there is not enough memory.
00279 %
00280 %  The format of the AcquireImageColormap method is:
00281 %
00282 %      MagickBooleanType AcquireImageColormap(Image *image,
00283 %        const unsigned long colors)
00284 %
00285 %  A description of each parameter follows:
00286 %
00287 %    o image: the image.
00288 %
00289 %    o colors: the number of colors in the image colormap.
00290 %
00291 */
00292 
00293 static inline unsigned long MagickMax(const unsigned long x,
00294   const unsigned long y)
00295 {
00296   if (x > y)
00297     return(x);
00298   return(y);
00299 }
00300 
00301 static inline unsigned long MagickMin(const unsigned long x,
00302   const unsigned long y)
00303 {
00304   if (x < y)
00305     return(x);
00306   return(y);
00307 }
00308 
00309 MagickExport MagickBooleanType AcquireImageColormap(Image *image,
00310   const unsigned long colors)
00311 {
00312   register long
00313     i;
00314 
00315   size_t
00316     length;
00317 
00318   /*
00319     Allocate image colormap.
00320   */
00321   assert(image != (Image *) NULL);
00322   assert(image->signature == MagickSignature);
00323   if (image->debug != MagickFalse)
00324     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00325   image->colors=colors;
00326   length=(size_t) colors;
00327   if (image->colormap == (PixelPacket *) NULL)
00328     image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
00329       sizeof(*image->colormap));
00330   else
00331     image->colormap=(PixelPacket *) ResizeQuantumMemory(image->colormap,length,
00332       sizeof(*image->colormap));
00333   if (image->colormap == (PixelPacket *) NULL)
00334     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00335       image->filename);
00336   for (i=0; i < (long) image->colors; i++)
00337   {
00338     unsigned long
00339       pixel;
00340 
00341     pixel=(unsigned long) (i*(QuantumRange/MagickMax(colors-1,1)));
00342     image->colormap[i].red=(Quantum) pixel;
00343     image->colormap[i].green=(Quantum) pixel;
00344     image->colormap[i].blue=(Quantum) pixel;
00345     image->colormap[i].opacity=OpaqueOpacity;
00346   }
00347   return(SetImageStorageClass(image,PseudoClass));
00348 }
00349 
00350 /*
00351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00352 %                                                                             %
00353 %                                                                             %
00354 %                                                                             %
00355 %   A c q u i r e I m a g e I n f o                                           %
00356 %                                                                             %
00357 %                                                                             %
00358 %                                                                             %
00359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00360 %
00361 %  AcquireImageInfo() allocates the ImageInfo structure.
00362 %
00363 %  The format of the AcquireImageInfo method is:
00364 %
00365 %      ImageInfo *AcquireImageInfo(void)
00366 %
00367 */
00368 MagickExport ImageInfo *AcquireImageInfo(void)
00369 {
00370   ImageInfo
00371     *image_info;
00372 
00373   image_info=(ImageInfo *) AcquireAlignedMemory(1,sizeof(*image_info));
00374   if (image_info == (ImageInfo *) NULL)
00375     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00376   GetImageInfo(image_info);
00377   return(image_info);
00378 }
00379 
00380 /*
00381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00382 %                                                                             %
00383 %                                                                             %
00384 %                                                                             %
00385 %   A c q u i r e N e x t I m a g e                                           %
00386 %                                                                             %
00387 %                                                                             %
00388 %                                                                             %
00389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00390 %
00391 %  AcquireNextImage() initializes the next image in a sequence to
00392 %  default values.  The next member of image points to the newly allocated
00393 %  image.  If there is a memory shortage, next is assigned NULL.
00394 %
00395 %  The format of the AcquireNextImage method is:
00396 %
00397 %      void AcquireNextImage(const ImageInfo *image_info,Image *image)
00398 %
00399 %  A description of each parameter follows:
00400 %
00401 %    o image_info: Many of the image default values are set from this
00402 %      structure.  For example, filename, compression, depth, background color,
00403 %      and others.
00404 %
00405 %    o image: the image.
00406 %
00407 */
00408 MagickExport void AcquireNextImage(const ImageInfo *image_info,Image *image)
00409 {
00410   /*
00411     Allocate image structure.
00412   */
00413   assert(image != (Image *) NULL);
00414   assert(image->signature == MagickSignature);
00415   if (image->debug != MagickFalse)
00416     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00417   image->next=AcquireImage(image_info);
00418   if (GetNextImageInList(image) == (Image *) NULL)
00419     return;
00420   (void) CopyMagickString(GetNextImageInList(image)->filename,image->filename,
00421     MaxTextExtent);
00422   if (image_info != (ImageInfo *) NULL)
00423     (void) CopyMagickString(GetNextImageInList(image)->filename,
00424       image_info->filename,MaxTextExtent);
00425   DestroyBlob(GetNextImageInList(image));
00426   image->next->blob=ReferenceBlob(image->blob);
00427   image->next->endian=image->endian;
00428   image->next->scene=image->scene+1;
00429   image->next->previous=image;
00430 }
00431 
00432 /*
00433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00434 %                                                                             %
00435 %                                                                             %
00436 %                                                                             %
00437 %     A p p e n d I m a g e s                                                 %
00438 %                                                                             %
00439 %                                                                             %
00440 %                                                                             %
00441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00442 %
00443 %  AppendImages() takes all images from the current image pointer to the end
00444 %  of the image list and appends them to each other top-to-bottom if the
00445 %  stack parameter is true, otherwise left-to-right.
00446 %
00447 %  The current gravity setting now effects how the image is justified in the
00448 %  final image.
00449 %
00450 %  The format of the AppendImages method is:
00451 %
00452 %      Image *AppendImages(const Image *image,const MagickBooleanType stack,
00453 %        ExceptionInfo *exception)
00454 %
00455 %  A description of each parameter follows:
00456 %
00457 %    o image: the image sequence.
00458 %
00459 %    o stack: A value other than 0 stacks the images top-to-bottom.
00460 %
00461 %    o exception: return any errors or warnings in this structure.
00462 %
00463 */
00464 MagickExport Image *AppendImages(const Image *image,
00465   const MagickBooleanType stack,ExceptionInfo *exception)
00466 {
00467 #define AppendImageTag  "Append/Image"
00468 
00469   CacheView
00470     *append_view,
00471     *image_view;
00472 
00473   Image
00474     *append_image;
00475 
00476   long
00477     n,
00478     x_offset,
00479     y,
00480     y_offset;
00481 
00482   MagickBooleanType
00483     matte,
00484     proceed,
00485     status;
00486 
00487   RectangleInfo
00488     geometry;
00489 
00490   register const Image
00491     *next;
00492 
00493   unsigned long
00494     height,
00495     number_images,
00496     width;
00497 
00498   /*
00499     Ensure the image have the same column width.
00500   */
00501   assert(image != (Image *) NULL);
00502   assert(image->signature == MagickSignature);
00503   if (image->debug != MagickFalse)
00504     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00505   assert(exception != (ExceptionInfo *) NULL);
00506   assert(exception->signature == MagickSignature);
00507   matte=image->matte;
00508   number_images=1;
00509   width=image->columns;
00510   height=image->rows;
00511   next=GetNextImageInList(image);
00512   for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
00513   {
00514     if (next->matte != MagickFalse)
00515       matte=MagickTrue;
00516     number_images++;
00517     if (stack != MagickFalse)
00518       {
00519         if (next->columns > width)
00520           width=next->columns;
00521         height+=next->rows;
00522         continue;
00523       }
00524     width+=next->columns;
00525     if (next->rows > height)
00526       height=next->rows;
00527   }
00528   /*
00529     Initialize append next attributes.
00530   */
00531   append_image=CloneImage(image,width,height,MagickTrue,exception);
00532   if (append_image == (Image *) NULL)
00533     return((Image *) NULL);
00534   if (SetImageStorageClass(append_image,DirectClass) == MagickFalse)
00535     {
00536       InheritException(exception,&append_image->exception);
00537       append_image=DestroyImage(append_image);
00538       return((Image *) NULL);
00539     }
00540   append_image->matte=matte;
00541   (void) SetImageBackgroundColor(append_image);
00542   status=MagickTrue;
00543   x_offset=0;
00544   y_offset=0;
00545   append_view=AcquireCacheView(append_image);
00546   for (n=0; n < (long) number_images; n++)
00547   {
00548     SetGeometry(append_image,&geometry);
00549     GravityAdjustGeometry(image->columns,image->rows,image->gravity,&geometry);
00550     if (stack != MagickFalse)
00551       x_offset-=geometry.x;
00552     else
00553       y_offset-=geometry.y;
00554     image_view=AcquireCacheView(image);
00555 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00556     #pragma omp parallel for schedule(dynamic,4) shared(status)
00557 #endif
00558     for (y=0; y < (long) image->rows; y++)
00559     {
00560       MagickBooleanType
00561         sync;
00562 
00563       register const IndexPacket
00564         *restrict indexes;
00565 
00566       register const PixelPacket
00567         *restrict p;
00568 
00569       register IndexPacket
00570         *restrict append_indexes;
00571 
00572       register long
00573         x;
00574 
00575       register PixelPacket
00576         *restrict q;
00577 
00578       if (status == MagickFalse)
00579         continue;
00580       p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
00581       q=QueueCacheViewAuthenticPixels(append_view,x_offset,y+y_offset,
00582         image->columns,1,exception);
00583       if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
00584         {
00585           status=MagickFalse;
00586           continue;
00587         }
00588       indexes=GetCacheViewVirtualIndexQueue(image_view);
00589       append_indexes=GetCacheViewAuthenticIndexQueue(append_view);
00590       for (x=0; x < (long) image->columns; x++)
00591       {
00592         SetRedPixelComponent(q,GetRedPixelComponent(p));
00593         SetGreenPixelComponent(q,GetGreenPixelComponent(p));
00594         SetBluePixelComponent(q,GetBluePixelComponent(p));
00595         SetOpacityPixelComponent(q,OpaqueOpacity);
00596         if (image->matte != MagickFalse)
00597           SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
00598         if (image->colorspace == CMYKColorspace)
00599           append_indexes[x]=indexes[x];
00600         p++;
00601         q++;
00602       }
00603       sync=SyncCacheViewAuthenticPixels(append_view,exception);
00604       if (sync == MagickFalse)
00605         continue;
00606     }
00607     image_view=DestroyCacheView(image_view);
00608     proceed=SetImageProgress(image,AppendImageTag,n,number_images);
00609     if (proceed == MagickFalse)
00610       break;
00611     if (stack == MagickFalse)
00612       {
00613         x_offset+=image->columns;
00614         y_offset=0;
00615       }
00616     else
00617       {
00618         x_offset=0;
00619         y_offset+=image->rows;
00620       }
00621     image=GetNextImageInList(image);
00622   }
00623   append_view=DestroyCacheView(append_view);
00624   if (status == MagickFalse)
00625     append_image=DestroyImage(append_image);
00626   return(append_image);
00627 }
00628 
00629 /*
00630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00631 %                                                                             %
00632 %                                                                             %
00633 %                                                                             %
00634 %   C a t c h I m a g e E x c e p t i o n                                     %
00635 %                                                                             %
00636 %                                                                             %
00637 %                                                                             %
00638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00639 %
00640 %  CatchImageException() returns if no exceptions are found in the image
00641 %  sequence, otherwise it determines the most severe exception and reports
00642 %  it as a warning or error depending on the severity.
00643 %
00644 %  The format of the CatchImageException method is:
00645 %
00646 %      ExceptionType CatchImageException(Image *image)
00647 %
00648 %  A description of each parameter follows:
00649 %
00650 %    o image: An image sequence.
00651 %
00652 */
00653 MagickExport ExceptionType CatchImageException(Image *image)
00654 {
00655   ExceptionInfo
00656     *exception;
00657 
00658   ExceptionType
00659     severity;
00660 
00661   assert(image != (const Image *) NULL);
00662   assert(image->signature == MagickSignature);
00663   if (image->debug != MagickFalse)
00664     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00665   exception=AcquireExceptionInfo();
00666   GetImageException(image,exception);
00667   CatchException(exception);
00668   severity=exception->severity;
00669   exception=DestroyExceptionInfo(exception);
00670   return(severity);
00671 }
00672 
00673 /*
00674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00675 %                                                                             %
00676 %                                                                             %
00677 %                                                                             %
00678 %   C l i p I m a g e P a t h                                                 %
00679 %                                                                             %
00680 %                                                                             %
00681 %                                                                             %
00682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00683 %
00684 %  ClipImagePath() sets the image clip mask based any clipping path information
00685 %  if it exists.
00686 %
00687 %  The format of the ClipImagePath method is:
00688 %
00689 %      MagickBooleanType ClipImagePath(Image *image,const char *pathname,
00690 %        const MagickBooleanType inside)
00691 %
00692 %  A description of each parameter follows:
00693 %
00694 %    o image: the image.
00695 %
00696 %    o pathname: name of clipping path resource. If name is preceded by #, use
00697 %      clipping path numbered by name.
00698 %
00699 %    o inside: if non-zero, later operations take effect inside clipping path.
00700 %      Otherwise later operations take effect outside clipping path.
00701 %
00702 */
00703 
00704 MagickExport MagickBooleanType ClipImage(Image *image)
00705 {
00706   return(ClipImagePath(image,"#1",MagickTrue));
00707 }
00708 
00709 MagickExport MagickBooleanType ClipImagePath(Image *image,const char *pathname,
00710   const MagickBooleanType inside)
00711 {
00712 #define ClipImagePathTag  "ClipPath/Image"
00713 
00714   char
00715     *property;
00716 
00717   const char
00718     *value;
00719 
00720   Image
00721     *clip_mask;
00722 
00723   ImageInfo
00724     *image_info;
00725 
00726   assert(image != (const Image *) NULL);
00727   assert(image->signature == MagickSignature);
00728   if (image->debug != MagickFalse)
00729     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00730   assert(pathname != NULL);
00731   property=AcquireString(pathname);
00732   (void) FormatMagickString(property,MaxTextExtent,"8BIM:1999,2998:%s",
00733     pathname);
00734   value=GetImageProperty(image,property);
00735   property=DestroyString(property);
00736   if (value == (const char *) NULL)
00737     {
00738       ThrowFileException(&image->exception,OptionError,"NoClipPathDefined",
00739         image->filename);
00740       return(MagickFalse);
00741     }
00742   image_info=AcquireImageInfo();
00743   (void) CopyMagickString(image_info->filename,image->filename,MaxTextExtent);
00744   (void) ConcatenateMagickString(image_info->filename,pathname,MaxTextExtent);
00745   clip_mask=BlobToImage(image_info,value,strlen(value),&image->exception);
00746   image_info=DestroyImageInfo(image_info);
00747   if (clip_mask == (Image *) NULL)
00748     return(MagickFalse);
00749   if (clip_mask->storage_class == PseudoClass)
00750     {
00751       (void) SyncImage(clip_mask);
00752       if (SetImageStorageClass(clip_mask,DirectClass) == MagickFalse)
00753         return(MagickFalse);
00754     }
00755   if (inside == MagickFalse)
00756     (void) NegateImage(clip_mask,MagickFalse);
00757   (void) FormatMagickString(clip_mask->magick_filename,MaxTextExtent,
00758     "8BIM:1999,2998:%s\nPS",pathname);
00759   (void) SetImageClipMask(image,clip_mask);
00760   clip_mask=DestroyImage(clip_mask);
00761   return(MagickTrue);
00762 }
00763 
00764 /*
00765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00766 %                                                                             %
00767 %                                                                             %
00768 %                                                                             %
00769 %   C l o n e I m a g e                                                       %
00770 %                                                                             %
00771 %                                                                             %
00772 %                                                                             %
00773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00774 %
00775 %  CloneImage() copies an image and returns the copy as a new image object.
00776 %  If the specified columns and rows is 0, an exact copy of the image is
00777 %  returned, otherwise the pixel data is undefined and must be initialized
00778 %  with the QueueAuthenticPixels() and SyncAuthenticPixels() methods.  On
00779 %  failure, a NULL image is returned and exception describes the reason for the
00780 %  failure.
00781 %
00782 %  The format of the CloneImage method is:
00783 %
00784 %      Image *CloneImage(const Image *image,const unsigned long columns,
00785 %        const unsigned long rows,const MagickBooleanType orphan,
00786 %        ExceptionInfo *exception)
00787 %
00788 %  A description of each parameter follows:
00789 %
00790 %    o image: the image.
00791 %
00792 %    o columns: the number of columns in the cloned image.
00793 %
00794 %    o rows: the number of rows in the cloned image.
00795 %
00796 %    o detach:  With a value other than 0, the cloned image is detached from
00797 %      its parent I/O stream.
00798 %
00799 %    o exception: return any errors or warnings in this structure.
00800 %
00801 */
00802 MagickExport Image *CloneImage(const Image *image,const unsigned long columns,
00803   const unsigned long rows,const MagickBooleanType detach,
00804   ExceptionInfo *exception)
00805 {
00806   Image
00807     *clone_image;
00808 
00809   MagickRealType
00810     scale;
00811 
00812   size_t
00813     length;
00814 
00815   /*
00816     Clone the image.
00817   */
00818   assert(image != (const Image *) NULL);
00819   assert(image->signature == MagickSignature);
00820   if (image->debug != MagickFalse)
00821     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00822   assert(exception != (ExceptionInfo *) NULL);
00823   assert(exception->signature == MagickSignature);
00824   clone_image=(Image *) AcquireAlignedMemory(1,sizeof(*clone_image));
00825   if (clone_image == (Image *) NULL)
00826     ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
00827   (void) ResetMagickMemory(clone_image,0,sizeof(*clone_image));
00828   clone_image->signature=MagickSignature;
00829   clone_image->storage_class=image->storage_class;
00830   clone_image->colorspace=image->colorspace;
00831   clone_image->matte=image->matte;
00832   clone_image->columns=image->columns;
00833   clone_image->rows=image->rows;
00834   clone_image->dither=image->dither;
00835   if (image->colormap != (PixelPacket *) NULL)
00836     {
00837       /*
00838         Allocate and copy the image colormap.
00839       */
00840       clone_image->colors=image->colors;
00841       length=(size_t) image->colors;
00842       clone_image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
00843         sizeof(*clone_image->colormap));
00844       if (clone_image->colormap == (PixelPacket *) NULL)
00845         ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
00846       (void) CopyMagickMemory(clone_image->colormap,image->colormap,length*
00847         sizeof(*clone_image->colormap));
00848     }
00849   (void) CloneImageProfiles(clone_image,image);
00850   (void) CloneImageProperties(clone_image,image);
00851   (void) CloneImageArtifacts(clone_image,image);
00852   GetTimerInfo(&clone_image->timer);
00853   GetExceptionInfo(&clone_image->exception);
00854   InheritException(&clone_image->exception,&image->exception);
00855   if (image->ascii85 != (void *) NULL)
00856     Ascii85Initialize(clone_image);
00857   clone_image->magick_columns=image->magick_columns;
00858   clone_image->magick_rows=image->magick_rows;
00859   clone_image->type=image->type;
00860   (void) CopyMagickString(clone_image->magick_filename,image->magick_filename,
00861     MaxTextExtent);
00862   (void) CopyMagickString(clone_image->magick,image->magick,MaxTextExtent);
00863   (void) CopyMagickString(clone_image->filename,image->filename,MaxTextExtent);
00864   clone_image->progress_monitor=image->progress_monitor;
00865   clone_image->client_data=image->client_data;
00866   clone_image->reference_count=1;
00867   clone_image->next=NewImageList();
00868   clone_image->previous=NewImageList();
00869   clone_image->list=NewImageList();
00870   clone_image->clip_mask=NewImageList();
00871   clone_image->mask=NewImageList();
00872   if (detach == MagickFalse)
00873     clone_image->blob=ReferenceBlob(image->blob);
00874   else
00875     clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
00876   clone_image->debug=IsEventLogging();
00877   clone_image->semaphore=AllocateSemaphoreInfo();
00878   if ((columns == 0) && (rows == 0))
00879     {
00880       if (image->montage != (char *) NULL)
00881         (void) CloneString(&clone_image->montage,image->montage);
00882       if (image->directory != (char *) NULL)
00883         (void) CloneString(&clone_image->directory,image->directory);
00884       if (image->clip_mask != (Image *) NULL)
00885         clone_image->clip_mask=CloneImage(image->clip_mask,0,0,MagickTrue,
00886           exception);
00887       if (image->mask != (Image *) NULL)
00888         clone_image->mask=CloneImage(image->mask,0,0,MagickTrue,exception);
00889       clone_image->cache=ReferencePixelCache(image->cache);
00890       return(clone_image);
00891     }
00892   scale=(MagickRealType) columns/(MagickRealType) image->columns;
00893   clone_image->page.width=(unsigned long) floor(scale*image->page.width+0.5);
00894   clone_image->page.x=(long) ceil(scale*image->page.x-0.5);
00895   clone_image->tile_offset.x=(long) ceil(scale*image->tile_offset.x-0.5);
00896   scale=(MagickRealType) rows/(MagickRealType) image->rows;
00897   clone_image->page.height=(unsigned long) floor(scale*image->page.height+0.5);
00898   clone_image->page.y=(long) ceil(image->page.y*scale-0.5);
00899   clone_image->tile_offset.y=(long) ceil(scale*image->tile_offset.y-0.5);
00900   clone_image->columns=columns;
00901   clone_image->rows=rows;
00902   clone_image->cache=ClonePixelCache(image->cache);
00903   return(clone_image);
00904 }
00905 
00906 /*
00907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00908 %                                                                             %
00909 %                                                                             %
00910 %                                                                             %
00911 %   C l o n e I m a g e I n f o                                               %
00912 %                                                                             %
00913 %                                                                             %
00914 %                                                                             %
00915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00916 %
00917 %  CloneImageInfo() makes a copy of the given image info structure.  If
00918 %  NULL is specified, a new image info structure is created initialized to
00919 %  default values.
00920 %
00921 %  The format of the CloneImageInfo method is:
00922 %
00923 %      ImageInfo *CloneImageInfo(const ImageInfo *image_info)
00924 %
00925 %  A description of each parameter follows:
00926 %
00927 %    o image_info: the image info.
00928 %
00929 */
00930 MagickExport ImageInfo *CloneImageInfo(const ImageInfo *image_info)
00931 {
00932   ImageInfo
00933     *clone_info;
00934 
00935   clone_info=AcquireImageInfo();
00936   if (image_info == (ImageInfo *) NULL)
00937     return(clone_info);
00938   clone_info->compression=image_info->compression;
00939   clone_info->temporary=image_info->temporary;
00940   clone_info->adjoin=image_info->adjoin;
00941   clone_info->antialias=image_info->antialias;
00942   clone_info->scene=image_info->scene;
00943   clone_info->number_scenes=image_info->number_scenes;
00944   clone_info->depth=image_info->depth;
00945   if (image_info->size != (char *) NULL)
00946     (void) CloneString(&clone_info->size,image_info->size);
00947   if (image_info->extract != (char *) NULL)
00948     (void) CloneString(&clone_info->extract,image_info->extract);
00949   if (image_info->scenes != (char *) NULL)
00950     (void) CloneString(&clone_info->scenes,image_info->scenes);
00951   if (image_info->page != (char *) NULL)
00952     (void) CloneString(&clone_info->page,image_info->page);
00953   clone_info->interlace=image_info->interlace;
00954   clone_info->endian=image_info->endian;
00955   clone_info->units=image_info->units;
00956   clone_info->quality=image_info->quality;
00957   if (image_info->sampling_factor != (char *) NULL)
00958     (void) CloneString(&clone_info->sampling_factor,
00959       image_info->sampling_factor);
00960   if (image_info->server_name != (char *) NULL)
00961     (void) CloneString(&clone_info->server_name,image_info->server_name);
00962   if (image_info->font != (char *) NULL)
00963     (void) CloneString(&clone_info->font,image_info->font);
00964   if (image_info->texture != (char *) NULL)
00965     (void) CloneString(&clone_info->texture,image_info->texture);
00966   if (image_info->density != (char *) NULL)
00967     (void) CloneString(&clone_info->density,image_info->density);
00968   clone_info->pointsize=image_info->pointsize;
00969   clone_info->fuzz=image_info->fuzz;
00970   clone_info->pen=image_info->pen;
00971   clone_info->background_color=image_info->background_color;
00972   clone_info->border_color=image_info->border_color;
00973   clone_info->matte_color=image_info->matte_color;
00974   clone_info->transparent_color=image_info->transparent_color;
00975   clone_info->dither=image_info->dither;
00976   clone_info->monochrome=image_info->monochrome;
00977   clone_info->colors=image_info->colors;
00978   clone_info->colorspace=image_info->colorspace;
00979   clone_info->type=image_info->type;
00980   clone_info->orientation=image_info->orientation;
00981   clone_info->preview_type=image_info->preview_type;
00982   clone_info->group=image_info->group;
00983   clone_info->ping=image_info->ping;
00984   clone_info->verbose=image_info->verbose;
00985   if (image_info->view != (char *) NULL)
00986     (void) CloneString(&clone_info->view,image_info->view);
00987   if (image_info->authenticate != (char *) NULL)
00988     (void) CloneString(&clone_info->authenticate,image_info->authenticate);
00989   (void) CloneImageOptions(clone_info,image_info);
00990   clone_info->progress_monitor=image_info->progress_monitor;
00991   clone_info->client_data=image_info->client_data;
00992   clone_info->cache=image_info->cache;
00993   if (image_info->cache != (void *) NULL)
00994     clone_info->cache=ReferencePixelCache(image_info->cache);
00995   if (image_info->profile != (void *) NULL)
00996     clone_info->profile=(void *) CloneStringInfo((StringInfo *)
00997       image_info->profile);
00998   SetImageInfoFile(clone_info,image_info->file);
00999   SetImageInfoBlob(clone_info,image_info->blob,image_info->length);
01000   clone_info->stream=image_info->stream;
01001   clone_info->virtual_pixel_method=image_info->virtual_pixel_method;
01002   (void) CopyMagickString(clone_info->magick,image_info->magick,MaxTextExtent);
01003   (void) CopyMagickString(clone_info->unique,image_info->unique,MaxTextExtent);
01004   (void) CopyMagickString(clone_info->zero,image_info->zero,MaxTextExtent);
01005   (void) CopyMagickString(clone_info->filename,image_info->filename,
01006     MaxTextExtent);
01007   clone_info->subimage=image_info->scene;  /* deprecated */
01008   clone_info->subrange=image_info->number_scenes;  /* deprecated */
01009   clone_info->channel=image_info->channel;
01010   clone_info->debug=IsEventLogging();
01011   clone_info->signature=image_info->signature;
01012   return(clone_info);
01013 }
01014 
01015 /*
01016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01017 %                                                                             %
01018 %                                                                             %
01019 %                                                                             %
01020 %     C o m b i n e I m a g e s                                               %
01021 %                                                                             %
01022 %                                                                             %
01023 %                                                                             %
01024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01025 %
01026 %  CombineImages() combines one or more images into a single image.  The
01027 %  grayscale value of the pixels of each image in the sequence is assigned in
01028 %  order to the specified channels of the combined image.   The typical
01029 %  ordering would be image 1 => Red, 2 => Green, 3 => Blue, etc.
01030 %
01031 %  The format of the CombineImages method is:
01032 %
01033 %      Image *CombineImages(const Image *image,const ChannelType channel,
01034 %        ExceptionInfo *exception)
01035 %
01036 %  A description of each parameter follows:
01037 %
01038 %    o image: the image.
01039 %
01040 %    o exception: return any errors or warnings in this structure.
01041 %
01042 */
01043 MagickExport Image *CombineImages(const Image *image,const ChannelType channel,
01044   ExceptionInfo *exception)
01045 {
01046 #define CombineImageTag  "Combine/Image"
01047 
01048   CacheView
01049     *combine_view;
01050 
01051   const Image
01052     *next;
01053 
01054   Image
01055     *combine_image;
01056 
01057   long
01058     progress,
01059     y;
01060 
01061   MagickBooleanType
01062     status;
01063 
01064   /*
01065     Ensure the image are the same size.
01066   */
01067   assert(image != (const Image *) NULL);
01068   assert(image->signature == MagickSignature);
01069   if (image->debug != MagickFalse)
01070     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01071   assert(exception != (ExceptionInfo *) NULL);
01072   assert(exception->signature == MagickSignature);
01073   for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
01074   {
01075     if ((next->columns != image->columns) || (next->rows != image->rows))
01076       ThrowImageException(OptionError,"ImagesAreNotTheSameSize");
01077   }
01078   combine_image=CloneImage(image,0,0,MagickTrue,exception);
01079   if (combine_image == (Image *) NULL)
01080     return((Image *) NULL);
01081   if (SetImageStorageClass(combine_image,DirectClass) == MagickFalse)
01082     {
01083       InheritException(exception,&combine_image->exception);
01084       combine_image=DestroyImage(combine_image);
01085       return((Image *) NULL);
01086     }
01087   if ((channel & OpacityChannel) != 0)
01088     combine_image->matte=MagickTrue;
01089   (void) SetImageBackgroundColor(combine_image);
01090   /*
01091     Combine images.
01092   */
01093   status=MagickTrue;
01094   progress=0;
01095   combine_view=AcquireCacheView(combine_image);
01096 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01097   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
01098 #endif
01099   for (y=0; y < (long) combine_image->rows; y++)
01100   {
01101     CacheView
01102       *image_view;
01103 
01104     const Image
01105       *next;
01106 
01107     PixelPacket
01108       *pixels;
01109 
01110     register const PixelPacket
01111       *restrict p;
01112 
01113     register long
01114       x;
01115 
01116     register PixelPacket
01117       *restrict q;
01118 
01119     if (status == MagickFalse)
01120       continue;
01121     pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns,
01122       1,exception);
01123     if (pixels == (PixelPacket *) NULL)
01124       {
01125         status=MagickFalse;
01126         continue;
01127       }
01128     next=image;
01129     if (((channel & RedChannel) != 0) && (next != (Image *) NULL))
01130       {
01131         image_view=AcquireCacheView(next);
01132         p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01133         if (p == (const PixelPacket *) NULL)
01134           continue;
01135         q=pixels;
01136         for (x=0; x < (long) combine_image->columns; x++)
01137         {
01138           SetRedPixelComponent(q,PixelIntensityToQuantum(p));
01139           p++;
01140           q++;
01141         }
01142         image_view=DestroyCacheView(image_view);
01143         next=GetNextImageInList(next);
01144       }
01145     if (((channel & GreenChannel) != 0) && (next != (Image *) NULL))
01146       {
01147         image_view=AcquireCacheView(next);
01148         p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01149         if (p == (const PixelPacket *) NULL)
01150           continue;
01151         q=pixels;
01152         for (x=0; x < (long) combine_image->columns; x++)
01153         {
01154           SetGreenPixelComponent(q,PixelIntensityToQuantum(p));
01155           p++;
01156           q++;
01157         }
01158         image_view=DestroyCacheView(image_view);
01159         next=GetNextImageInList(next);
01160       }
01161     if (((channel & BlueChannel) != 0) && (next != (Image *) NULL))
01162       {
01163         image_view=AcquireCacheView(next);
01164         p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01165         if (p == (const PixelPacket *) NULL)
01166           continue;
01167         q=pixels;
01168         for (x=0; x < (long) combine_image->columns; x++)
01169         {
01170           SetBluePixelComponent(q,PixelIntensityToQuantum(p));
01171           p++;
01172           q++;
01173         }
01174         image_view=DestroyCacheView(image_view);
01175         next=GetNextImageInList(next);
01176       }
01177     if (((channel & OpacityChannel) != 0) && (next != (Image *) NULL))
01178       {
01179         image_view=AcquireCacheView(next);
01180         p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01181         if (p == (const PixelPacket *) NULL)
01182           continue;
01183         q=pixels;
01184         for (x=0; x < (long) combine_image->columns; x++)
01185         {
01186           SetOpacityPixelComponent(q,PixelIntensityToQuantum(p));
01187           p++;
01188           q++;
01189         }
01190         image_view=DestroyCacheView(image_view);
01191         next=GetNextImageInList(next);
01192       }
01193     if (((channel & IndexChannel) != 0) &&
01194         (image->colorspace == CMYKColorspace) && (next != (Image *) NULL))
01195       {
01196         IndexPacket
01197           *indexes;
01198 
01199         image_view=AcquireCacheView(next);
01200         p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01201         if (p == (const PixelPacket *) NULL)
01202           continue;
01203         indexes=GetCacheViewAuthenticIndexQueue(combine_view);
01204         for (x=0; x < (long) combine_image->columns; x++)
01205         {
01206           indexes[x]=PixelIntensityToQuantum(p);
01207           p++;
01208         }
01209         image_view=DestroyCacheView(image_view);
01210         next=GetNextImageInList(next);
01211       }
01212     if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse)
01213       status=MagickFalse;
01214     if (image->progress_monitor != (MagickProgressMonitor) NULL)
01215       {
01216         MagickBooleanType
01217           proceed;
01218 
01219 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01220         #pragma omp critical (MagickCore_CombineImages)
01221 #endif
01222         proceed=SetImageProgress(image,CombineImageTag,progress++,
01223           combine_image->rows);
01224         if (proceed == MagickFalse)
01225           status=MagickFalse;
01226       }
01227   }
01228   combine_view=DestroyCacheView(combine_view);
01229   if (status == MagickFalse)
01230     combine_image=DestroyImage(combine_image);
01231   return(combine_image);
01232 }
01233 
01234 /*
01235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01236 %                                                                             %
01237 %                                                                             %
01238 %                                                                             %
01239 %   D e s t r o y I m a g e                                                   %
01240 %                                                                             %
01241 %                                                                             %
01242 %                                                                             %
01243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01244 %
01245 %  DestroyImage() dereferences an image, deallocating memory associated with
01246 %  the image if the reference count becomes zero.
01247 %
01248 %  The format of the DestroyImage method is:
01249 %
01250 %      Image *DestroyImage(Image *image)
01251 %
01252 %  A description of each parameter follows:
01253 %
01254 %    o image: the image.
01255 %
01256 */
01257 MagickExport Image *DestroyImage(Image *image)
01258 {
01259   MagickBooleanType
01260     destroy;
01261 
01262   /*
01263     Dereference image.
01264   */
01265   assert(image != (Image *) NULL);
01266   assert(image->signature == MagickSignature);
01267   if (image->debug != MagickFalse)
01268     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01269   destroy=MagickFalse;
01270   LockSemaphoreInfo(image->semaphore);
01271   image->reference_count--;
01272   if (image->reference_count == 0)
01273     destroy=MagickTrue;
01274   UnlockSemaphoreInfo(image->semaphore);
01275   if (destroy == MagickFalse)
01276     return((Image *) NULL);
01277   /*
01278     Destroy image.
01279   */
01280   DestroyImagePixels(image);
01281   if (image->clip_mask != (Image *) NULL)
01282     image->clip_mask=DestroyImage(image->clip_mask);
01283   if (image->mask != (Image *) NULL)
01284     image->mask=DestroyImage(image->mask);
01285   if (image->montage != (char *) NULL)
01286     image->montage=DestroyString(image->montage);
01287   if (image->directory != (char *) NULL)
01288     image->directory=DestroyString(image->directory);
01289   if (image->colormap != (PixelPacket *) NULL)
01290     image->colormap=(PixelPacket *) RelinquishMagickMemory(image->colormap);
01291   if (image->geometry != (char *) NULL)
01292     image->geometry=DestroyString(image->geometry);
01293   DestroyImageProfiles(image);
01294   DestroyImageProperties(image);
01295   DestroyImageArtifacts(image);
01296   if (image->ascii85 != (Ascii85Info*) NULL)
01297     image->ascii85=(Ascii85Info *) RelinquishMagickMemory(image->ascii85);
01298   DestroyBlob(image);
01299   (void) DestroyExceptionInfo(&image->exception);
01300   if (image->semaphore != (SemaphoreInfo *) NULL)
01301     DestroySemaphoreInfo(&image->semaphore);
01302   image->signature=(~MagickSignature);
01303   image=(Image *) RelinquishMagickMemory(image);
01304   return(image);
01305 }
01306 
01307 /*
01308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01309 %                                                                             %
01310 %                                                                             %
01311 %                                                                             %
01312 %   D e s t r o y I m a g e I n f o                                           %
01313 %                                                                             %
01314 %                                                                             %
01315 %                                                                             %
01316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01317 %
01318 %  DestroyImageInfo() deallocates memory associated with an ImageInfo
01319 %  structure.
01320 %
01321 %  The format of the DestroyImageInfo method is:
01322 %
01323 %      ImageInfo *DestroyImageInfo(ImageInfo *image_info)
01324 %
01325 %  A description of each parameter follows:
01326 %
01327 %    o image_info: the image info.
01328 %
01329 */
01330 MagickExport ImageInfo *DestroyImageInfo(ImageInfo *image_info)
01331 {
01332   assert(image_info != (ImageInfo *) NULL);
01333   assert(image_info->signature == MagickSignature);
01334   if (image_info->debug != MagickFalse)
01335     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
01336       image_info->filename);
01337   if (image_info->size != (char *) NULL)
01338     image_info->size=DestroyString(image_info->size);
01339   if (image_info->extract != (char *) NULL)
01340     image_info->extract=DestroyString(image_info->extract);
01341   if (image_info->scenes != (char *) NULL)
01342     image_info->scenes=DestroyString(image_info->scenes);
01343   if (image_info->page != (char *) NULL)
01344     image_info->page=DestroyString(image_info->page);
01345   if (image_info->sampling_factor != (char *) NULL)
01346     image_info->sampling_factor=DestroyString(
01347       image_info->sampling_factor);
01348   if (image_info->server_name != (char *) NULL)
01349     image_info->server_name=DestroyString(
01350       image_info->server_name);
01351   if (image_info->font != (char *) NULL)
01352     image_info->font=DestroyString(image_info->font);
01353   if (image_info->texture != (char *) NULL)
01354     image_info->texture=DestroyString(image_info->texture);
01355   if (image_info->density != (char *) NULL)
01356     image_info->density=DestroyString(image_info->density);
01357   if (image_info->view != (char *) NULL)
01358     image_info->view=DestroyString(image_info->view);
01359   if (image_info->authenticate != (char *) NULL)
01360     image_info->authenticate=DestroyString(
01361       image_info->authenticate);
01362   DestroyImageOptions(image_info);
01363   if (image_info->cache != (void *) NULL)
01364     image_info->cache=DestroyPixelCache(image_info->cache);
01365   if (image_info->profile != (StringInfo *) NULL)
01366     image_info->profile=(void *) DestroyStringInfo((StringInfo *)
01367       image_info->profile);
01368   image_info->signature=(~MagickSignature);
01369   image_info=(ImageInfo *) RelinquishMagickMemory(image_info);
01370   return(image_info);
01371 }
01372 
01373 /*
01374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01375 %                                                                             %
01376 %                                                                             %
01377 %                                                                             %
01378 +   D i s a s s o c i a t e I m a g e S t r e a m                             %
01379 %                                                                             %
01380 %                                                                             %
01381 %                                                                             %
01382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01383 %
01384 %  DisassociateImageStream() disassociates the image stream.
01385 %
01386 %  The format of the DisassociateImageStream method is:
01387 %
01388 %      MagickBooleanType DisassociateImageStream(const Image *image)
01389 %
01390 %  A description of each parameter follows:
01391 %
01392 %    o image: the image.
01393 %
01394 */
01395 MagickExport void DisassociateImageStream(Image *image)
01396 {
01397   assert(image != (const Image *) NULL);
01398   assert(image->signature == MagickSignature);
01399   if (image->debug != MagickFalse)
01400     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01401   (void) DetachBlob(image->blob);
01402 }
01403 
01404 /*
01405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01406 %                                                                             %
01407 %                                                                             %
01408 %                                                                             %
01409 %   G e t I m a g e A l p h a C h a n n e l                                   %
01410 %                                                                             %
01411 %                                                                             %
01412 %                                                                             %
01413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01414 %
01415 %  GetImageAlphaChannel() returns MagickFalse if the image alpha channel is
01416 %  not activated.  That is, the image is RGB rather than RGBA or CMYK rather
01417 %  than CMYKA.
01418 %
01419 %  The format of the GetImageAlphaChannel method is:
01420 %
01421 %      MagickBooleanType GetImageAlphaChannel(const Image *image)
01422 %
01423 %  A description of each parameter follows:
01424 %
01425 %    o image: the image.
01426 %
01427 */
01428 MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
01429 {
01430   assert(image != (const Image *) NULL);
01431   if (image->debug != MagickFalse)
01432     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01433   assert(image->signature == MagickSignature);
01434   return(image->matte);
01435 }
01436 
01437 /*
01438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01439 %                                                                             %
01440 %                                                                             %
01441 %                                                                             %
01442 %   G e t I m a g e C l i p M a s k                                           %
01443 %                                                                             %
01444 %                                                                             %
01445 %                                                                             %
01446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01447 %
01448 %  GetImageClipMask() returns the clip path associated with the image.
01449 %
01450 %  The format of the GetImageClipMask method is:
01451 %
01452 %      Image *GetImageClipMask(const Image *image,ExceptionInfo *exception)
01453 %
01454 %  A description of each parameter follows:
01455 %
01456 %    o image: the image.
01457 %
01458 */
01459 MagickExport Image *GetImageClipMask(const Image *image,
01460   ExceptionInfo *exception)
01461 {
01462   assert(image != (const Image *) NULL);
01463   if (image->debug != MagickFalse)
01464     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01465   assert(image->signature == MagickSignature);
01466   if (image->clip_mask == (Image *) NULL)
01467     return((Image *) NULL);
01468   return(CloneImage(image->clip_mask,0,0,MagickTrue,exception));
01469 }
01470 
01471 /*
01472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01473 %                                                                             %
01474 %                                                                             %
01475 %                                                                             %
01476 %   G e t I m a g e E x c e p t i o n                                         %
01477 %                                                                             %
01478 %                                                                             %
01479 %                                                                             %
01480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01481 %
01482 %  GetImageException() traverses an image sequence and returns any
01483 %  error more severe than noted by the exception parameter.
01484 %
01485 %  The format of the GetImageException method is:
01486 %
01487 %      void GetImageException(Image *image,ExceptionInfo *exception)
01488 %
01489 %  A description of each parameter follows:
01490 %
01491 %    o image: Specifies a pointer to a list of one or more images.
01492 %
01493 %    o exception: return the highest severity exception.
01494 %
01495 */
01496 MagickExport void GetImageException(Image *image,ExceptionInfo *exception)
01497 {
01498   register Image
01499     *next;
01500 
01501   assert(image != (Image *) NULL);
01502   assert(image->signature == MagickSignature);
01503   if (image->debug != MagickFalse)
01504     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01505   assert(exception != (ExceptionInfo *) NULL);
01506   assert(exception->signature == MagickSignature);
01507   for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
01508   {
01509     if (next->exception.severity == UndefinedException)
01510       continue;
01511     if (next->exception.severity > exception->severity)
01512       InheritException(exception,&next->exception);
01513     next->exception.severity=UndefinedException;
01514   }
01515 }
01516 
01517 /*
01518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01519 %                                                                             %
01520 %                                                                             %
01521 %                                                                             %
01522 %   G e t I m a g e I n f o                                                   %
01523 %                                                                             %
01524 %                                                                             %
01525 %                                                                             %
01526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01527 %
01528 %  GetImageInfo() initializes image_info to default values.
01529 %
01530 %  The format of the GetImageInfo method is:
01531 %
01532 %      void GetImageInfo(ImageInfo *image_info)
01533 %
01534 %  A description of each parameter follows:
01535 %
01536 %    o image_info: the image info.
01537 %
01538 */
01539 MagickExport void GetImageInfo(ImageInfo *image_info)
01540 {
01541   ExceptionInfo
01542     *exception;
01543 
01544   /*
01545     File and image dimension members.
01546   */
01547   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01548   assert(image_info != (ImageInfo *) NULL);
01549   (void) ResetMagickMemory(image_info,0,sizeof(*image_info));
01550   image_info->adjoin=MagickTrue;
01551   image_info->interlace=NoInterlace;
01552   image_info->channel=DefaultChannels;
01553   image_info->quality=UndefinedCompressionQuality;
01554   image_info->antialias=MagickTrue;
01555   image_info->dither=MagickTrue;
01556   exception=AcquireExceptionInfo();
01557   (void) QueryColorDatabase(BackgroundColor,&image_info->background_color,
01558     exception);
01559   (void) QueryColorDatabase(BorderColor,&image_info->border_color,exception);
01560   (void) QueryColorDatabase(MatteColor,&image_info->matte_color,exception);
01561   (void) QueryColorDatabase(TransparentColor,&image_info->transparent_color,
01562     exception);
01563   exception=DestroyExceptionInfo(exception);
01564   image_info->debug=IsEventLogging();
01565   image_info->signature=MagickSignature;
01566 }
01567 
01568 /*
01569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01570 %                                                                             %
01571 %                                                                             %
01572 %                                                                             %
01573 %   G e t I m a g e I n f o F i l e                                           %
01574 %                                                                             %
01575 %                                                                             %
01576 %                                                                             %
01577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01578 %
01579 %  GetImageInfoFile() returns the image info file member.
01580 %
01581 %  The format of the GetImageInfoFile method is:
01582 %
01583 %      FILE *GetImageInfoFile(const ImageInfo *image_info)
01584 %
01585 %  A description of each parameter follows:
01586 %
01587 %    o image_info: the image info.
01588 %
01589 */
01590 MagickExport FILE *GetImageInfoFile(const ImageInfo *image_info)
01591 {
01592   return(image_info->file);
01593 }
01594 
01595 /*
01596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01597 %                                                                             %
01598 %                                                                             %
01599 %                                                                             %
01600 %   G e t I m a g e M a s k                                                   %
01601 %                                                                             %
01602 %                                                                             %
01603 %                                                                             %
01604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01605 %
01606 %  GetImageMask() returns the mask associated with the image.
01607 %
01608 %  The format of the GetImageMask method is:
01609 %
01610 %      Image *GetImageMask(const Image *image,ExceptionInfo *exception)
01611 %
01612 %  A description of each parameter follows:
01613 %
01614 %    o image: the image.
01615 %
01616 */
01617 MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
01618 {
01619   assert(image != (const Image *) NULL);
01620   if (image->debug != MagickFalse)
01621     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01622   assert(image->signature == MagickSignature);
01623   if (image->mask == (Image *) NULL)
01624     return((Image *) NULL);
01625   return(CloneImage(image->mask,0,0,MagickTrue,exception));
01626 }
01627 
01628 /*
01629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01630 %                                                                             %
01631 %                                                                             %
01632 %                                                                             %
01633 +   G e t I m a g e R e f e r e n c e C o u n t                               %
01634 %                                                                             %
01635 %                                                                             %
01636 %                                                                             %
01637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01638 %
01639 %  GetImageReferenceCount() returns the image reference count.
01640 %
01641 %  The format of the GetReferenceCount method is:
01642 %
01643 %      long GetImageReferenceCount(Image *image)
01644 %
01645 %  A description of each parameter follows:
01646 %
01647 %    o image: the image.
01648 %
01649 */
01650 MagickExport long GetImageReferenceCount(Image *image)
01651 {
01652   long
01653     reference_count;
01654 
01655   assert(image != (Image *) NULL);
01656   assert(image->signature == MagickSignature);
01657   if (image->debug != MagickFalse)
01658     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01659   LockSemaphoreInfo(image->semaphore);
01660   reference_count=image->reference_count;
01661   UnlockSemaphoreInfo(image->semaphore);
01662   return(reference_count);
01663 }
01664 
01665 /*
01666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01667 %                                                                             %
01668 %                                                                             %
01669 %                                                                             %
01670 %   G e t I m a g e V i r t u a l P i x e l M e t h o d                       %
01671 %                                                                             %
01672 %                                                                             %
01673 %                                                                             %
01674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01675 %
01676 %  GetImageVirtualPixelMethod() gets the "virtual pixels" method for the
01677 %  image.  A virtual pixel is any pixel access that is outside the boundaries
01678 %  of the image cache.
01679 %
01680 %  The format of the GetImageVirtualPixelMethod() method is:
01681 %
01682 %      VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
01683 %
01684 %  A description of each parameter follows:
01685 %
01686 %    o image: the image.
01687 %
01688 */
01689 MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
01690 {
01691   assert(image != (Image *) NULL);
01692   assert(image->signature == MagickSignature);
01693   if (image->debug != MagickFalse)
01694     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01695   return(GetPixelCacheVirtualMethod(image));
01696 }
01697 
01698 /*
01699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01700 %                                                                             %
01701 %                                                                             %
01702 %                                                                             %
01703 %  I n t e r p r e t I m a g e F i l e n a m e                                %
01704 %                                                                             %
01705 %                                                                             %
01706 %                                                                             %
01707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01708 %
01709 %  InterpretImageFilename() interprets embedded characters in an image filename.
01710 %  The filename length is returned.
01711 %
01712 %  The format of the InterpretImageFilename method is:
01713 %
01714 %      size_t InterpretImageFilename(const ImageInfo *image_info,
01715 %        Image *image,const char *format,int value,char *filename)
01716 %
01717 %  A description of each parameter follows.
01718 %
01719 %    o image_info: the image info..
01720 %
01721 %    o image: the image.
01722 %
01723 %    o format:  A filename describing the format to use to write the numeric
01724 %      argument. Only the first numeric format identifier is replaced.
01725 %
01726 %    o value:  Numeric value to substitute into format filename.
01727 %
01728 %    o filename:  return the formatted filename in this character buffer.
01729 %
01730 */
01731 MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
01732   Image *image,const char *format,int value,char *filename)
01733 {
01734   char
01735     *q;
01736 
01737   int
01738     c;
01739 
01740   MagickBooleanType
01741     canonical;
01742 
01743   register const char
01744     *p;
01745 
01746   canonical=MagickFalse;
01747   (void) CopyMagickString(filename,format,MaxTextExtent);
01748   for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
01749   {
01750     q=(char *) p+1;
01751     if (*q == '%')
01752       {
01753         p=q+1;
01754         continue;
01755       }
01756     if (*q == '0')
01757       {
01758         long
01759           value;
01760 
01761         value=strtol(q,&q,10);
01762       }
01763     switch (*q)
01764     {
01765       case 'd':
01766       case 'o':
01767       case 'x':
01768       {
01769         q++;
01770         c=(*q);
01771         *q='\0';
01772         (void) FormatMagickString(filename+(p-format),(size_t) (MaxTextExtent-
01773           (p-format)),p,value);
01774         *q=c;
01775         (void) ConcatenateMagickString(filename,q,MaxTextExtent);
01776         canonical=MagickTrue;
01777         if (*(q-1) != '%')
01778           break;
01779         p++;
01780         break;
01781       }
01782       case '[':
01783       {
01784         char
01785           pattern[MaxTextExtent];
01786 
01787         const char
01788           *value;
01789 
01790         long
01791           depth;
01792 
01793         register char
01794           *r;
01795 
01796         register long
01797           i;
01798 
01799         /*
01800           Image option.
01801         */
01802         if (strchr(p,']') == (char *) NULL)
01803           break;
01804         depth=1;
01805         r=q+1;
01806         for (i=0; (i < (MaxTextExtent-1L)) && (*r != '\0'); i++)
01807         {
01808           if (*r == '[')
01809             depth++;
01810           if (*r == ']')
01811             depth--;
01812           if (depth <= 0)
01813             break;
01814           pattern[i]=(*r++);
01815         }
01816         pattern[i]='\0';
01817         if (LocaleNCompare(pattern,"filename:",9) != 0)
01818           break;
01819         value=(const char *) NULL;
01820         if ((image_info != (const ImageInfo *) NULL) &&
01821             (image != (const Image *) NULL))
01822           value=GetMagickProperty(image_info,image,pattern);
01823         else
01824           if (image != (Image *) NULL)
01825             value=GetImageProperty(image,pattern);
01826           else
01827             if (image_info != (ImageInfo *) NULL)
01828               value=GetImageOption(image_info,pattern);
01829         if (value == (const char *) NULL)
01830           break;
01831         q--;
01832         c=(*q);
01833         *q='\0';
01834         (void) CopyMagickString(filename+(p-format),value,(size_t)
01835           (MaxTextExtent-(p-format)));
01836         *q=c;
01837         (void) ConcatenateMagickString(filename,r+1,MaxTextExtent);
01838         canonical=MagickTrue;
01839         if (*(q-1) != '%')
01840           break;
01841         p++;
01842         break;
01843       }
01844       default:
01845         break;
01846     }
01847   }
01848   for (q=filename; *q != '\0'; q++)
01849     if ((*q == '%') && (*(q+1) == '%'))
01850       (void) CopyMagickString(q,q+1,(size_t) (MaxTextExtent-(q-filename)));
01851   if (canonical == MagickFalse)
01852     (void) CopyMagickString(filename,format,MaxTextExtent);
01853   return(strlen(filename));
01854 }
01855 
01856 /*
01857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01858 %                                                                             %
01859 %                                                                             %
01860 %                                                                             %
01861 %   I s H i g h D y n a m i c R a n g e I m a g e                             %
01862 %                                                                             %
01863 %                                                                             %
01864 %                                                                             %
01865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01866 %
01867 %  IsHighDynamicRangeImage() returns MagickTrue if any pixel component is
01868 %  non-integer or exceeds the bounds of the quantum depth (e.g. for Q16
01869 %  0..65535.
01870 %
01871 %  The format of the IsHighDynamicRangeImage method is:
01872 %
01873 %      MagickBooleanType IsHighDynamicRangeImage(const Image *image,
01874 %        ExceptionInfo *exception)
01875 %
01876 %  A description of each parameter follows:
01877 %
01878 %    o image: the image.
01879 %
01880 %    o exception: return any errors or warnings in this structure.
01881 %
01882 */
01883 MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
01884   ExceptionInfo *exception)
01885 {
01886 #if !defined(MAGICKCORE_HDRI_SUPPORT)
01887   (void) image;
01888   (void) exception;
01889   return(MagickFalse);
01890 #else
01891   CacheView
01892     *image_view;
01893 
01894   long
01895     y;
01896 
01897   MagickBooleanType
01898     status;
01899 
01900   MagickPixelPacket
01901     zero;
01902 
01903   assert(image != (Image *) NULL);
01904   assert(image->signature == MagickSignature);
01905   if (image->debug != MagickFalse)
01906     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01907   status=MagickTrue;
01908   GetMagickPixelPacket(image,&zero);
01909   image_view=AcquireCacheView(image);
01910 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01911   #pragma omp parallel for schedule(dynamic,4) shared(status)
01912 #endif
01913   for (y=0; y < (long) image->rows; y++)
01914   {
01915     MagickPixelPacket
01916       pixel;
01917 
01918     register const IndexPacket
01919       *indexes;
01920 
01921     register const PixelPacket
01922       *p;
01923 
01924     register long
01925       x;
01926 
01927     if (status == MagickFalse)
01928       continue;
01929     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
01930     if (p == (const PixelPacket *) NULL)
01931       {
01932         status=MagickFalse;
01933         continue;
01934       }
01935     indexes=GetCacheViewVirtualIndexQueue(image_view);
01936     pixel=zero;
01937     for (x=0; x < (long) image->columns; x++)
01938     {
01939       SetMagickPixelPacket(image,p,indexes+x,&pixel);
01940       if ((pixel.red < 0.0) || (pixel.red > QuantumRange) ||
01941           (pixel.red != (QuantumAny) pixel.red))
01942         break;
01943       if ((pixel.green < 0.0) || (pixel.green > QuantumRange) ||
01944           (pixel.green != (QuantumAny) pixel.green))
01945         break;
01946       if ((pixel.blue < 0.0) || (pixel.blue > QuantumRange) ||
01947           (pixel.blue != (QuantumAny) pixel.blue))
01948         break;
01949       if (pixel.matte != MagickFalse)
01950         {
01951           if ((pixel.opacity < 0.0) || (pixel.opacity > QuantumRange) ||
01952               (pixel.opacity != (QuantumAny) pixel.opacity))
01953             break;
01954         }
01955       if (pixel.colorspace == CMYKColorspace)
01956         {
01957           if ((pixel.index < 0.0) || (pixel.index > QuantumRange) ||
01958               (pixel.index != (QuantumAny) pixel.index))
01959             break;
01960         }
01961       p++;
01962     }
01963     if (x < (long) image->columns)
01964       status=MagickFalse;
01965   }
01966   image_view=DestroyCacheView(image_view);
01967   return(status != MagickFalse ? MagickFalse : MagickTrue);
01968 #endif
01969 }
01970 
01971 /*
01972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01973 %                                                                             %
01974 %                                                                             %
01975 %                                                                             %
01976 %     I s I m a g e O b j e c t                                               %
01977 %                                                                             %
01978 %                                                                             %
01979 %                                                                             %
01980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01981 %
01982 %  IsImageObject() returns MagickTrue if the image sequence contains a valid
01983 %  set of image objects.
01984 %
01985 %  The format of the IsImageObject method is:
01986 %
01987 %      MagickBooleanType IsImageObject(const Image *image)
01988 %
01989 %  A description of each parameter follows:
01990 %
01991 %    o image: the image.
01992 %
01993 */
01994 MagickExport MagickBooleanType IsImageObject(const Image *image)
01995 {
01996   register const Image
01997     *p;
01998 
01999   assert(image != (Image *) NULL);
02000   if (image->debug != MagickFalse)
02001     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02002   for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
02003     if (p->signature != MagickSignature)
02004       return(MagickFalse);
02005   return(MagickTrue);
02006 }
02007 
02008 /*
02009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02010 %                                                                             %
02011 %                                                                             %
02012 %                                                                             %
02013 %     I s T a i n t I m a g e                                                 %
02014 %                                                                             %
02015 %                                                                             %
02016 %                                                                             %
02017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02018 %
02019 %  IsTaintImage() returns MagickTrue any pixel in the image has been altered
02020 %  since it was first constituted.
02021 %
02022 %  The format of the IsTaintImage method is:
02023 %
02024 %      MagickBooleanType IsTaintImage(const Image *image)
02025 %
02026 %  A description of each parameter follows:
02027 %
02028 %    o image: the image.
02029 %
02030 */
02031 MagickExport MagickBooleanType IsTaintImage(const Image *image)
02032 {
02033   char
02034     magick[MaxTextExtent],
02035     filename[MaxTextExtent];
02036 
02037   register const Image
02038     *p;
02039 
02040   assert(image != (Image *) NULL);
02041   if (image->debug != MagickFalse)
02042     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02043   assert(image->signature == MagickSignature);
02044   (void) CopyMagickString(magick,image->magick,MaxTextExtent);
02045   (void) CopyMagickString(filename,image->filename,MaxTextExtent);
02046   for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
02047   {
02048     if (p->taint != MagickFalse)
02049       return(MagickTrue);
02050     if (LocaleCompare(p->magick,magick) != 0)
02051       return(MagickTrue);
02052     if (LocaleCompare(p->filename,filename) != 0)
02053       return(MagickTrue);
02054   }
02055   return(MagickFalse);
02056 }
02057 
02058 /*
02059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02060 %                                                                             %
02061 %                                                                             %
02062 %                                                                             %
02063 %   M o d i f y I m a g e                                                     %
02064 %                                                                             %
02065 %                                                                             %
02066 %                                                                             %
02067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02068 %
02069 %  ModifyImage() ensures that there is only a single reference to the image
02070 %  to be modified, updating the provided image pointer to point to a clone of
02071 %  the original image if necessary.
02072 %
02073 %  The format of the ModifyImage method is:
02074 %
02075 %      MagickBooleanType ModifyImage(Image *image,ExceptionInfo *exception)
02076 %
02077 %  A description of each parameter follows:
02078 %
02079 %    o image: the image.
02080 %
02081 %    o exception: return any errors or warnings in this structure.
02082 %
02083 */
02084 MagickExport MagickBooleanType ModifyImage(Image **image,
02085   ExceptionInfo *exception)
02086 {
02087   Image
02088     *clone_image;
02089 
02090   assert(image != (Image **) NULL);
02091   assert(*image != (Image *) NULL);
02092   assert((*image)->signature == MagickSignature);
02093   if ((*image)->debug != MagickFalse)
02094     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
02095   if (GetImageReferenceCount(*image) <= 1)
02096     return(MagickTrue);
02097   clone_image=CloneImage(*image,0,0,MagickTrue,exception);
02098   LockSemaphoreInfo((*image)->semaphore);
02099   (*image)->reference_count--;
02100   UnlockSemaphoreInfo((*image)->semaphore);
02101   *image=clone_image;
02102   return(MagickTrue);
02103 }
02104 
02105 /*
02106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02107 %                                                                             %
02108 %                                                                             %
02109 %                                                                             %
02110 %   N e w M a g i c k I m a g e                                               %
02111 %                                                                             %
02112 %                                                                             %
02113 %                                                                             %
02114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02115 %
02116 %  NewMagickImage() creates a blank image canvas of the specified size and
02117 %  background color.
02118 %
02119 %  The format of the NewMagickImage method is:
02120 %
02121 %      Image *NewMagickImage(const ImageInfo *image_info,
02122 %        const unsigned long width,const unsigned long height,
02123 %        const MagickPixelPacket *background)
02124 %
02125 %  A description of each parameter follows:
02126 %
02127 %    o image: the image.
02128 %
02129 %    o width: the image width.
02130 %
02131 %    o height: the image height.
02132 %
02133 %    o background: the image color.
02134 %
02135 */
02136 MagickExport Image *NewMagickImage(const ImageInfo *image_info,
02137   const unsigned long width,const unsigned long height,
02138   const MagickPixelPacket *background)
02139 {
02140   CacheView
02141     *image_view;
02142 
02143   ExceptionInfo
02144     *exception;
02145 
02146   Image
02147     *image;
02148 
02149   long
02150     y;
02151 
02152   MagickBooleanType
02153     status;
02154 
02155   assert(image_info != (const ImageInfo *) NULL);
02156   if (image_info->debug != MagickFalse)
02157     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02158   assert(image_info->signature == MagickSignature);
02159   assert(background != (const MagickPixelPacket *) NULL);
02160   image=AcquireImage(image_info);
02161   image->columns=width;
02162   image->rows=height;
02163   image->colorspace=background->colorspace;
02164   image->matte=background->matte;
02165   image->fuzz=background->fuzz;
02166   image->depth=background->depth;
02167   status=MagickTrue;
02168   exception=(&image->exception);
02169   image_view=AcquireCacheView(image);
02170 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02171   #pragma omp parallel for schedule(dynamic,4) shared(status)
02172 #endif
02173   for (y=0; y < (long) image->rows; y++)
02174   {
02175     register IndexPacket
02176       *restrict indexes;
02177 
02178     register long
02179       x;
02180 
02181     register PixelPacket
02182       *restrict q;
02183 
02184     if (status == MagickFalse)
02185       continue;
02186     q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
02187     if (q == (PixelPacket *) NULL)
02188       {
02189         status=MagickFalse;
02190         continue;
02191       }
02192     indexes=GetCacheViewAuthenticIndexQueue(image_view);
02193     for (x=0; x < (long) image->columns; x++)
02194     {
02195       SetPixelPacket(image,background,q,indexes+x);
02196       q++;
02197     }
02198     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02199       status=MagickFalse;
02200   }
02201   image_view=DestroyCacheView(image_view);
02202   if (status == MagickFalse)
02203     image=DestroyImage(image);
02204   return(image);
02205 }
02206 
02207 /*
02208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02209 %                                                                             %
02210 %                                                                             %
02211 %                                                                             %
02212 %   R e f e r e n c e I m a g e                                               %
02213 %                                                                             %
02214 %                                                                             %
02215 %                                                                             %
02216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02217 %
02218 %  ReferenceImage() increments the reference count associated with an image
02219 %  returning a pointer to the image.
02220 %
02221 %  The format of the ReferenceImage method is:
02222 %
02223 %      Image *ReferenceImage(Image *image)
02224 %
02225 %  A description of each parameter follows:
02226 %
02227 %    o image: the image.
02228 %
02229 */
02230 MagickExport Image *ReferenceImage(Image *image)
02231 {
02232   assert(image != (Image *) NULL);
02233   if (image->debug != MagickFalse)
02234     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02235   assert(image->signature == MagickSignature);
02236   LockSemaphoreInfo(image->semaphore);
02237   image->reference_count++;
02238   UnlockSemaphoreInfo(image->semaphore);
02239   return(image);
02240 }
02241 
02242 /*
02243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02244 %                                                                             %
02245 %                                                                             %
02246 %                                                                             %
02247 %   R e s e t I m a g e P a g e                                               %
02248 %                                                                             %
02249 %                                                                             %
02250 %                                                                             %
02251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02252 %
02253 %  ResetImagePage() resets the image page canvas and position.
02254 %
02255 %  The format of the ResetImagePage method is:
02256 %
02257 %      MagickBooleanType ResetImagePage(Image *image,const char *page)
02258 %
02259 %  A description of each parameter follows:
02260 %
02261 %    o image: the image.
02262 %
02263 %    o page: the relative page specification.
02264 %
02265 */
02266 MagickExport MagickBooleanType ResetImagePage(Image *image,const char *page)
02267 {
02268   MagickStatusType
02269     flags;
02270 
02271   RectangleInfo
02272     geometry;
02273 
02274   assert(image != (Image *) NULL);
02275   assert(image->signature == MagickSignature);
02276   if (image->debug != MagickFalse)
02277     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02278   flags=ParseAbsoluteGeometry(page,&geometry);
02279   if ((flags & WidthValue) != 0)
02280     {
02281       if ((flags & HeightValue) == 0)
02282         geometry.height=geometry.width;
02283       image->page.width=geometry.width;
02284       image->page.height=geometry.height;
02285     }
02286   if ((flags & AspectValue) != 0)
02287     {
02288       if ((flags & XValue) != 0)
02289         image->page.x+=geometry.x;
02290       if ((flags & YValue) != 0)
02291         image->page.y+=geometry.y;
02292     }
02293   else
02294     {
02295       if ((flags & XValue) != 0)
02296         {
02297           image->page.x=geometry.x;
02298           if ((image->page.width == 0) && (geometry.x > 0))
02299             image->page.width=image->columns+geometry.x;
02300         }
02301       if ((flags & YValue) != 0)
02302         {
02303           image->page.y=geometry.y;
02304           if ((image->page.height == 0) && (geometry.y > 0))
02305             image->page.height=image->rows+geometry.y;
02306         }
02307     }
02308   return(MagickTrue);
02309 }
02310 
02311 /*
02312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02313 %                                                                             %
02314 %                                                                             %
02315 %                                                                             %
02316 %     S e p a r a t e I m a g e C h a n n e l                                 %
02317 %                                                                             %
02318 %                                                                             %
02319 %                                                                             %
02320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02321 %
02322 %  SeparateImageChannel() separates a channel from the image and returns it as
02323 %  a grayscale image.  A channel is a particular color component of each pixel
02324 %  in the image.
02325 %
02326 %  The format of the SeparateImageChannel method is:
02327 %
02328 %      MagickBooleanType SeparateImageChannel(Image *image,
02329 %        const ChannelType channel)
02330 %
02331 %  A description of each parameter follows:
02332 %
02333 %    o image: the image.
02334 %
02335 %    o channel: Identify which channel to extract: RedChannel, GreenChannel,
02336 %      BlueChannel, OpacityChannel, CyanChannel, MagentaChannel,
02337 %      YellowChannel, or BlackChannel.
02338 %
02339 */
02340 MagickExport MagickBooleanType SeparateImageChannel(Image *image,
02341   const ChannelType channel)
02342 {
02343 #define SeparateImageTag  "Separate/Image"
02344 
02345   CacheView
02346     *image_view;
02347 
02348   ExceptionInfo
02349     *exception;
02350 
02351   long
02352     progress,
02353     y;
02354 
02355   MagickBooleanType
02356     status;
02357 
02358   assert(image != (Image *) NULL);
02359   assert(image->signature == MagickSignature);
02360   if (image->debug != MagickFalse)
02361     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02362   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02363     return(MagickFalse);
02364   /*
02365     Separate image channels.
02366   */
02367   status=MagickTrue;
02368   if (channel == GrayChannels)
02369     image->matte=MagickTrue;
02370   progress=0;
02371   exception=(&image->exception);
02372   image_view=AcquireCacheView(image);
02373 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02374   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
02375 #endif
02376   for (y=0; y < (long) image->rows; y++)
02377   {
02378     register IndexPacket
02379       *restrict indexes;
02380 
02381     register long
02382       x;
02383 
02384     register PixelPacket
02385       *restrict q;
02386 
02387     if (status == MagickFalse)
02388       continue;
02389     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
02390     if (q == (PixelPacket *) NULL)
02391       {
02392         status=MagickFalse;
02393         continue;
02394       }
02395     indexes=GetCacheViewAuthenticIndexQueue(image_view);
02396     switch (channel)
02397     {
02398       case RedChannel:
02399       {
02400         for (x=0; x < (long) image->columns; x++)
02401         {
02402           q->green=q->red;
02403           q->blue=q->red;
02404           q++;
02405         }
02406         break;
02407       }
02408       case GreenChannel:
02409       {
02410         for (x=0; x < (long) image->columns; x++)
02411         {
02412           q->red=q->green;
02413           q->blue=q->green;
02414           q++;
02415         }
02416         break;
02417       }
02418       case BlueChannel:
02419       {
02420         for (x=0; x < (long) image->columns; x++)
02421         {
02422           q->red=q->blue;
02423           q->green=q->blue;
02424           q++;
02425         }
02426         break;
02427       }
02428       case OpacityChannel:
02429       {
02430         for (x=0; x < (long) image->columns; x++)
02431         {
02432           q->red=q->opacity;
02433           q->green=q->opacity;
02434           q->blue=q->opacity;
02435           q++;
02436         }
02437         break;
02438       }
02439       case BlackChannel:
02440       {
02441         if ((image->storage_class != PseudoClass) &&
02442             (image->colorspace != CMYKColorspace))
02443           break;
02444         for (x=0; x < (long) image->columns; x++)
02445         {
02446           q->red=indexes[x];
02447           q->green=indexes[x];
02448           q->blue=indexes[x];
02449           q++;
02450         }
02451         break;
02452       }
02453       case TrueAlphaChannel:
02454       {
02455         for (x=0; x < (long) image->columns; x++)
02456         {
02457           q->red=(Quantum) GetAlphaPixelComponent(q);
02458           q->green=(Quantum) GetAlphaPixelComponent(q);
02459           q->blue=(Quantum) GetAlphaPixelComponent(q);
02460           q++;
02461         }
02462         break;
02463       }
02464       case GrayChannels:
02465       {
02466         for (x=0; x < (long) image->columns; x++)
02467         {
02468           q->opacity=(Quantum) (QuantumRange-PixelIntensityToQuantum(q));
02469           q++;
02470         }
02471         break;
02472       }
02473       default:
02474         break;
02475     }
02476     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02477       status=MagickFalse;
02478     if (image->progress_monitor != (MagickProgressMonitor) NULL)
02479       {
02480         MagickBooleanType
02481           proceed;
02482 
02483 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02484         #pragma omp critical (MagickCore_SeparateImageChannel)
02485 #endif
02486         proceed=SetImageProgress(image,SeparateImageTag,progress++,image->rows);
02487         if (proceed == MagickFalse)
02488           status=MagickFalse;
02489       }
02490   }
02491   image_view=DestroyCacheView(image_view);
02492   if (channel != GrayChannels)
02493     image->matte=MagickFalse;
02494   (void) SetImageColorspace(image,RGBColorspace);
02495   return(status);
02496 }
02497 
02498 /*
02499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02500 %                                                                             %
02501 %                                                                             %
02502 %                                                                             %
02503 %     S e p a r a t e I m a g e s                                             %
02504 %                                                                             %
02505 %                                                                             %
02506 %                                                                             %
02507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02508 %
02509 %  SeparateImages() returns a separate grayscale image for each channel
02510 %  specified.
02511 %
02512 %  The format of the SeparateImages method is:
02513 %
02514 %      MagickBooleanType SeparateImages(const Image *image,
02515 %        const ChannelType channel,ExceptionInfo *exception)
02516 %
02517 %  A description of each parameter follows:
02518 %
02519 %    o image: the image.
02520 %
02521 %    o channel: Identify which channels to extract: RedChannel, GreenChannel,
02522 %      BlueChannel, OpacityChannel, CyanChannel, MagentaChannel,
02523 %      YellowChannel, or BlackChannel.
02524 %
02525 %    o exception: return any errors or warnings in this structure.
02526 %
02527 */
02528 MagickExport Image *SeparateImages(const Image *image,const ChannelType channel,
02529   ExceptionInfo *exception)
02530 {
02531   Image
02532     *images,
02533     *separate_image;
02534 
02535   assert(image != (Image *) NULL);
02536   assert(image->signature == MagickSignature);
02537   if (image->debug != MagickFalse)
02538     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02539   images=NewImageList();
02540   if ((channel & RedChannel) != 0)
02541     {
02542       separate_image=CloneImage(image,0,0,MagickTrue,exception);
02543       (void) SeparateImageChannel(separate_image,RedChannel);
02544       AppendImageToList(&images,separate_image);
02545     }
02546   if ((channel & GreenChannel) != 0)
02547     {
02548       separate_image=CloneImage(image,0,0,MagickTrue,exception);
02549       (void) SeparateImageChannel(separate_image,GreenChannel);
02550       AppendImageToList(&images,separate_image);
02551     }
02552   if ((channel & BlueChannel) != 0)
02553     {
02554       separate_image=CloneImage(image,0,0,MagickTrue,exception);
02555       (void) SeparateImageChannel(separate_image,BlueChannel);
02556       AppendImageToList(&images,separate_image);
02557     }
02558   if (((channel & BlackChannel) != 0) && (image->colorspace == CMYKColorspace))
02559     {
02560       separate_image=CloneImage(image,0,0,MagickTrue,exception);
02561       (void) SeparateImageChannel(separate_image,BlackChannel);
02562       AppendImageToList(&images,separate_image);
02563     }
02564   if ((channel & OpacityChannel) != 0)
02565     {
02566       separate_image=CloneImage(image,0,0,MagickTrue,exception);
02567       (void) SeparateImageChannel(separate_image,OpacityChannel);
02568       AppendImageToList(&images,separate_image);
02569     }
02570   return(images);
02571 }
02572 
02573 /*
02574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02575 %                                                                             %
02576 %                                                                             %
02577 %                                                                             %
02578 %   S e t I m a g e A l p h a C h a n n e l                                   %
02579 %                                                                             %
02580 %                                                                             %
02581 %                                                                             %
02582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02583 %
02584 %  SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
02585 %  channel.
02586 %
02587 %  The format of the SetImageAlphaChannel method is:
02588 %
02589 %      MagickBooleanType SetImageAlphaChannel(Image *image,
02590 %        const AlphaChannelType alpha_type)
02591 %
02592 %  A description of each parameter follows:
02593 %
02594 %    o image: the image.
02595 %
02596 %    o alpha_type:  The alpha channel type: ActivateAlphaChannel,
02597 %      CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
02598 %      OpaqueAlphaChannel, ResetAlphaChannel, SetAlphaChannel,
02599 %      ShapeAlphaChannel, and TransparentAlphaChannel.
02600 %
02601 */
02602 MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
02603   const AlphaChannelType alpha_type)
02604 {
02605   MagickBooleanType
02606     status;
02607 
02608   assert(image != (Image *) NULL);
02609   if (image->debug != MagickFalse)
02610     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02611   assert(image->signature == MagickSignature);
02612   status=MagickFalse;
02613   switch (alpha_type)
02614   {
02615     case ActivateAlphaChannel:
02616     {
02617       image->matte=MagickTrue;
02618       break;
02619     }
02620     case BackgroundAlphaChannel:
02621     {
02622       CacheView
02623         *image_view;
02624 
02625       ExceptionInfo
02626         *exception;
02627 
02628       IndexPacket
02629         index;
02630 
02631       long
02632         y;
02633 
02634       MagickBooleanType
02635         status;
02636 
02637       MagickPixelPacket
02638         background;
02639 
02640       PixelPacket
02641         pixel;
02642 
02643       /*
02644         Set transparent pixels to background color.
02645       */
02646       if (image->matte == MagickFalse)
02647         break;
02648       if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02649         break;
02650       GetMagickPixelPacket(image,&background);
02651       SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
02652         NULL,&background);
02653       if (image->colorspace == CMYKColorspace)
02654         ConvertRGBToCMYK(&background);
02655       index=0;
02656       SetPixelPacket(image,&background,&pixel,&index);
02657       status=MagickTrue;
02658       exception=(&image->exception);
02659       image_view=AcquireCacheView(image);
02660       #if defined(MAGICKCORE_OPENMP_SUPPORT)
02661         #pragma omp parallel for schedule(dynamic,4) shared(status)
02662       #endif
02663       for (y=0; y < (long) image->rows; y++)
02664       {
02665         register IndexPacket
02666           *restrict indexes;
02667 
02668         register long
02669           x;
02670 
02671         register PixelPacket
02672           *restrict q;
02673 
02674         if (status == MagickFalse)
02675           continue;
02676         q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
02677           exception);
02678         if (q == (PixelPacket *) NULL)
02679           {
02680             status=MagickFalse;
02681             continue;
02682           }
02683         for (x=0; x < (long) image->columns; x++)
02684         {
02685           if (q->opacity == TransparentOpacity)
02686             {
02687               q->red=pixel.red;
02688               q->green=pixel.green;
02689               q->blue=pixel.blue;
02690             }
02691           q++;
02692         }
02693         if (image->colorspace == CMYKColorspace)
02694           {
02695             indexes=GetCacheViewAuthenticIndexQueue(image_view);
02696             for (x=0; x < (long) image->columns; x++)
02697               indexes[x]=index;
02698           }
02699         if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02700           status=MagickFalse;
02701       }
02702       image_view=DestroyCacheView(image_view);
02703       return(status);
02704     }
02705     case DeactivateAlphaChannel:
02706     {
02707       image->matte=MagickFalse;
02708       break;
02709     }
02710     case ShapeAlphaChannel:
02711     case CopyAlphaChannel:
02712     {
02713       /*
02714         Special usage case for SeparateImageChannel(): copy grayscale color to
02715         the alpha channel.
02716       */
02717       status=SeparateImageChannel(image,GrayChannels);
02718       image->matte=MagickTrue; /* make sure transparency is now on! */
02719       if (alpha_type == ShapeAlphaChannel)
02720         {
02721           MagickPixelPacket
02722             background;
02723 
02724           /*
02725             Reset all color channels to background color.
02726           */
02727           GetMagickPixelPacket(image,&background);
02728           SetMagickPixelPacket(image,&(image->background_color),(IndexPacket *)
02729             NULL,&background);
02730           (void) LevelColorsImage(image,&background,&background,MagickTrue);
02731         }
02732       break;
02733     }
02734     case ExtractAlphaChannel:
02735     {
02736       status=SeparateImageChannel(image,TrueAlphaChannel);
02737       image->matte=MagickFalse;
02738       break;
02739     }
02740     case ResetAlphaChannel:
02741     case OpaqueAlphaChannel:
02742     {
02743       status=SetImageOpacity(image,OpaqueOpacity);
02744       image->matte=MagickTrue;
02745       break;
02746     }
02747     case TransparentAlphaChannel:
02748     {
02749       status=SetImageOpacity(image,TransparentOpacity);
02750       image->matte=MagickTrue;
02751       break;
02752     }
02753     case SetAlphaChannel:
02754     {
02755       if (image->matte == MagickFalse)
02756         {
02757           status=SetImageOpacity(image,OpaqueOpacity);
02758           image->matte=MagickTrue;
02759         }
02760       break;
02761     }
02762     case UndefinedAlphaChannel:
02763       break;
02764   }
02765   return(status);
02766 }
02767 
02768 /*
02769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02770 %                                                                             %
02771 %                                                                             %
02772 %                                                                             %
02773 %   S e t I m a g e B a c k g r o u n d C o l o r                             %
02774 %                                                                             %
02775 %                                                                             %
02776 %                                                                             %
02777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02778 %
02779 %  SetImageBackgroundColor() initializes the image pixels to the image
02780 %  background color.  The background color is defined by the background_color
02781 %  member of the image structure.
02782 %
02783 %  The format of the SetImage method is:
02784 %
02785 %      MagickBooleanType SetImageBackgroundColor(Image *image)
02786 %
02787 %  A description of each parameter follows:
02788 %
02789 %    o image: the image.
02790 %
02791 */
02792 MagickExport MagickBooleanType SetImageBackgroundColor(Image *image)
02793 {
02794   CacheView
02795     *image_view;
02796 
02797   ExceptionInfo
02798     *exception;
02799 
02800   IndexPacket
02801     index;
02802 
02803   long
02804     y;
02805 
02806   MagickBooleanType
02807     status;
02808 
02809   MagickPixelPacket
02810     background;
02811 
02812   PixelPacket
02813     pixel;
02814 
02815   assert(image != (Image *) NULL);
02816   if (image->debug != MagickFalse)
02817     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02818   assert(image->signature == MagickSignature);
02819   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02820     return(MagickFalse);
02821   if (image->background_color.opacity != OpaqueOpacity)
02822     image->matte=MagickTrue;
02823   GetMagickPixelPacket(image,&background);
02824   SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
02825     NULL,&background);
02826   if (image->colorspace == CMYKColorspace)
02827     ConvertRGBToCMYK(&background);
02828   index=0;
02829   SetPixelPacket(image,&background,&pixel,&index);
02830   /*
02831     Set image background color.
02832   */
02833   status=MagickTrue;
02834   exception=(&image->exception);
02835   image_view=AcquireCacheView(image);
02836 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02837   #pragma omp parallel for schedule(dynamic,4) shared(status)
02838 #endif
02839   for (y=0; y < (long) image->rows; y++)
02840   {
02841     register IndexPacket
02842       *restrict indexes;
02843 
02844     register long
02845       x;
02846 
02847     register PixelPacket
02848       *restrict q;
02849 
02850     if (status == MagickFalse)
02851       continue;
02852     q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
02853     if (q == (PixelPacket *) NULL)
02854       {
02855         status=MagickFalse;
02856         continue;
02857       }
02858     for (x=0; x < (long) image->columns; x++)
02859       *q++=pixel;
02860     if (image->colorspace == CMYKColorspace)
02861       {
02862         indexes=GetCacheViewAuthenticIndexQueue(image_view);
02863         for (x=0; x < (long) image->columns; x++)
02864           indexes[x]=index;
02865       }
02866     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02867       status=MagickFalse;
02868   }
02869   image_view=DestroyCacheView(image_view);
02870   return(status);
02871 }
02872 
02873 /*
02874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02875 %                                                                             %
02876 %                                                                             %
02877 %                                                                             %
02878 %   S e t I m a g e S t o r a g e C l a s s                                   %
02879 %                                                                             %
02880 %                                                                             %
02881 %                                                                             %
02882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02883 %
02884 %  SetImageStorageClass() sets the image class: DirectClass for true color
02885 %  images or PseudoClass for colormapped images.
02886 %
02887 %  The format of the SetImageStorageClass method is:
02888 %
02889 %      MagickBooleanType SetImageStorageClass(Image *image,
02890 %        const ClassType storage_class)
02891 %
02892 %  A description of each parameter follows:
02893 %
02894 %    o image: the image.
02895 %
02896 %    o storage_class:  The image class.
02897 %
02898 */
02899 MagickExport MagickBooleanType SetImageStorageClass(Image *image,
02900   const ClassType storage_class)
02901 {
02902   Cache
02903     cache;
02904 
02905   if (image->storage_class == storage_class)
02906     return(MagickTrue);
02907   image->storage_class=storage_class;
02908   cache=GetImagePixelCache(image,MagickTrue,&image->exception);
02909   return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
02910 }
02911 
02912 /*
02913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02914 %                                                                             %
02915 %                                                                             %
02916 %                                                                             %
02917 %   S e t I m a g e C l i p M a s k                                           %
02918 %                                                                             %
02919 %                                                                             %
02920 %                                                                             %
02921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02922 %
02923 %  SetImageClipMask() associates a clip path with the image.  The clip path
02924 %  must be the same dimensions as the image.  Set any pixel component of
02925 %  the clip path to TransparentOpacity to prevent that corresponding image
02926 %  pixel component from being updated when SyncAuthenticPixels() is applied.
02927 %
02928 %  The format of the SetImageClipMask method is:
02929 %
02930 %      MagickBooleanType SetImageClipMask(Image *image,const Image *clip_mask)
02931 %
02932 %  A description of each parameter follows:
02933 %
02934 %    o image: the image.
02935 %
02936 %    o clip_mask: the image clip path.
02937 %
02938 */
02939 MagickExport MagickBooleanType SetImageClipMask(Image *image,
02940   const Image *clip_mask)
02941 {
02942   assert(image != (Image *) NULL);
02943   if (image->debug != MagickFalse)
02944     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02945   assert(image->signature == MagickSignature);
02946   if (clip_mask != (const Image *) NULL)
02947     if ((clip_mask->columns != image->columns) ||
02948         (clip_mask->rows != image->rows))
02949       ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
02950   if (image->clip_mask != (Image *) NULL)
02951     image->clip_mask=DestroyImage(image->clip_mask);
02952   image->clip_mask=NewImageList();
02953   if (clip_mask == (Image *) NULL)
02954     return(MagickTrue);
02955   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02956     return(MagickFalse);
02957   image->clip_mask=CloneImage(clip_mask,0,0,MagickTrue,&image->exception);
02958   if (image->clip_mask == (Image *) NULL)
02959     return(MagickFalse);
02960   return(MagickTrue);
02961 }
02962 
02963 /*
02964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02965 %                                                                             %
02966 %                                                                             %
02967 %                                                                             %
02968 %   S e t I m a g e E x t e n t                                               %
02969 %                                                                             %
02970 %                                                                             %
02971 %                                                                             %
02972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02973 %
02974 %  SetImageExtent() sets the image size (i.e. columns & rows).
02975 %
02976 %  The format of the SetImageExtent method is:
02977 %
02978 %      MagickBooleanType SetImageExtent(Image *image,
02979 %        const unsigned long columns,const unsigned long rows)
02980 %
02981 %  A description of each parameter follows:
02982 %
02983 %    o image: the image.
02984 %
02985 %    o columns:  The image width in pixels.
02986 %
02987 %    o rows:  The image height in pixels.
02988 %
02989 */
02990 MagickExport MagickBooleanType SetImageExtent(Image *image,
02991   const unsigned long columns,const unsigned long rows)
02992 {
02993   Cache
02994     cache;
02995 
02996   if ((columns != 0) && (rows != 0))
02997     {
02998       image->columns=columns;
02999       image->rows=rows;
03000     }
03001   cache=GetImagePixelCache(image,MagickTrue,&image->exception);
03002   return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
03003 }
03004 
03005 /*
03006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03007 %                                                                             %
03008 %                                                                             %
03009 %                                                                             %
03010 +   S e t I m a g e I n f o                                                   %
03011 %                                                                             %
03012 %                                                                             %
03013 %                                                                             %
03014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03015 %
03016 %  SetImageInfo() initializes the `magick' field of the ImageInfo structure.
03017 %  It is set to a type of image format based on the prefix or suffix of the
03018 %  filename.  For example, `ps:image' returns PS indicating a Postscript image.
03019 %  JPEG is returned for this filename: `image.jpg'.  The filename prefix has
03020 %  precendence over the suffix.  Use an optional index enclosed in brackets
03021 %  after a file name to specify a desired scene of a multi-resolution image
03022 %  format like Photo CD (e.g. img0001.pcd[4]).  A True (non-zero) return value
03023 %  indicates success.
03024 %
03025 %  The format of the SetImageInfo method is:
03026 %
03027 %      MagickBooleanType SetImageInfo(ImageInfo *image_info,
03028 %        const unsigned int frames,ExceptionInfo *exception)
03029 %
03030 %  A description of each parameter follows:
03031 %
03032 %    o image_info: the image info.
03033 %
03034 %    o frames: the number of images you intend to write.
03035 %
03036 %    o exception: return any errors or warnings in this structure.
03037 %
03038 */
03039 MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info,
03040   const unsigned int frames,ExceptionInfo *exception)
03041 {
03042   char
03043     extension[MaxTextExtent],
03044     filename[MaxTextExtent],
03045     magic[MaxTextExtent],
03046     *q,
03047     subimage[MaxTextExtent];
03048 
03049   const MagicInfo
03050     *magic_info;
03051 
03052   const MagickInfo
03053     *magick_info;
03054 
03055   ExceptionInfo
03056     *sans_exception;
03057 
03058   Image
03059     *image;
03060 
03061   MagickBooleanType
03062     status;
03063 
03064   register const char
03065     *p;
03066 
03067   ssize_t
03068     count;
03069 
03070   unsigned char
03071     magick[2*MaxTextExtent];
03072 
03073   /*
03074     Look for 'image.format' in filename.
03075   */
03076   assert(image_info != (ImageInfo *) NULL);
03077   assert(image_info->signature == MagickSignature);
03078   if (image_info->debug != MagickFalse)
03079     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03080       image_info->filename);
03081   *subimage='\0';
03082   if (frames == 0)
03083     {
03084       GetPathComponent(image_info->filename,SubimagePath,subimage);
03085       if (*subimage != '\0')
03086         {
03087           /*
03088             Look for scene specification (e.g. img0001.pcd[4]).
03089           */
03090           if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse)
03091             {
03092               if (IsGeometry(subimage) != MagickFalse)
03093                 (void) CloneString(&image_info->extract,subimage);
03094             }
03095           else
03096             {
03097               unsigned long
03098                 first,
03099                 last;
03100 
03101               (void) CloneString(&image_info->scenes,subimage);
03102               image_info->scene=StringToUnsignedLong(image_info->scenes);
03103               image_info->number_scenes=image_info->scene;
03104               p=image_info->scenes;
03105               for (q=(char *) image_info->scenes; *q != '\0'; p++)
03106               {
03107                 while ((isspace((int) ((unsigned char) *p)) != 0) ||
03108                        (*p == ','))
03109                   p++;
03110                 first=(unsigned long) strtol(p,&q,10);
03111                 last=first;
03112                 while (isspace((int) ((unsigned char) *q)) != 0)
03113                   q++;
03114                 if (*q == '-')
03115                   last=(unsigned long) strtol(q+1,&q,10);
03116                 if (first > last)
03117                   Swap(first,last);
03118                 if (first < image_info->scene)
03119                   image_info->scene=first;
03120                 if (last > image_info->number_scenes)
03121                   image_info->number_scenes=last;
03122                 p=q;
03123               }
03124               image_info->number_scenes-=image_info->scene-1;
03125               image_info->subimage=image_info->scene;
03126               image_info->subrange=image_info->number_scenes;
03127             }
03128         }
03129     }
03130   *extension='\0';
03131   GetPathComponent(image_info->filename,ExtensionPath,extension);
03132 #if defined(MAGICKCORE_ZLIB_DELEGATE)
03133   if (*extension != '\0')
03134     if ((LocaleCompare(extension,"gz") == 0) ||
03135         (LocaleCompare(extension,"Z") == 0) ||
03136         (LocaleCompare(extension,"wmz") == 0))
03137       {
03138         char
03139           path[MaxTextExtent];
03140 
03141         (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
03142         path[strlen(path)-strlen(extension)-1]='\0';
03143         GetPathComponent(path,ExtensionPath,extension);
03144       }
03145 #endif
03146 #if defined(MAGICKCORE_BZLIB_DELEGATE)
03147   if (*extension != '\0')
03148     if (LocaleCompare(extension,"bz2") == 0)
03149       {
03150         char
03151           path[MaxTextExtent];
03152 
03153         (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
03154         path[strlen(path)-strlen(extension)-1]='\0';
03155         GetPathComponent(path,ExtensionPath,extension);
03156       }
03157 #endif
03158   image_info->affirm=MagickFalse;
03159   sans_exception=AcquireExceptionInfo();
03160   if (*extension != '\0')
03161     {
03162       MagickFormatType
03163         format_type;
03164 
03165       register long
03166         i;
03167 
03168       static const char
03169         *format_type_formats[] =
03170         {
03171           "AUTOTRACE",
03172           "BROWSE",
03173           "DCRAW",
03174           "EDIT",
03175           "EPHEMERAL",
03176           "LAUNCH",
03177           "MPEG:DECODE",
03178           "MPEG:ENCODE",
03179           "PRINT",
03180           "PS:ALPHA",
03181           "PS:CMYK",
03182           "PS:COLOR",
03183           "PS:GRAY",
03184           "PS:MONO",
03185           "SCAN",
03186           "SHOW",
03187           "WIN",
03188           (char *) NULL
03189         };
03190 
03191       /*
03192         User specified image format.
03193       */
03194       (void) CopyMagickString(magic,extension,MaxTextExtent);
03195       LocaleUpper(magic);
03196       /*
03197         Look for explicit image formats.
03198       */
03199       format_type=UndefinedFormatType;
03200       i=0;
03201       while ((format_type == UndefinedFormatType) &&
03202              (format_type_formats[i] != (char *) NULL))
03203       {
03204         if ((*magic == *format_type_formats[i]) &&
03205             (LocaleCompare(magic,format_type_formats[i]) == 0))
03206           format_type=ExplicitFormatType;
03207         i++;
03208       }
03209       magick_info=GetMagickInfo(magic,sans_exception);
03210       if ((magick_info != (const MagickInfo *) NULL) &&
03211           (magick_info->format_type != UndefinedFormatType))
03212         format_type=magick_info->format_type;
03213       if (format_type == UndefinedFormatType)
03214         (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03215       else
03216         if (format_type == ExplicitFormatType)
03217           {
03218             image_info->affirm=MagickTrue;
03219             (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03220           }
03221       if (LocaleCompare(magic,"RGB") == 0)
03222         image_info->affirm=MagickFalse;  /* maybe SGI disguised as RGB */
03223     }
03224   /*
03225     Look for explicit 'format:image' in filename.
03226   */
03227   *magic='\0';
03228   GetPathComponent(image_info->filename,MagickPath,magic);
03229   if (*magic == '\0')
03230     (void) CopyMagickString(magic,image_info->magick,MaxTextExtent);
03231   else
03232     {
03233       /*
03234         User specified image format.
03235       */
03236       LocaleUpper(magic);
03237       if (IsMagickConflict(magic) == MagickFalse)
03238         {
03239           (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03240           if (LocaleCompare(magic,"EPHEMERAL") != 0)
03241             image_info->affirm=MagickTrue;
03242           else
03243             image_info->temporary=MagickTrue;
03244         }
03245     }
03246   magick_info=GetMagickInfo(magic,sans_exception);
03247   sans_exception=DestroyExceptionInfo(sans_exception);
03248   if ((magick_info == (const MagickInfo *) NULL) ||
03249       (GetMagickEndianSupport(magick_info) == MagickFalse))
03250     image_info->endian=UndefinedEndian;
03251   GetPathComponent(image_info->filename,CanonicalPath,filename);
03252   (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
03253   if ((image_info->adjoin != MagickFalse) && (frames > 1))
03254     {
03255       /*
03256         Test for multiple image support (e.g. image%02d.png).
03257       */
03258       (void) InterpretImageFilename(image_info,(Image *) NULL,
03259         image_info->filename,(int) image_info->scene,filename);
03260       if ((LocaleCompare(filename,image_info->filename) != 0) &&
03261           (strchr(filename,'%') == (char *) NULL))
03262         image_info->adjoin=MagickFalse;
03263     }
03264   if ((image_info->adjoin != MagickFalse) && (frames > 0))
03265     {
03266       /*
03267         Some image formats do not support multiple frames per file.
03268       */
03269       magick_info=GetMagickInfo(magic,exception);
03270       if (magick_info != (const MagickInfo *) NULL)
03271         if (GetMagickAdjoin(magick_info) == MagickFalse)
03272           image_info->adjoin=MagickFalse;
03273     }
03274   if (image_info->affirm != MagickFalse)
03275     return(MagickTrue);
03276   if (frames == 0)
03277     {
03278       /*
03279         Determine the image format from the first few bytes of the file.
03280       */
03281       image=AcquireImage(image_info);
03282       (void) CopyMagickString(image->filename,image_info->filename,
03283         MaxTextExtent);
03284       status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
03285       if (status == MagickFalse)
03286         {
03287           image=DestroyImage(image);
03288           return(MagickFalse);
03289         }
03290       if ((IsBlobSeekable(image) == MagickFalse) ||
03291           (IsBlobExempt(image) != MagickFalse))
03292         {
03293           /*
03294             Copy standard input or pipe to temporary file.
03295           */
03296           *filename='\0';
03297           status=ImageToFile(image,filename,exception);
03298           (void) CloseBlob(image);
03299           if (status == MagickFalse)
03300             {
03301               image=DestroyImage(image);
03302               return(MagickFalse);
03303             }
03304           SetImageInfoFile(image_info,(FILE *) NULL);
03305           (void) CopyMagickString(image->filename,filename,MaxTextExtent);
03306           status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
03307           if (status == MagickFalse)
03308             {
03309               image=DestroyImage(image);
03310               return(MagickFalse);
03311             }
03312           (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
03313           image_info->temporary=MagickTrue;
03314         }
03315       (void) ResetMagickMemory(magick,0,sizeof(magick));
03316       count=ReadBlob(image,2*MaxTextExtent,magick);
03317       (void) CloseBlob(image);
03318       image=DestroyImage(image);
03319       /*
03320         Check magic.xml configuration file.
03321       */
03322       sans_exception=AcquireExceptionInfo();
03323       magic_info=GetMagicInfo(magick,(size_t) count,sans_exception);
03324       if ((magic_info != (const MagicInfo *) NULL) &&
03325           (GetMagicName(magic_info) != (char *) NULL))
03326         {
03327           (void) CopyMagickString(image_info->magick,GetMagicName(magic_info),
03328             MaxTextExtent);
03329           magick_info=GetMagickInfo(image_info->magick,sans_exception);
03330           if ((magick_info == (const MagickInfo *) NULL) ||
03331               (GetMagickEndianSupport(magick_info) == MagickFalse))
03332             image_info->endian=UndefinedEndian;
03333           sans_exception=DestroyExceptionInfo(sans_exception);
03334           return(MagickTrue);
03335         }
03336       magick_info=GetMagickInfo(image_info->magick,sans_exception);
03337       if ((magick_info == (const MagickInfo *) NULL) ||
03338           (GetMagickEndianSupport(magick_info) == MagickFalse))
03339         image_info->endian=UndefinedEndian;
03340       sans_exception=DestroyExceptionInfo(sans_exception);
03341     }
03342   return(MagickTrue);
03343 }
03344 
03345 /*
03346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03347 %                                                                             %
03348 %                                                                             %
03349 %                                                                             %
03350 %   S e t I m a g e I n f o B l o b                                           %
03351 %                                                                             %
03352 %                                                                             %
03353 %                                                                             %
03354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03355 %
03356 %  SetImageInfoBlob() sets the image info blob member.
03357 %
03358 %  The format of the SetImageInfoBlob method is:
03359 %
03360 %      void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
03361 %        const size_t length)
03362 %
03363 %  A description of each parameter follows:
03364 %
03365 %    o image_info: the image info.
03366 %
03367 %    o blob: the blob.
03368 %
03369 %    o length: the blob length.
03370 %
03371 */
03372 MagickExport void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
03373   const size_t length)
03374 {
03375   assert(image_info != (ImageInfo *) NULL);
03376   assert(image_info->signature == MagickSignature);
03377   if (image_info->debug != MagickFalse)
03378     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03379       image_info->filename);
03380   image_info->blob=(void *) blob;
03381   image_info->length=length;
03382 }
03383 
03384 /*
03385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03386 %                                                                             %
03387 %                                                                             %
03388 %                                                                             %
03389 %   S e t I m a g e I n f o F i l e                                           %
03390 %                                                                             %
03391 %                                                                             %
03392 %                                                                             %
03393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03394 %
03395 %  SetImageInfoFile() sets the image info file member.
03396 %
03397 %  The format of the SetImageInfoFile method is:
03398 %
03399 %      void SetImageInfoFile(ImageInfo *image_info,FILE *file)
03400 %
03401 %  A description of each parameter follows:
03402 %
03403 %    o image_info: the image info.
03404 %
03405 %    o file: the file.
03406 %
03407 */
03408 MagickExport void SetImageInfoFile(ImageInfo *image_info,FILE *file)
03409 {
03410   assert(image_info != (ImageInfo *) NULL);
03411   assert(image_info->signature == MagickSignature);
03412   if (image_info->debug != MagickFalse)
03413     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03414       image_info->filename);
03415   image_info->file=file;
03416 }
03417 
03418 /*
03419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03420 %                                                                             %
03421 %                                                                             %
03422 %                                                                             %
03423 %   S e t I m a g e M a s k                                                   %
03424 %                                                                             %
03425 %                                                                             %
03426 %                                                                             %
03427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03428 %
03429 %  SetImageMask() associates a mask with the image.  The mask must be the same
03430 %  dimensions as the image.
03431 %
03432 %  The format of the SetImageMask method is:
03433 %
03434 %      MagickBooleanType SetImageMask(Image *image,const Image *mask)
03435 %
03436 %  A description of each parameter follows:
03437 %
03438 %    o image: the image.
03439 %
03440 %    o mask: the image mask.
03441 %
03442 */
03443 MagickExport MagickBooleanType SetImageMask(Image *image,
03444   const Image *mask)
03445 {
03446   assert(image != (Image *) NULL);
03447   if (image->debug != MagickFalse)
03448     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03449   assert(image->signature == MagickSignature);
03450   if (mask != (const Image *) NULL)
03451     if ((mask->columns != image->columns) || (mask->rows != image->rows))
03452       ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
03453   if (image->mask != (Image *) NULL)
03454     image->mask=DestroyImage(image->mask);
03455   image->mask=NewImageList();
03456   if (mask == (Image *) NULL)
03457     return(MagickTrue);
03458   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
03459     return(MagickFalse);
03460   image->mask=CloneImage(mask,0,0,MagickTrue,&image->exception);
03461   if (image->mask == (Image *) NULL)
03462     return(MagickFalse);
03463   return(MagickTrue);
03464 }
03465 
03466 /*
03467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03468 %                                                                             %
03469 %                                                                             %
03470 %                                                                             %
03471 %     S e t I m a g e O p a c i t y                                           %
03472 %                                                                             %
03473 %                                                                             %
03474 %                                                                             %
03475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03476 %
03477 %  SetImageOpacity() sets the opacity levels of the image.
03478 %
03479 %  The format of the SetImageOpacity method is:
03480 %
03481 %      MagickBooleanType SetImageOpacity(Image *image,const Quantum opacity)
03482 %
03483 %  A description of each parameter follows:
03484 %
03485 %    o image: the image.
03486 %
03487 %    o opacity: the level of transparency: 0 is fully opaque and QuantumRange is
03488 %      fully transparent.
03489 %
03490 */
03491 MagickExport MagickBooleanType SetImageOpacity(Image *image,
03492   const Quantum opacity)
03493 {
03494   CacheView
03495     *image_view;
03496 
03497   ExceptionInfo
03498     *exception;
03499 
03500   long
03501     y;
03502 
03503   MagickBooleanType
03504     status;
03505 
03506   assert(image != (Image *) NULL);
03507   if (image->debug != MagickFalse)
03508     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03509   assert(image->signature == MagickSignature);
03510   image->matte=opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
03511   status=MagickTrue;
03512   exception=(&image->exception);
03513   image_view=AcquireCacheView(image);
03514 #if defined(MAGICKCORE_OPENMP_SUPPORT)
03515   #pragma omp parallel for schedule(dynamic,4) shared(status)
03516 #endif
03517   for (y=0; y < (long) image->rows; y++)
03518   {
03519     register long
03520       x;
03521 
03522     register PixelPacket
03523       *restrict q;
03524 
03525     if (status == MagickFalse)
03526       continue;
03527     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
03528     if (q == (PixelPacket *) NULL)
03529       {
03530         status=MagickFalse;
03531         continue;
03532       }
03533     for (x=0; x < (long) image->columns; x++)
03534     {
03535       SetOpacityPixelComponent(q,opacity);
03536       q++;
03537     }
03538     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
03539       status=MagickFalse;
03540   }
03541   image_view=DestroyCacheView(image_view);
03542   return(status);
03543 }
03544 
03545 /*
03546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03547 %                                                                             %
03548 %                                                                             %
03549 %                                                                             %
03550 %   S e t I m a g e T y p e                                                   %
03551 %                                                                             %
03552 %                                                                             %
03553 %                                                                             %
03554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03555 %
03556 %  SetImageType() sets the type of image.  Choose from these types:
03557 %
03558 %        Bilevel        Grayscale       GrayscaleMatte
03559 %        Palette        PaletteMatte    TrueColor
03560 %        TrueColorMatte ColorSeparation ColorSeparationMatte
03561 %        OptimizeType
03562 %
03563 %  The format of the SetImageType method is:
03564 %
03565 %      MagickBooleanType SetImageType(Image *image,const ImageType type)
03566 %
03567 %  A description of each parameter follows:
03568 %
03569 %    o image: the image.
03570 %
03571 %    o type: Image type.
03572 %
03573 */
03574 MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type)
03575 {
03576   const char
03577     *artifact;
03578 
03579   ImageInfo
03580     *image_info;
03581 
03582   MagickBooleanType
03583     status;
03584 
03585   QuantizeInfo
03586     *quantize_info;
03587 
03588   assert(image != (Image *) NULL);
03589   if (image->debug != MagickFalse)
03590     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03591   assert(image->signature == MagickSignature);
03592   status=MagickTrue;
03593   image_info=AcquireImageInfo();
03594   image_info->dither=image->dither;
03595   artifact=GetImageArtifact(image,"dither");
03596   if (artifact != (const char *) NULL)
03597     (void) SetImageOption(image_info,"dither",artifact);
03598   switch (type)
03599   {
03600     case BilevelType:
03601     {
03602       if (IsGrayImage(image,&image->exception) == MagickFalse)
03603         status=TransformImageColorspace(image,GRAYColorspace);
03604       if (IsMonochromeImage(image,&image->exception) == MagickFalse)
03605         {
03606           quantize_info=AcquireQuantizeInfo(image_info);
03607           quantize_info->number_colors=2;
03608           quantize_info->colorspace=GRAYColorspace;
03609           status=QuantizeImage(quantize_info,image);
03610           quantize_info=DestroyQuantizeInfo(quantize_info);
03611         }
03612       image->matte=MagickFalse;
03613       break;
03614     }
03615     case GrayscaleType:
03616     {
03617       if (IsGrayImage(image,&image->exception) == MagickFalse)
03618         status=TransformImageColorspace(image,GRAYColorspace);
03619       image->matte=MagickFalse;
03620       break;
03621     }
03622     case GrayscaleMatteType:
03623     {
03624       if (IsGrayImage(image,&image->exception) == MagickFalse)
03625         status=TransformImageColorspace(image,GRAYColorspace);
03626       if (image->matte == MagickFalse)
03627         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03628       break;
03629     }
03630     case PaletteType:
03631     {
03632       if (image->colorspace != RGBColorspace)
03633         status=TransformImageColorspace(image,RGBColorspace);
03634       if ((image->storage_class == DirectClass) || (image->colors > 256))
03635         {
03636           quantize_info=AcquireQuantizeInfo(image_info);
03637           quantize_info->number_colors=256;
03638           status=QuantizeImage(quantize_info,image);
03639           quantize_info=DestroyQuantizeInfo(quantize_info);
03640         }
03641       image->matte=MagickFalse;
03642       break;
03643     }
03644     case PaletteBilevelMatteType:
03645     {
03646       if (image->colorspace != RGBColorspace)
03647         status=TransformImageColorspace(image,RGBColorspace);
03648       if (image->matte == MagickFalse)
03649         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03650       (void) BilevelImageChannel(image,AlphaChannel,(double) QuantumRange/2.0);
03651       quantize_info=AcquireQuantizeInfo(image_info);
03652       status=QuantizeImage(quantize_info,image);
03653       quantize_info=DestroyQuantizeInfo(quantize_info);
03654       break;
03655     }
03656     case PaletteMatteType:
03657     {
03658       if (image->colorspace != RGBColorspace)
03659         status=TransformImageColorspace(image,RGBColorspace);
03660       if (image->matte == MagickFalse)
03661         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03662       quantize_info=AcquireQuantizeInfo(image_info);
03663       quantize_info->colorspace=TransparentColorspace;
03664       status=QuantizeImage(quantize_info,image);
03665       quantize_info=DestroyQuantizeInfo(quantize_info);
03666       break;
03667     }
03668     case TrueColorType:
03669     {
03670       if (image->colorspace != RGBColorspace)
03671         status=TransformImageColorspace(image,RGBColorspace);
03672       if (image->storage_class != DirectClass)
03673         status=SetImageStorageClass(image,DirectClass);
03674       image->matte=MagickFalse;
03675       break;
03676     }
03677     case TrueColorMatteType:
03678     {
03679       if (image->colorspace != RGBColorspace)
03680         status=TransformImageColorspace(image,RGBColorspace);
03681       if (image->storage_class != DirectClass)
03682         status=SetImageStorageClass(image,DirectClass);
03683       if (image->matte == MagickFalse)
03684         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03685       break;
03686     }
03687     case ColorSeparationType:
03688     {
03689       if (image->colorspace != CMYKColorspace)
03690         {
03691           if (image->colorspace != RGBColorspace)
03692             status=TransformImageColorspace(image,RGBColorspace);
03693           status=TransformImageColorspace(image,CMYKColorspace);
03694         }
03695       if (image->storage_class != DirectClass)
03696         status=SetImageStorageClass(image,DirectClass);
03697       image->matte=MagickFalse;
03698       break;
03699     }
03700     case ColorSeparationMatteType:
03701     {
03702       if (image->colorspace != CMYKColorspace)
03703         {
03704           if (image->colorspace != RGBColorspace)
03705             status=TransformImageColorspace(image,RGBColorspace);
03706           status=TransformImageColorspace(image,CMYKColorspace);
03707         }
03708       if (image->storage_class != DirectClass)
03709         status=SetImageStorageClass(image,DirectClass);
03710       if (image->matte == MagickFalse)
03711         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03712       break;
03713     }
03714     case OptimizeType:
03715     case UndefinedType:
03716       break;
03717   }
03718   image->type=type;
03719   image_info=DestroyImageInfo(image_info);
03720   return(status);
03721 }
03722 
03723 /*
03724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03725 %                                                                             %
03726 %                                                                             %
03727 %                                                                             %
03728 %   S e t I m a g e V i r t u a l P i x e l M e t h o d                       %
03729 %                                                                             %
03730 %                                                                             %
03731 %                                                                             %
03732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03733 %
03734 %  SetImageVirtualPixelMethod() sets the "virtual pixels" method for the
03735 %  image and returns the previous setting.  A virtual pixel is any pixel access
03736 %  that is outside the boundaries of the image cache.
03737 %
03738 %  The format of the SetImageVirtualPixelMethod() method is:
03739 %
03740 %      VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
03741 %        const VirtualPixelMethod virtual_pixel_method)
03742 %
03743 %  A description of each parameter follows:
03744 %
03745 %    o image: the image.
03746 %
03747 %    o virtual_pixel_method: choose the type of virtual pixel.
03748 %
03749 */
03750 MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
03751   const VirtualPixelMethod virtual_pixel_method)
03752 {
03753   assert(image != (const Image *) NULL);
03754   assert(image->signature == MagickSignature);
03755   if (image->debug != MagickFalse)
03756     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
03757   return(SetPixelCacheVirtualMethod(image,virtual_pixel_method));
03758 }
03759 
03760 /*
03761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03762 %                                                                             %
03763 %                                                                             %
03764 %                                                                             %
03765 %   S t r i p I m a g e                                                       %
03766 %                                                                             %
03767 %                                                                             %
03768 %                                                                             %
03769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03770 %
03771 %  StripImage() strips an image of all profiles and comments.
03772 %
03773 %  The format of the StripImage method is:
03774 %
03775 %      MagickBooleanType StripImage(Image *image)
03776 %
03777 %  A description of each parameter follows:
03778 %
03779 %    o image: the image.
03780 %
03781 */
03782 MagickExport MagickBooleanType StripImage(Image *image)
03783 {
03784   assert(image != (Image *) NULL);
03785   if (image->debug != MagickFalse)
03786     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03787   DestroyImageProfiles(image);
03788   (void) DeleteImageProperty(image,"comment");
03789   return(MagickTrue);
03790 }
03791 
03792 /*
03793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03794 %                                                                             %
03795 %                                                                             %
03796 %                                                                             %
03797 +   S y n c I m a g e                                                         %
03798 %                                                                             %
03799 %                                                                             %
03800 %                                                                             %
03801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03802 %
03803 %  SyncImage() initializes the red, green, and blue intensities of each pixel
03804 %  as defined by the colormap index.
03805 %
03806 %  The format of the SyncImage method is:
03807 %
03808 %      MagickBooleanType SyncImage(Image *image)
03809 %
03810 %  A description of each parameter follows:
03811 %
03812 %    o image: the image.
03813 %
03814 */
03815 
03816 static inline IndexPacket PushColormapIndex(Image *image,
03817   const unsigned long index,Magick