2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % IIIII M M AAA GGGG EEEEE %
8 % I M M M AAAAA G GG EEE %
10 % IIIII M M A A GGGG EEEEE %
13 % MagickCore Image Methods %
20 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "magick/studio.h"
44 #include "magick/animate.h"
45 #include "magick/artifact.h"
46 #include "magick/blob.h"
47 #include "magick/blob-private.h"
48 #include "magick/cache.h"
49 #include "magick/cache-private.h"
50 #include "magick/cache-view.h"
51 #include "magick/client.h"
52 #include "magick/color.h"
53 #include "magick/color-private.h"
54 #include "magick/colorspace.h"
55 #include "magick/colorspace-private.h"
56 #include "magick/composite.h"
57 #include "magick/composite-private.h"
58 #include "magick/compress.h"
59 #include "magick/constitute.h"
60 #include "magick/deprecate.h"
61 #include "magick/display.h"
62 #include "magick/draw.h"
63 #include "magick/enhance.h"
64 #include "magick/exception.h"
65 #include "magick/exception-private.h"
66 #include "magick/gem.h"
67 #include "magick/geometry.h"
68 #include "magick/list.h"
69 #include "magick/image-private.h"
70 #include "magick/magic.h"
71 #include "magick/magick.h"
72 #include "magick/memory_.h"
73 #include "magick/module.h"
74 #include "magick/monitor.h"
75 #include "magick/monitor-private.h"
76 #include "magick/option.h"
77 #include "magick/paint.h"
78 #include "magick/pixel-private.h"
79 #include "magick/profile.h"
80 #include "magick/property.h"
81 #include "magick/quantize.h"
82 #include "magick/random_.h"
83 #include "magick/segment.h"
84 #include "magick/semaphore.h"
85 #include "magick/signature-private.h"
86 #include "magick/statistic.h"
87 #include "magick/string_.h"
88 #include "magick/thread-private.h"
89 #include "magick/threshold.h"
90 #include "magick/timer.h"
91 #include "magick/utility.h"
92 #include "magick/version.h"
93 #include "magick/xwindow-private.h"
99 BackgroundColor[] = "#ffffff", /* white */
100 BorderColor[] = "#dfdfdf", /* gray */
101 DefaultTileFrame[] = "15x15+3+3",
102 DefaultTileGeometry[] = "120x120+4+3>",
103 DefaultTileLabel[] = "%f\n%G\n%b",
104 ForegroundColor[] = "#000", /* black */
105 LoadImageTag[] = "Load/Image",
106 LoadImagesTag[] = "Load/Images",
107 MatteColor[] = "#bdbdbd", /* gray */
108 PSDensityGeometry[] = "72.0x72.0",
109 PSPageGeometry[] = "612x792",
110 SaveImageTag[] = "Save/Image",
111 SaveImagesTag[] = "Save/Images",
112 TransparentColor[] = "#00000000"; /* transparent black */
115 DefaultResolution = 72.0;
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 % A c q u i r e I m a g e %
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % AcquireImage() returns a pointer to an image structure initialized to
131 % The format of the AcquireImage method is:
133 % Image *AcquireImage(const ImageInfo *image_info)
135 % A description of each parameter follows:
137 % o image_info: Many of the image default values are set from this
138 % structure. For example, filename, compression, depth, background color,
142 MagickExport Image *AcquireImage(const ImageInfo *image_info)
151 Allocate image structure.
153 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
154 image=(Image *) AcquireMagickMemory(sizeof(*image));
155 if (image == (Image *) NULL)
156 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
157 (void) ResetMagickMemory(image,0,sizeof(*image));
159 Initialize Image structure.
161 (void) CopyMagickString(image->magick,"MIFF",MaxTextExtent);
162 image->storage_class=DirectClass;
163 image->depth=MAGICKCORE_QUANTUM_DEPTH;
164 image->colorspace=RGBColorspace;
165 image->interlace=NoInterlace;
166 image->ticks_per_second=UndefinedTicksPerSecond;
167 image->compose=OverCompositeOp;
169 GetExceptionInfo(&image->exception);
170 (void) QueryColorDatabase(BackgroundColor,&image->background_color,
172 (void) QueryColorDatabase(BorderColor,&image->border_color,&image->exception);
173 (void) QueryColorDatabase(MatteColor,&image->matte_color,&image->exception);
174 (void) QueryColorDatabase(TransparentColor,&image->transparent_color,
176 image->x_resolution=DefaultResolution;
177 image->y_resolution=DefaultResolution;
178 image->units=PixelsPerInchResolution;
179 GetTimerInfo(&image->timer);
180 image->cache=AcquirePixelCache(0);
181 image->blob=CloneBlobInfo((BlobInfo *) NULL);
182 image->debug=IsEventLogging();
183 image->reference_count=1;
184 image->semaphore=AllocateSemaphoreInfo();
185 image->signature=MagickSignature;
186 if (image_info == (ImageInfo *) NULL)
191 SetBlobExempt(image,image_info->file != (FILE *) NULL ? MagickTrue :
193 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
194 (void) CopyMagickString(image->magick_filename,image_info->filename,
196 (void) CopyMagickString(image->magick,image_info->magick,MaxTextExtent);
197 if (image_info->size != (char *) NULL)
199 (void) ParseAbsoluteGeometry(image_info->size,&image->extract_info);
200 image->columns=image->extract_info.width;
201 image->rows=image->extract_info.height;
202 image->offset=image->extract_info.x;
203 image->extract_info.x=0;
204 image->extract_info.y=0;
206 if (image_info->extract != (char *) NULL)
211 flags=ParseAbsoluteGeometry(image_info->extract,&geometry);
212 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
214 image->extract_info=geometry;
215 Swap(image->columns,image->extract_info.width);
216 Swap(image->rows,image->extract_info.height);
219 image->compression=image_info->compression;
220 image->quality=image_info->quality;
221 image->endian=image_info->endian;
222 image->interlace=image_info->interlace;
223 image->units=image_info->units;
224 if (image_info->density != (char *) NULL)
229 flags=ParseGeometry(image_info->density,&geometry_info);
230 image->x_resolution=geometry_info.rho;
231 image->y_resolution=geometry_info.sigma;
232 if ((flags & SigmaValue) == 0)
233 image->y_resolution=image->x_resolution;
235 if (image_info->page != (char *) NULL)
240 image->page=image->extract_info;
241 geometry=GetPageGeometry(image_info->page);
242 (void) ParseAbsoluteGeometry(geometry,&image->page);
243 geometry=DestroyString(geometry);
245 if (image_info->depth != 0)
246 image->depth=image_info->depth;
247 image->dither=image_info->dither;
248 image->background_color=image_info->background_color;
249 image->border_color=image_info->border_color;
250 image->matte_color=image_info->matte_color;
251 image->transparent_color=image_info->transparent_color;
252 image->progress_monitor=image_info->progress_monitor;
253 image->client_data=image_info->client_data;
254 if (image_info->cache != (void *) NULL)
255 ClonePixelCacheMethods(image->cache,image_info->cache);
256 (void) SetImageVirtualPixelMethod(image,image_info->virtual_pixel_method);
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 % A c q u i r e I m a g e C o l o r m a p %
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 % AcquireImageColormap() allocates an image colormap and initializes
272 % it to a linear gray colorspace. If the image already has a colormap,
273 % it is replaced. AcquireImageColormap() returns MagickTrue if successful,
274 % otherwise MagickFalse if there is not enough memory.
276 % The format of the AcquireImageColormap method is:
278 % MagickBooleanType AcquireImageColormap(Image *image,
279 % const unsigned long colors)
281 % A description of each parameter follows:
283 % o image: the image.
285 % o colors: the number of colors in the image colormap.
289 static inline unsigned long MagickMax(const unsigned long x,
290 const unsigned long y)
297 static inline unsigned long MagickMin(const unsigned long x,
298 const unsigned long y)
305 MagickExport MagickBooleanType AcquireImageColormap(Image *image,
306 const unsigned long colors)
315 Allocate image colormap.
317 assert(image != (Image *) NULL);
318 assert(image->signature == MagickSignature);
319 if (image->debug != MagickFalse)
320 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
321 image->colors=MagickMin(colors,MaxColormapSize);
322 length=(size_t) colors;
323 if (image->colormap == (PixelPacket *) NULL)
324 image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
325 sizeof(*image->colormap));
327 image->colormap=(PixelPacket *) ResizeQuantumMemory(image->colormap,length,
328 sizeof(*image->colormap));
329 if (image->colormap == (PixelPacket *) NULL)
330 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
332 for (i=0; i < (long) image->colors; i++)
337 pixel=(unsigned long) (i*(QuantumRange/MagickMax(colors-1,1)));
338 image->colormap[i].red=(Quantum) pixel;
339 image->colormap[i].green=(Quantum) pixel;
340 image->colormap[i].blue=(Quantum) pixel;
341 image->colormap[i].opacity=OpaqueOpacity;
343 return(SetImageStorageClass(image,PseudoClass));
347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 % A c q u i r e I m a g e I n f o %
355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357 % AcquireImageInfo() allocates the ImageInfo structure.
359 % The format of the AcquireImageInfo method is:
361 % ImageInfo *AcquireImageInfo(void)
364 MagickExport ImageInfo *AcquireImageInfo(void)
369 image_info=(ImageInfo *) AcquireMagickMemory(sizeof(*image_info));
370 if (image_info == (ImageInfo *) NULL)
371 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
372 GetImageInfo(image_info);
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 % A c q u i r e N e x t I m a g e %
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 % AcquireNextImage() initializes the next image in a sequence to
388 % default values. The next member of image points to the newly allocated
389 % image. If there is a memory shortage, next is assigned NULL.
391 % The format of the AcquireNextImage method is:
393 % void AcquireNextImage(const ImageInfo *image_info,Image *image)
395 % A description of each parameter follows:
397 % o image_info: Many of the image default values are set from this
398 % structure. For example, filename, compression, depth, background color,
401 % o image: the image.
404 MagickExport void AcquireNextImage(const ImageInfo *image_info,Image *image)
407 Allocate image structure.
409 assert(image != (Image *) NULL);
410 assert(image->signature == MagickSignature);
411 if (image->debug != MagickFalse)
412 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
413 image->next=AcquireImage(image_info);
414 if (GetNextImageInList(image) == (Image *) NULL)
416 (void) CopyMagickString(GetNextImageInList(image)->filename,image->filename,
418 if (image_info != (ImageInfo *) NULL)
419 (void) CopyMagickString(GetNextImageInList(image)->filename,
420 image_info->filename,MaxTextExtent);
421 DestroyBlob(GetNextImageInList(image));
422 image->next->blob=ReferenceBlob(image->blob);
423 image->next->endian=image->endian;
424 image->next->scene=image->scene+1;
425 image->next->previous=image;
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 % A p p e n d I m a g e s %
437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 % AppendImages() takes all images from the current image pointer to the end
440 % of the image list and appends them to each other top-to-bottom if the
441 % stack parameter is true, otherwise left-to-right.
443 % The current gravity setting now effects how the image is justified in the
446 % The format of the AppendImages method is:
448 % Image *AppendImages(const Image *image,const MagickBooleanType stack,
449 % ExceptionInfo *exception)
451 % A description of each parameter follows:
453 % o image: the image sequence.
455 % o stack: A value other than 0 stacks the images top-to-bottom.
457 % o exception: return any errors or warnings in this structure.
460 MagickExport Image *AppendImages(const Image *image,
461 const MagickBooleanType stack,ExceptionInfo *exception)
463 #define AppendImageTag "Append/Image"
495 Ensure the image have the same column width.
497 assert(image != (Image *) NULL);
498 assert(image->signature == MagickSignature);
499 if (image->debug != MagickFalse)
500 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
501 assert(exception != (ExceptionInfo *) NULL);
502 assert(exception->signature == MagickSignature);
505 width=image->columns;
507 next=GetNextImageInList(image);
508 for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
510 if (next->matte != MagickFalse)
513 if (stack != MagickFalse)
515 if (next->columns > width)
520 width+=next->columns;
521 if (next->rows > height)
525 Initialize append next attributes.
527 append_image=CloneImage(image,width,height,MagickTrue,exception);
528 if (append_image == (Image *) NULL)
529 return((Image *) NULL);
530 if (SetImageStorageClass(append_image,DirectClass) == MagickFalse)
532 InheritException(exception,&append_image->exception);
533 append_image=DestroyImage(append_image);
534 return((Image *) NULL);
536 append_image->matte=matte;
537 (void) SetImageBackgroundColor(append_image);
541 append_view=AcquireCacheView(append_image);
542 for (n=0; n < (long) number_images; n++)
544 SetGeometry(append_image,&geometry);
545 GravityAdjustGeometry(image->columns,image->rows,image->gravity,&geometry);
546 if (stack != MagickFalse)
547 x_offset-=geometry.x;
549 y_offset-=geometry.y;
550 image_view=AcquireCacheView(image);
551 #if defined(MAGICKCORE_OPENMP_SUPPORT)
552 #pragma omp parallel for schedule(dynamic,4) shared(status)
554 for (y=0; y < (long) image->rows; y++)
559 register const IndexPacket
562 register const PixelPacket
566 *__restrict append_indexes;
574 if (status == MagickFalse)
576 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
577 q=QueueCacheViewAuthenticPixels(append_view,x_offset,y+y_offset,
578 image->columns,1,exception);
579 if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
584 indexes=GetCacheViewVirtualIndexQueue(image_view);
585 append_indexes=GetCacheViewAuthenticIndexQueue(append_view);
586 for (x=0; x < (long) image->columns; x++)
591 q->opacity=OpaqueOpacity;
592 if (image->matte != MagickFalse)
593 q->opacity=p->opacity;
594 if (image->colorspace == CMYKColorspace)
595 append_indexes[x]=indexes[x];
599 sync=SyncCacheViewAuthenticPixels(append_view,exception);
600 if (sync == MagickFalse)
603 image_view=DestroyCacheView(image_view);
604 proceed=SetImageProgress(image,AppendImageTag,n,number_images);
605 if (proceed == MagickFalse)
607 if (stack == MagickFalse)
609 x_offset+=image->columns;
615 y_offset+=image->rows;
617 image=GetNextImageInList(image);
619 append_view=DestroyCacheView(append_view);
620 if (status == MagickFalse)
621 append_image=DestroyImage(append_image);
622 return(append_image);
626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630 % A v e r a g e I m a g e s %
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 % AverageImages() takes a set of images and averages them together. Each
637 % image in the set must have the same width and height. AverageImages()
638 % returns a single image with each corresponding pixel component of each
639 % image averaged. On failure, a NULL image is returned and exception
640 % describes the reason for the failure.
642 % The format of the AverageImages method is:
644 % Image *AverageImages(Image *image,ExceptionInfo *exception)
646 % A description of each parameter follows:
648 % o image: the image sequence.
650 % o exception: return any errors or warnings in this structure.
654 static MagickPixelPacket **DestroyPixelThreadSet(MagickPixelPacket **pixels)
659 assert(pixels != (MagickPixelPacket **) NULL);
660 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
661 if (pixels[i] != (MagickPixelPacket *) NULL)
662 pixels[i]=(MagickPixelPacket *) RelinquishMagickMemory(pixels[i]);
663 pixels=(MagickPixelPacket **) RelinquishAlignedMemory(pixels);
667 static MagickPixelPacket **AcquirePixelThreadSet(const Image *image)
679 number_threads=GetOpenMPMaximumThreads();
680 pixels=(MagickPixelPacket **) AcquireAlignedMemory(number_threads,
682 if (pixels == (MagickPixelPacket **) NULL)
683 return((MagickPixelPacket **) NULL);
684 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
685 for (i=0; i < (long) number_threads; i++)
687 pixels[i]=(MagickPixelPacket *) AcquireQuantumMemory(image->columns,
689 if (pixels[i] == (MagickPixelPacket *) NULL)
690 return(DestroyPixelThreadSet(pixels));
691 for (j=0; j < (long) image->columns; j++)
692 GetMagickPixelPacket(image,&pixels[i][j]);
697 MagickExport Image *AverageImages(const Image *image,ExceptionInfo *exception)
699 #define AverageImageTag "Average/Image"
725 Ensure the image are the same size.
727 assert(image != (Image *) NULL);
728 assert(image->signature == MagickSignature);
729 if (image->debug != MagickFalse)
730 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
731 assert(exception != (ExceptionInfo *) NULL);
732 assert(exception->signature == MagickSignature);
733 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
734 if ((next->columns != image->columns) || (next->rows != image->rows))
735 ThrowImageException(OptionError,"ImageWidthsOrHeightsDiffer");
737 Initialize average next attributes.
739 average_image=CloneImage(image,image->columns,image->rows,MagickTrue,
741 if (average_image == (Image *) NULL)
742 return((Image *) NULL);
743 if (SetImageStorageClass(average_image,DirectClass) == MagickFalse)
745 InheritException(exception,&average_image->exception);
746 average_image=DestroyImage(average_image);
747 return((Image *) NULL);
749 average_pixels=AcquirePixelThreadSet(image);
750 if (average_pixels == (MagickPixelPacket **) NULL)
752 average_image=DestroyImage(average_image);
753 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
756 Average image pixels.
760 GetMagickPixelPacket(image,&zero);
761 number_images=GetImageListLength(image);
762 average_view=AcquireCacheView(average_image);
763 #if defined(MAGICKCORE_OPENMP_SUPPORT)
764 #pragma omp parallel for schedule(dynamic) shared(progress,status)
766 for (y=0; y < (long) average_image->rows; y++)
778 *__restrict average_indexes;
784 register MagickPixelPacket
790 if (status == MagickFalse)
792 q=QueueCacheViewAuthenticPixels(average_view,0,y,average_image->columns,1,
794 if (q == (PixelPacket *) NULL)
799 average_indexes=GetCacheViewAuthenticIndexQueue(average_view);
801 average_pixel=average_pixels[GetOpenMPThreadId()];
802 for (x=0; x < (long) average_image->columns; x++)
803 average_pixel[x]=zero;
805 for (i=0; i < (long) number_images; i++)
807 register const IndexPacket
810 register const PixelPacket
813 image_view=AcquireCacheView(next);
814 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
815 if (p == (const PixelPacket *) NULL)
817 image_view=DestroyCacheView(image_view);
820 indexes=GetCacheViewVirtualIndexQueue(image_view);
821 for (x=0; x < (long) next->columns; x++)
823 SetMagickPixelPacket(next,p,indexes+x,&pixel);
824 average_pixel[x].red+=QuantumScale*pixel.red;
825 average_pixel[x].green+=QuantumScale*pixel.green;
826 average_pixel[x].blue+=QuantumScale*pixel.blue;
827 average_pixel[x].opacity+=QuantumScale*pixel.opacity;
828 if (average_image->colorspace == CMYKColorspace)
829 average_pixel[x].index+=QuantumScale*pixel.index;
832 image_view=DestroyCacheView(image_view);
833 next=GetNextImageInList(next);
835 for (x=0; x < (long) average_image->columns; x++)
837 average_pixel[x].red=(MagickRealType) (QuantumRange*
838 average_pixel[x].red/number_images);
839 average_pixel[x].green=(MagickRealType) (QuantumRange*
840 average_pixel[x].green/number_images);
841 average_pixel[x].blue=(MagickRealType) (QuantumRange*
842 average_pixel[x].blue/number_images);
843 average_pixel[x].opacity=(MagickRealType) (QuantumRange*
844 average_pixel[x].opacity/number_images);
845 if (average_image->colorspace == CMYKColorspace)
846 average_pixel[x].index=(MagickRealType) (QuantumRange*
847 average_pixel[x].index/number_images);
848 SetPixelPacket(average_image,&average_pixel[x],q,average_indexes+x);
851 if (SyncCacheViewAuthenticPixels(average_view,exception) == MagickFalse)
853 if (image->progress_monitor != (MagickProgressMonitor) NULL)
858 #if defined(MAGICKCORE_OPENMP_SUPPORT)
859 #pragma omp critical (MagickCore_AverageImages)
861 proceed=SetImageProgress(image,AverageImageTag,progress++,
862 average_image->rows);
863 if (proceed == MagickFalse)
867 average_view=DestroyCacheView(average_view);
868 average_pixels=DestroyPixelThreadSet(average_pixels);
869 if (status == MagickFalse)
870 average_image=DestroyImage(average_image);
871 return(average_image);
875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879 % C a t c h I m a g e E x c e p t i o n %
883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 % CatchImageException() returns if no exceptions are found in the image
886 % sequence, otherwise it determines the most severe exception and reports
887 % it as a warning or error depending on the severity.
889 % The format of the CatchImageException method is:
891 % ExceptionType CatchImageException(Image *image)
893 % A description of each parameter follows:
895 % o image: An image sequence.
898 MagickExport ExceptionType CatchImageException(Image *image)
906 assert(image != (const Image *) NULL);
907 assert(image->signature == MagickSignature);
908 if (image->debug != MagickFalse)
909 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
910 exception=AcquireExceptionInfo();
911 GetImageException(image,exception);
912 CatchException(exception);
913 severity=exception->severity;
914 exception=DestroyExceptionInfo(exception);
919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923 % C l i p I m a g e P a t h %
927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 % ClipImagePath() sets the image clip mask based any clipping path information
932 % The format of the ClipImagePath method is:
934 % MagickBooleanType ClipImagePath(Image *image,const char *pathname,
935 % const MagickBooleanType inside)
937 % A description of each parameter follows:
939 % o image: the image.
941 % o pathname: name of clipping path resource. If name is preceded by #, use
942 % clipping path numbered by name.
944 % o inside: if non-zero, later operations take effect inside clipping path.
945 % Otherwise later operations take effect outside clipping path.
949 MagickExport MagickBooleanType ClipImage(Image *image)
951 return(ClipImagePath(image,"#1",MagickTrue));
954 MagickExport MagickBooleanType ClipImagePath(Image *image,const char *pathname,
955 const MagickBooleanType inside)
957 #define ClipImagePathTag "ClipPath/Image"
971 assert(image != (const Image *) NULL);
972 assert(image->signature == MagickSignature);
973 if (image->debug != MagickFalse)
974 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
975 assert(pathname != NULL);
976 property=AcquireString(pathname);
977 (void) FormatMagickString(property,MaxTextExtent,"8BIM:1999,2998:%s",
979 value=GetImageProperty(image,property);
980 property=DestroyString(property);
981 if (value == (const char *) NULL)
983 ThrowFileException(&image->exception,OptionError,"NoClipPathDefined",
987 image_info=AcquireImageInfo();
988 (void) CopyMagickString(image_info->filename,image->filename,MaxTextExtent);
989 (void) ConcatenateMagickString(image_info->filename,pathname,MaxTextExtent);
990 clip_mask=BlobToImage(image_info,value,strlen(value),&image->exception);
991 image_info=DestroyImageInfo(image_info);
992 if (clip_mask == (Image *) NULL)
994 if (clip_mask->storage_class == PseudoClass)
996 (void) SyncImage(clip_mask);
997 if (SetImageStorageClass(clip_mask,DirectClass) == MagickFalse)
1000 if (inside == MagickFalse)
1001 (void) NegateImage(clip_mask,MagickFalse);
1002 (void) FormatMagickString(clip_mask->magick_filename,MaxTextExtent,
1003 "8BIM:1999,2998:%s\nPS",pathname);
1004 (void) SetImageClipMask(image,clip_mask);
1005 clip_mask=DestroyImage(clip_mask);
1010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1014 % C l o n e I m a g e %
1018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1020 % CloneImage() copies an image and returns the copy as a new image object.
1021 % If the specified columns and rows is 0, an exact copy of the image is
1022 % returned, otherwise the pixel data is undefined and must be initialized
1023 % with the QueueAuthenticPixels() and SyncAuthenticPixels() methods. On
1024 % failure, a NULL image is returned and exception describes the reason for the
1027 % The format of the CloneImage method is:
1029 % Image *CloneImage(const Image *image,const unsigned long columns,
1030 % const unsigned long rows,const MagickBooleanType orphan,
1031 % ExceptionInfo *exception)
1033 % A description of each parameter follows:
1035 % o image: the image.
1037 % o columns: the number of columns in the cloned image.
1039 % o rows: the number of rows in the cloned image.
1041 % o detach: With a value other than 0, the cloned image is detached from
1042 % its parent I/O stream.
1044 % o exception: return any errors or warnings in this structure.
1047 MagickExport Image *CloneImage(const Image *image,const unsigned long columns,
1048 const unsigned long rows,const MagickBooleanType detach,
1049 ExceptionInfo *exception)
1063 assert(image != (const Image *) NULL);
1064 assert(image->signature == MagickSignature);
1065 if (image->debug != MagickFalse)
1066 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1067 assert(exception != (ExceptionInfo *) NULL);
1068 assert(exception->signature == MagickSignature);
1069 clone_image=(Image *) AcquireMagickMemory(sizeof(*clone_image));
1070 if (clone_image == (Image *) NULL)
1071 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
1072 (void) ResetMagickMemory(clone_image,0,sizeof(*clone_image));
1073 clone_image->signature=MagickSignature;
1074 clone_image->storage_class=image->storage_class;
1075 clone_image->colorspace=image->colorspace;
1076 clone_image->matte=image->matte;
1077 clone_image->columns=image->columns;
1078 clone_image->rows=image->rows;
1079 clone_image->dither=image->dither;
1080 if (image->colormap != (PixelPacket *) NULL)
1083 Allocate and copy the image colormap.
1085 clone_image->colors=image->colors;
1086 length=(size_t) image->colors;
1087 clone_image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
1088 sizeof(*clone_image->colormap));
1089 if (clone_image->colormap == (PixelPacket *) NULL)
1090 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
1091 (void) CopyMagickMemory(clone_image->colormap,image->colormap,length*
1092 sizeof(*clone_image->colormap));
1094 (void) CloneImageProfiles(clone_image,image);
1095 (void) CloneImageProperties(clone_image,image);
1096 (void) CloneImageArtifacts(clone_image,image);
1097 GetTimerInfo(&clone_image->timer);
1098 GetExceptionInfo(&clone_image->exception);
1099 InheritException(&clone_image->exception,&image->exception);
1100 if (image->ascii85 != (void *) NULL)
1101 Ascii85Initialize(clone_image);
1102 clone_image->magick_columns=image->magick_columns;
1103 clone_image->magick_rows=image->magick_rows;
1104 clone_image->type=image->type;
1105 (void) CopyMagickString(clone_image->magick_filename,image->magick_filename,
1107 (void) CopyMagickString(clone_image->magick,image->magick,MaxTextExtent);
1108 (void) CopyMagickString(clone_image->filename,image->filename,MaxTextExtent);
1109 clone_image->progress_monitor=image->progress_monitor;
1110 clone_image->client_data=image->client_data;
1111 clone_image->reference_count=1;
1112 clone_image->next=NewImageList();
1113 clone_image->previous=NewImageList();
1114 clone_image->list=NewImageList();
1115 clone_image->clip_mask=NewImageList();
1116 clone_image->mask=NewImageList();
1117 if (detach == MagickFalse)
1118 clone_image->blob=ReferenceBlob(image->blob);
1120 clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1121 clone_image->debug=IsEventLogging();
1122 clone_image->semaphore=AllocateSemaphoreInfo();
1123 if ((columns == 0) && (rows == 0))
1125 if (image->montage != (char *) NULL)
1126 (void) CloneString(&clone_image->montage,image->montage);
1127 if (image->directory != (char *) NULL)
1128 (void) CloneString(&clone_image->directory,image->directory);
1129 if (image->clip_mask != (Image *) NULL)
1130 clone_image->clip_mask=CloneImage(image->clip_mask,0,0,MagickTrue,
1132 if (image->mask != (Image *) NULL)
1133 clone_image->mask=CloneImage(image->mask,0,0,MagickTrue,exception);
1134 clone_image->cache=ReferencePixelCache(image->cache);
1135 return(clone_image);
1137 scale=(MagickRealType) columns/(MagickRealType) image->columns;
1138 clone_image->page.width=(unsigned long) (scale*image->page.width+0.5);
1139 clone_image->page.x=(long) (scale*image->page.x+0.5);
1140 clone_image->tile_offset.x=(long) (scale*image->tile_offset.x+0.5);
1141 scale=(MagickRealType) rows/(MagickRealType) image->rows;
1142 clone_image->page.height=(unsigned long) (scale*image->page.height+0.5);
1143 clone_image->page.y=(long) (image->page.y*scale+0.5);
1144 clone_image->tile_offset.y=(long) (scale*image->tile_offset.y+0.5);
1145 clone_image->columns=columns;
1146 clone_image->rows=rows;
1147 clone_image->cache=ClonePixelCache(image->cache);
1148 return(clone_image);
1152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1156 % C l o n e I m a g e I n f o %
1160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1162 % CloneImageInfo() makes a copy of the given image info structure. If
1163 % NULL is specified, a new image info structure is created initialized to
1166 % The format of the CloneImageInfo method is:
1168 % ImageInfo *CloneImageInfo(const ImageInfo *image_info)
1170 % A description of each parameter follows:
1172 % o image_info: the image info.
1175 MagickExport ImageInfo *CloneImageInfo(const ImageInfo *image_info)
1180 clone_info=AcquireImageInfo();
1181 if (image_info == (ImageInfo *) NULL)
1183 clone_info->compression=image_info->compression;
1184 clone_info->temporary=image_info->temporary;
1185 clone_info->adjoin=image_info->adjoin;
1186 clone_info->antialias=image_info->antialias;
1187 clone_info->scene=image_info->scene;
1188 clone_info->number_scenes=image_info->number_scenes;
1189 clone_info->depth=image_info->depth;
1190 if (image_info->size != (char *) NULL)
1191 (void) CloneString(&clone_info->size,image_info->size);
1192 if (image_info->extract != (char *) NULL)
1193 (void) CloneString(&clone_info->extract,image_info->extract);
1194 if (image_info->scenes != (char *) NULL)
1195 (void) CloneString(&clone_info->scenes,image_info->scenes);
1196 if (image_info->page != (char *) NULL)
1197 (void) CloneString(&clone_info->page,image_info->page);
1198 clone_info->interlace=image_info->interlace;
1199 clone_info->endian=image_info->endian;
1200 clone_info->units=image_info->units;
1201 clone_info->quality=image_info->quality;
1202 if (image_info->sampling_factor != (char *) NULL)
1203 (void) CloneString(&clone_info->sampling_factor,
1204 image_info->sampling_factor);
1205 if (image_info->server_name != (char *) NULL)
1206 (void) CloneString(&clone_info->server_name,image_info->server_name);
1207 if (image_info->font != (char *) NULL)
1208 (void) CloneString(&clone_info->font,image_info->font);
1209 if (image_info->texture != (char *) NULL)
1210 (void) CloneString(&clone_info->texture,image_info->texture);
1211 if (image_info->density != (char *) NULL)
1212 (void) CloneString(&clone_info->density,image_info->density);
1213 clone_info->pointsize=image_info->pointsize;
1214 clone_info->fuzz=image_info->fuzz;
1215 clone_info->pen=image_info->pen;
1216 clone_info->background_color=image_info->background_color;
1217 clone_info->border_color=image_info->border_color;
1218 clone_info->matte_color=image_info->matte_color;
1219 clone_info->transparent_color=image_info->transparent_color;
1220 clone_info->dither=image_info->dither;
1221 clone_info->monochrome=image_info->monochrome;
1222 clone_info->colors=image_info->colors;
1223 clone_info->colorspace=image_info->colorspace;
1224 clone_info->type=image_info->type;
1225 clone_info->orientation=image_info->orientation;
1226 clone_info->preview_type=image_info->preview_type;
1227 clone_info->group=image_info->group;
1228 clone_info->ping=image_info->ping;
1229 clone_info->verbose=image_info->verbose;
1230 if (image_info->view != (char *) NULL)
1231 (void) CloneString(&clone_info->view,image_info->view);
1232 if (image_info->authenticate != (char *) NULL)
1233 (void) CloneString(&clone_info->authenticate,image_info->authenticate);
1234 (void) CloneImageOptions(clone_info,image_info);
1235 clone_info->progress_monitor=image_info->progress_monitor;
1236 clone_info->client_data=image_info->client_data;
1237 clone_info->cache=image_info->cache;
1238 if (image_info->cache != (void *) NULL)
1239 clone_info->cache=ReferencePixelCache(image_info->cache);
1240 if (image_info->profile != (void *) NULL)
1241 clone_info->profile=(void *) CloneStringInfo((StringInfo *)
1242 image_info->profile);
1243 SetImageInfoFile(clone_info,image_info->file);
1244 SetImageInfoBlob(clone_info,image_info->blob,image_info->length);
1245 clone_info->stream=image_info->stream;
1246 clone_info->virtual_pixel_method=image_info->virtual_pixel_method;
1247 (void) CopyMagickString(clone_info->magick,image_info->magick,MaxTextExtent);
1248 (void) CopyMagickString(clone_info->unique,image_info->unique,MaxTextExtent);
1249 (void) CopyMagickString(clone_info->zero,image_info->zero,MaxTextExtent);
1250 (void) CopyMagickString(clone_info->filename,image_info->filename,
1252 clone_info->subimage=image_info->scene; /* deprecated */
1253 clone_info->subrange=image_info->number_scenes; /* deprecated */
1254 clone_info->channel=image_info->channel;
1255 clone_info->debug=IsEventLogging();
1256 clone_info->signature=image_info->signature;
1261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1265 % C o m b i n e I m a g e s %
1269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1271 % CombineImages() combines one or more images into a single image. The
1272 % grayscale value of the pixels of each image in the sequence is assigned in
1273 % order to the specified channels of the combined image. The typical
1274 % ordering would be image 1 => Red, 2 => Green, 3 => Blue, etc.
1276 % The format of the CombineImages method is:
1278 % Image *CombineImages(const Image *image,const ChannelType channel,
1279 % ExceptionInfo *exception)
1281 % A description of each parameter follows:
1283 % o image: the image.
1285 % o exception: return any errors or warnings in this structure.
1288 MagickExport Image *CombineImages(const Image *image,const ChannelType channel,
1289 ExceptionInfo *exception)
1291 #define CombineImageTag "Combine/Image"
1310 Ensure the image are the same size.
1312 assert(image != (const Image *) NULL);
1313 assert(image->signature == MagickSignature);
1314 if (image->debug != MagickFalse)
1315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1316 assert(exception != (ExceptionInfo *) NULL);
1317 assert(exception->signature == MagickSignature);
1318 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
1320 if ((next->columns != image->columns) || (next->rows != image->rows))
1321 ThrowImageException(OptionError,"ImagesAreNotTheSameSize");
1323 combine_image=CloneImage(image,0,0,MagickTrue,exception);
1324 if (combine_image == (Image *) NULL)
1325 return((Image *) NULL);
1326 if (SetImageStorageClass(combine_image,DirectClass) == MagickFalse)
1328 InheritException(exception,&combine_image->exception);
1329 combine_image=DestroyImage(combine_image);
1330 return((Image *) NULL);
1332 if ((channel & OpacityChannel) != 0)
1333 combine_image->matte=MagickTrue;
1334 (void) SetImageBackgroundColor(combine_image);
1340 combine_view=AcquireCacheView(combine_image);
1341 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1342 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
1344 for (y=0; y < (long) combine_image->rows; y++)
1355 register const PixelPacket
1361 register PixelPacket
1364 if (status == MagickFalse)
1366 pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns,
1368 if (pixels == (PixelPacket *) NULL)
1374 if (((channel & RedChannel) != 0) && (next != (Image *) NULL))
1376 image_view=AcquireCacheView(next);
1377 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
1378 if (p == (const PixelPacket *) NULL)
1381 for (x=0; x < (long) combine_image->columns; x++)
1383 q->red=PixelIntensityToQuantum(p);
1387 image_view=DestroyCacheView(image_view);
1388 next=GetNextImageInList(next);
1390 if (((channel & GreenChannel) != 0) && (next != (Image *) NULL))
1392 image_view=AcquireCacheView(next);
1393 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
1394 if (p == (const PixelPacket *) NULL)
1397 for (x=0; x < (long) combine_image->columns; x++)
1399 q->green=PixelIntensityToQuantum(p);
1403 image_view=DestroyCacheView(image_view);
1404 next=GetNextImageInList(next);
1406 if (((channel & BlueChannel) != 0) && (next != (Image *) NULL))
1408 image_view=AcquireCacheView(next);
1409 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
1410 if (p == (const PixelPacket *) NULL)
1413 for (x=0; x < (long) combine_image->columns; x++)
1415 q->blue=PixelIntensityToQuantum(p);
1419 image_view=DestroyCacheView(image_view);
1420 next=GetNextImageInList(next);
1422 if (((channel & OpacityChannel) != 0) && (next != (Image *) NULL))
1424 image_view=AcquireCacheView(next);
1425 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
1426 if (p == (const PixelPacket *) NULL)
1429 for (x=0; x < (long) combine_image->columns; x++)
1431 q->opacity=PixelIntensityToQuantum(p);
1435 image_view=DestroyCacheView(image_view);
1436 next=GetNextImageInList(next);
1438 if (((channel & IndexChannel) != 0) &&
1439 (image->colorspace == CMYKColorspace) && (next != (Image *) NULL))
1444 image_view=AcquireCacheView(next);
1445 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
1446 if (p == (const PixelPacket *) NULL)
1448 indexes=GetCacheViewAuthenticIndexQueue(combine_view);
1449 for (x=0; x < (long) combine_image->columns; x++)
1451 indexes[x]=PixelIntensityToQuantum(p);
1454 image_view=DestroyCacheView(image_view);
1455 next=GetNextImageInList(next);
1457 if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse)
1459 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1464 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1465 #pragma omp critical (MagickCore_CombineImages)
1467 proceed=SetImageProgress(image,CombineImageTag,progress++,
1468 combine_image->rows);
1469 if (proceed == MagickFalse)
1473 combine_view=DestroyCacheView(combine_view);
1474 if (status == MagickFalse)
1475 combine_image=DestroyImage(combine_image);
1476 return(combine_image);
1480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484 % C y c l e C o l o r m a p I m a g e %
1488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490 % CycleColormap() displaces an image's colormap by a given number of
1491 % positions. If you cycle the colormap a number of times you can produce
1492 % a psychodelic effect.
1494 % The format of the CycleColormapImage method is:
1496 % MagickBooleanType CycleColormapImage(Image *image,const long displace)
1498 % A description of each parameter follows:
1500 % o image: the image.
1502 % o displace: displace the colormap this amount.
1505 MagickExport MagickBooleanType CycleColormapImage(Image *image,
1506 const long displace)
1520 assert(image != (Image *) NULL);
1521 assert(image->signature == MagickSignature);
1522 if (image->debug != MagickFalse)
1523 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1524 if (image->storage_class == DirectClass)
1525 (void) SetImageType(image,PaletteType);
1527 exception=(&image->exception);
1528 image_view=AcquireCacheView(image);
1529 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1530 #pragma omp parallel for schedule(dynamic,4) shared(status)
1532 for (y=0; y < (long) image->rows; y++)
1537 register IndexPacket
1538 *__restrict indexes;
1543 register PixelPacket
1546 if (status == MagickFalse)
1548 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1549 if (q == (PixelPacket *) NULL)
1554 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1555 for (x=0; x < (long) image->columns; x++)
1557 index=(long) (indexes[x]+displace) % image->colors;
1559 index+=image->colors;
1560 indexes[x]=(IndexPacket) index;
1561 q->red=image->colormap[index].red;
1562 q->green=image->colormap[index].green;
1563 q->blue=image->colormap[index].blue;
1566 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1569 image_view=DestroyCacheView(image_view);
1574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1578 % D e s t r o y I m a g e %
1582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1584 % DestroyImage() dereferences an image, deallocating memory associated with
1585 % the image if the reference count becomes zero.
1587 % The format of the DestroyImage method is:
1589 % Image *DestroyImage(Image *image)
1591 % A description of each parameter follows:
1593 % o image: the image.
1596 MagickExport Image *DestroyImage(Image *image)
1604 assert(image != (Image *) NULL);
1605 assert(image->signature == MagickSignature);
1606 if (image->debug != MagickFalse)
1607 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1608 destroy=MagickFalse;
1609 (void) LockSemaphoreInfo(image->semaphore);
1610 image->reference_count--;
1611 if (image->reference_count == 0)
1613 (void) UnlockSemaphoreInfo(image->semaphore);
1614 if (destroy == MagickFalse)
1615 return((Image *) NULL);
1619 DestroyImagePixels(image);
1620 if (image->clip_mask != (Image *) NULL)
1621 image->clip_mask=DestroyImage(image->clip_mask);
1622 if (image->mask != (Image *) NULL)
1623 image->mask=DestroyImage(image->mask);
1624 if (image->montage != (char *) NULL)
1625 image->montage=DestroyString(image->montage);
1626 if (image->directory != (char *) NULL)
1627 image->directory=DestroyString(image->directory);
1628 if (image->colormap != (PixelPacket *) NULL)
1629 image->colormap=(PixelPacket *) RelinquishMagickMemory(image->colormap);
1630 if (image->geometry != (char *) NULL)
1631 image->geometry=DestroyString(image->geometry);
1632 #if !defined(MAGICKCORE_EXCLUDE_DEPRECATED)
1633 DestroyImageAttributes(image);
1635 DestroyImageProfiles(image);
1636 DestroyImageProperties(image);
1637 DestroyImageArtifacts(image);
1638 if (image->ascii85 != (Ascii85Info*) NULL)
1639 image->ascii85=(Ascii85Info *) RelinquishMagickMemory(image->ascii85);
1641 (void) DestroyExceptionInfo(&image->exception);
1642 if (image->semaphore != (SemaphoreInfo *) NULL)
1643 DestroySemaphoreInfo(&image->semaphore);
1644 image->signature=(~MagickSignature);
1645 image=(Image *) RelinquishMagickMemory(image);
1650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1654 % D e s t r o y I m a g e I n f o %
1658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1660 % DestroyImageInfo() deallocates memory associated with an ImageInfo
1663 % The format of the DestroyImageInfo method is:
1665 % ImageInfo *DestroyImageInfo(ImageInfo *image_info)
1667 % A description of each parameter follows:
1669 % o image_info: the image info.
1672 MagickExport ImageInfo *DestroyImageInfo(ImageInfo *image_info)
1674 assert(image_info != (ImageInfo *) NULL);
1675 assert(image_info->signature == MagickSignature);
1676 if (image_info->debug != MagickFalse)
1677 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1678 image_info->filename);
1679 if (image_info->size != (char *) NULL)
1680 image_info->size=DestroyString(image_info->size);
1681 if (image_info->extract != (char *) NULL)
1682 image_info->extract=DestroyString(image_info->extract);
1683 if (image_info->scenes != (char *) NULL)
1684 image_info->scenes=DestroyString(image_info->scenes);
1685 if (image_info->page != (char *) NULL)
1686 image_info->page=DestroyString(image_info->page);
1687 if (image_info->sampling_factor != (char *) NULL)
1688 image_info->sampling_factor=DestroyString(
1689 image_info->sampling_factor);
1690 if (image_info->server_name != (char *) NULL)
1691 image_info->server_name=DestroyString(
1692 image_info->server_name);
1693 if (image_info->font != (char *) NULL)
1694 image_info->font=DestroyString(image_info->font);
1695 if (image_info->texture != (char *) NULL)
1696 image_info->texture=DestroyString(image_info->texture);
1697 if (image_info->density != (char *) NULL)
1698 image_info->density=DestroyString(image_info->density);
1699 if (image_info->view != (char *) NULL)
1700 image_info->view=DestroyString(image_info->view);
1701 if (image_info->authenticate != (char *) NULL)
1702 image_info->authenticate=DestroyString(
1703 image_info->authenticate);
1704 DestroyImageOptions(image_info);
1705 if (image_info->cache != (void *) NULL)
1706 image_info->cache=DestroyPixelCache(image_info->cache);
1707 if (image_info->profile != (StringInfo *) NULL)
1708 image_info->profile=(void *) DestroyStringInfo((StringInfo *)
1709 image_info->profile);
1710 image_info->signature=(~MagickSignature);
1711 image_info=(ImageInfo *) RelinquishMagickMemory(image_info);
1716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1720 + D i s a s s o c i a t e I m a g e S t r e a m %
1724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1726 % DisassociateImageStream() disassociates the image stream.
1728 % The format of the DisassociateImageStream method is:
1730 % MagickBooleanType DisassociateImageStream(const Image *image)
1732 % A description of each parameter follows:
1734 % o image: the image.
1737 MagickExport void DisassociateImageStream(Image *image)
1739 assert(image != (const Image *) NULL);
1740 assert(image->signature == MagickSignature);
1741 if (image->debug != MagickFalse)
1742 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1743 (void) DetachBlob(image->blob);
1747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 % G e t I m a g e A l p h a C h a n n e l %
1755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1757 % GetImageAlphaChannel() returns MagickFalse if the image alpha channel is
1758 % not activated. That is, the image is RGB rather than RGBA or CMYK rather
1761 % The format of the GetImageAlphaChannel method is:
1763 % MagickBooleanType GetImageAlphaChannel(const Image *image)
1765 % A description of each parameter follows:
1767 % o image: the image.
1770 MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
1772 assert(image != (const Image *) NULL);
1773 if (image->debug != MagickFalse)
1774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1775 assert(image->signature == MagickSignature);
1776 return(image->matte);
1780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1784 % G e t I m a g e C l i p M a s k %
1788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1790 % GetImageClipMask() returns the clip path associated with the image.
1792 % The format of the GetImageClipMask method is:
1794 % Image *GetImageClipMask(const Image *image,ExceptionInfo *exception)
1796 % A description of each parameter follows:
1798 % o image: the image.
1801 MagickExport Image *GetImageClipMask(const Image *image,
1802 ExceptionInfo *exception)
1804 assert(image != (const Image *) NULL);
1805 if (image->debug != MagickFalse)
1806 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1807 assert(image->signature == MagickSignature);
1808 if (image->clip_mask == (Image *) NULL)
1809 return((Image *) NULL);
1810 return(CloneImage(image->clip_mask,0,0,MagickTrue,exception));
1814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818 % G e t I m a g e E x c e p t i o n %
1822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1824 % GetImageException() traverses an image sequence and returns any
1825 % error more severe than noted by the exception parameter.
1827 % The format of the GetImageException method is:
1829 % void GetImageException(Image *image,ExceptionInfo *exception)
1831 % A description of each parameter follows:
1833 % o image: Specifies a pointer to a list of one or more images.
1835 % o exception: return the highest severity exception.
1838 MagickExport void GetImageException(Image *image,ExceptionInfo *exception)
1843 assert(image != (Image *) NULL);
1844 assert(image->signature == MagickSignature);
1845 if (image->debug != MagickFalse)
1846 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1847 assert(exception != (ExceptionInfo *) NULL);
1848 assert(exception->signature == MagickSignature);
1849 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
1851 if (next->exception.severity == UndefinedException)
1853 if (next->exception.severity > exception->severity)
1854 InheritException(exception,&next->exception);
1855 next->exception.severity=UndefinedException;
1860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864 % G e t I m a g e I n f o %
1868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 % GetImageInfo() initializes image_info to default values.
1872 % The format of the GetImageInfo method is:
1874 % void GetImageInfo(ImageInfo *image_info)
1876 % A description of each parameter follows:
1878 % o image_info: the image info.
1881 MagickExport void GetImageInfo(ImageInfo *image_info)
1887 File and image dimension members.
1889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1890 assert(image_info != (ImageInfo *) NULL);
1891 (void) ResetMagickMemory(image_info,0,sizeof(*image_info));
1892 image_info->adjoin=MagickTrue;
1893 image_info->interlace=NoInterlace;
1894 image_info->channel=DefaultChannels;
1895 image_info->quality=UndefinedCompressionQuality;
1896 image_info->antialias=MagickTrue;
1897 image_info->dither=MagickTrue;
1898 exception=AcquireExceptionInfo();
1899 (void) QueryColorDatabase(BackgroundColor,&image_info->background_color,
1901 (void) QueryColorDatabase(BorderColor,&image_info->border_color,exception);
1902 (void) QueryColorDatabase(MatteColor,&image_info->matte_color,exception);
1903 (void) QueryColorDatabase(TransparentColor,&image_info->transparent_color,
1905 exception=DestroyExceptionInfo(exception);
1906 image_info->debug=IsEventLogging();
1907 image_info->signature=MagickSignature;
1911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1915 % G e t I m a g e M a s k %
1919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 % GetImageMask() returns the mask associated with the image.
1923 % The format of the GetImageMask method is:
1925 % Image *GetImageMask(const Image *image,ExceptionInfo *exception)
1927 % A description of each parameter follows:
1929 % o image: the image.
1932 MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
1934 assert(image != (const Image *) NULL);
1935 if (image->debug != MagickFalse)
1936 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1937 assert(image->signature == MagickSignature);
1938 if (image->mask == (Image *) NULL)
1939 return((Image *) NULL);
1940 return(CloneImage(image->mask,0,0,MagickTrue,exception));
1944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948 + G e t I m a g e R e f e r e n c e C o u n t %
1952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1954 % GetImageReferenceCount() returns the image reference count.
1956 % The format of the GetReferenceCount method is:
1958 % long GetImageReferenceCount(Image *image)
1960 % A description of each parameter follows:
1962 % o image: the image.
1965 MagickExport long GetImageReferenceCount(Image *image)
1970 assert(image != (Image *) NULL);
1971 assert(image->signature == MagickSignature);
1972 if (image->debug != MagickFalse)
1973 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1974 AcquireSemaphoreInfo(&image->semaphore);
1975 reference_count=image->reference_count;
1976 RelinquishSemaphoreInfo(image->semaphore);
1977 return(reference_count);
1981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 % G e t I m a g e T y p e %
1989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1991 % GetImageType() returns the potential type of image:
1993 % Bilevel Grayscale GrayscaleMatte
1994 % Palette PaletteMatte TrueColor
1995 % TrueColorMatte ColorSeparation ColorSeparationMatte
1997 % To ensure the image type matches its potential, use SetImageType():
1999 % (void) SetImageType(image,GetImageType(image));
2001 % The format of the GetImageType method is:
2003 % ImageType GetImageType(const Image *image,ExceptionInfo *exception)
2005 % A description of each parameter follows:
2007 % o image: the image.
2009 % o exception: return any errors or warnings in this structure.
2012 MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
2014 assert(image != (Image *) NULL);
2015 assert(image->signature == MagickSignature);
2016 if (image->debug != MagickFalse)
2017 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2018 if (image->colorspace == CMYKColorspace)
2020 if (image->matte == MagickFalse)
2021 return(ColorSeparationType);
2022 return(ColorSeparationMatteType);
2024 if (IsMonochromeImage(image,exception) != MagickFalse)
2025 return(BilevelType);
2026 if (IsGrayImage(image,exception) != MagickFalse)
2028 if (image->matte != MagickFalse)
2029 return(GrayscaleMatteType);
2030 return(GrayscaleType);
2032 if (IsPaletteImage(image,exception) != MagickFalse)
2034 if (image->matte != MagickFalse)
2035 return(PaletteMatteType);
2036 return(PaletteType);
2038 if (image->matte != MagickFalse)
2039 return(TrueColorMatteType);
2040 return(TrueColorType);
2044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048 % 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 %
2052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2054 % GetImageVirtualPixelMethod() gets the "virtual pixels" method for the
2055 % image. A virtual pixel is any pixel access that is outside the boundaries
2056 % of the image cache.
2058 % The format of the GetImageVirtualPixelMethod() method is:
2060 % VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
2062 % A description of each parameter follows:
2064 % o image: the image.
2067 MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
2069 assert(image != (Image *) NULL);
2070 assert(image->signature == MagickSignature);
2071 if (image->debug != MagickFalse)
2072 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2073 return(GetPixelCacheVirtualMethod(image));
2077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2081 % I n t e r p r e t I m a g e F i l e n a m e %
2085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2087 % InterpretImageFilename() interprets embedded characters in an image filename.
2088 % The filename length is returned.
2090 % The format of the InterpretImageFilename method is:
2092 % size_t InterpretImageFilename(const ImageInfo *image_info,
2093 % Image *image,const char *format,int value,char *filename)
2095 % A description of each parameter follows.
2097 % o image_info: the image info..
2099 % o image: the image.
2101 % o format: A filename describing the format to use to write the numeric
2102 % argument. Only the first numeric format identifier is replaced.
2104 % o value: Numeric value to substitute into format filename.
2106 % o filename: return the formatted filename in this character buffer.
2109 MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
2110 Image *image,const char *format,int value,char *filename)
2124 canonical=MagickFalse;
2125 (void) CopyMagickString(filename,format,MaxTextExtent);
2126 for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
2139 value=strtol(q,&q,10);
2150 (void) FormatMagickString(filename+(p-format),(size_t) (MaxTextExtent-
2151 (p-format)),p,value);
2153 (void) ConcatenateMagickString(filename,q,MaxTextExtent);
2154 canonical=MagickTrue;
2163 pattern[MaxTextExtent];
2180 if (strchr(p,']') == (char *) NULL)
2184 for (i=0; (i < (MaxTextExtent-1L)) && (*r != '\0'); i++)
2195 if (LocaleNCompare(pattern,"filename:",9) != 0)
2197 value=(const char *) NULL;
2198 if ((image_info != (const ImageInfo *) NULL) &&
2199 (image != (const Image *) NULL))
2200 value=GetMagickProperty(image_info,image,pattern);
2202 if (image != (Image *) NULL)
2203 value=GetImageProperty(image,pattern);
2205 if (image_info != (ImageInfo *) NULL)
2206 value=GetImageOption(image_info,pattern);
2207 if (value == (const char *) NULL)
2212 (void) CopyMagickString(filename+(p-format),value,(size_t)
2213 (MaxTextExtent-(p-format)));
2215 (void) ConcatenateMagickString(filename,r+1,MaxTextExtent);
2216 canonical=MagickTrue;
2226 for (q=filename; *q != '\0'; q++)
2227 if ((*q == '%') && (*(q+1) == '%'))
2228 (void) CopyMagickString(q,q+1,(size_t) (MaxTextExtent-(q-filename)));
2229 if (canonical == MagickFalse)
2230 (void) CopyMagickString(filename,format,MaxTextExtent);
2231 return(strlen(filename));
2235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2239 % I s H i g h D y n a m i c R a n g e I m a g e %
2243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2245 % IsHighDynamicRangeImage() returns MagickTrue if any pixel component is
2246 % non-integer or exceeds the bounds of the quantum depth (e.g. for Q16
2249 % The format of the IsHighDynamicRangeImage method is:
2251 % MagickBooleanType IsHighDynamicRangeImage(const Image *image,
2252 % ExceptionInfo *exception)
2254 % A description of each parameter follows:
2256 % o image: the image.
2258 % o exception: return any errors or warnings in this structure.
2261 MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
2262 ExceptionInfo *exception)
2264 #if !defined(MAGICKCORE_HDRI_SUPPORT)
2267 return(MagickFalse);
2281 assert(image != (Image *) NULL);
2282 assert(image->signature == MagickSignature);
2283 if (image->debug != MagickFalse)
2284 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2286 GetMagickPixelPacket(image,&zero);
2287 image_view=AcquireCacheView(image);
2288 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2289 #pragma omp parallel for schedule(dynamic,4) shared(status)
2291 for (y=0; y < (long) image->rows; y++)
2296 register const IndexPacket
2299 register const PixelPacket
2305 if (status == MagickFalse)
2307 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2308 if (p == (const PixelPacket *) NULL)
2313 indexes=GetCacheViewVirtualIndexQueue(image_view);
2315 for (x=0; x < (long) image->columns; x++)
2317 SetMagickPixelPacket(image,p,indexes+x,&pixel);
2318 if ((pixel.red < 0.0) || (pixel.red > QuantumRange) ||
2319 (pixel.red != (QuantumAny) pixel.red))
2321 if ((pixel.green < 0.0) || (pixel.green > QuantumRange) ||
2322 (pixel.green != (QuantumAny) pixel.green))
2324 if ((pixel.blue < 0.0) || (pixel.blue > QuantumRange) ||
2325 (pixel.blue != (QuantumAny) pixel.blue))
2327 if (pixel.matte != MagickFalse)
2329 if ((pixel.opacity < 0.0) || (pixel.opacity > QuantumRange) ||
2330 (pixel.opacity != (QuantumAny) pixel.opacity))
2333 if (pixel.colorspace == CMYKColorspace)
2335 if ((pixel.index < 0.0) || (pixel.index > QuantumRange) ||
2336 (pixel.index != (QuantumAny) pixel.index))
2341 if (x < (long) image->columns)
2344 image_view=DestroyCacheView(image_view);
2345 return(status != MagickFalse ? MagickFalse : MagickTrue);
2350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2354 % I s I m a g e O b j e c t %
2358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2360 % IsImageObject() returns MagickTrue if the image sequence contains a valid
2361 % set of image objects.
2363 % The format of the IsImageObject method is:
2365 % MagickBooleanType IsImageObject(const Image *image)
2367 % A description of each parameter follows:
2369 % o image: the image.
2372 MagickExport MagickBooleanType IsImageObject(const Image *image)
2374 register const Image
2377 assert(image != (Image *) NULL);
2378 if (image->debug != MagickFalse)
2379 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2380 for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
2381 if (p->signature != MagickSignature)
2382 return(MagickFalse);
2387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2391 % I s T a i n t I m a g e %
2395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2397 % IsTaintImage() returns MagickTrue any pixel in the image has been altered
2398 % since it was first constituted.
2400 % The format of the IsTaintImage method is:
2402 % MagickBooleanType IsTaintImage(const Image *image)
2404 % A description of each parameter follows:
2406 % o image: the image.
2409 MagickExport MagickBooleanType IsTaintImage(const Image *image)
2412 magick[MaxTextExtent],
2413 filename[MaxTextExtent];
2415 register const Image
2418 assert(image != (Image *) NULL);
2419 if (image->debug != MagickFalse)
2420 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2421 assert(image->signature == MagickSignature);
2422 (void) CopyMagickString(magick,image->magick,MaxTextExtent);
2423 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
2424 for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
2426 if (p->taint != MagickFalse)
2428 if (LocaleCompare(p->magick,magick) != 0)
2430 if (LocaleCompare(p->filename,filename) != 0)
2433 return(MagickFalse);
2437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2441 % M o d i f y I m a g e %
2445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2447 % ModifyImage() ensures that there is only a single reference to the image
2448 % to be modified, updating the provided image pointer to point to a clone of
2449 % the original image if necessary.
2451 % The format of the ModifyImage method is:
2453 % MagickBooleanType ModifyImage(Image *image,ExceptionInfo *exception)
2455 % A description of each parameter follows:
2457 % o image: the image.
2459 % o exception: return any errors or warnings in this structure.
2462 MagickExport MagickBooleanType ModifyImage(Image **image,
2463 ExceptionInfo *exception)
2468 assert(image != (Image **) NULL);
2469 assert(*image != (Image *) NULL);
2470 assert((*image)->signature == MagickSignature);
2471 if ((*image)->debug != MagickFalse)
2472 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
2473 if (GetImageReferenceCount(*image) <= 1)
2475 clone_image=CloneImage(*image,0,0,MagickTrue,exception);
2476 AcquireSemaphoreInfo(&(*image)->semaphore);
2477 (*image)->reference_count--;
2478 RelinquishSemaphoreInfo((*image)->semaphore);
2484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2488 % N e w M a g i c k I m a g e %
2492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2494 % NewMagickImage() creates a blank image canvas of the specified size and
2497 % The format of the NewMagickImage method is:
2499 % Image *NewMagickImage(const ImageInfo *image_info,
2500 % const unsigned long width,const unsigned long height,
2501 % const MagickPixelPacket *background)
2503 % A description of each parameter follows:
2505 % o image: the image.
2507 % o width: the image width.
2509 % o height: the image height.
2511 % o background: the image color.
2514 MagickExport Image *NewMagickImage(const ImageInfo *image_info,
2515 const unsigned long width,const unsigned long height,
2516 const MagickPixelPacket *background)
2533 assert(image_info != (const ImageInfo *) NULL);
2534 if (image_info->debug != MagickFalse)
2535 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2536 assert(image_info->signature == MagickSignature);
2537 assert(background != (const MagickPixelPacket *) NULL);
2538 image=AcquireImage(image_info);
2539 image->columns=width;
2541 image->colorspace=background->colorspace;
2542 image->matte=background->matte;
2543 image->fuzz=background->fuzz;
2544 image->depth=background->depth;
2546 exception=(&image->exception);
2547 image_view=AcquireCacheView(image);
2548 for (y=0; y < (long) image->rows; y++)
2550 register IndexPacket
2551 *__restrict indexes;
2556 register PixelPacket
2559 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2560 if (q == (PixelPacket *) NULL)
2565 indexes=GetCacheViewAuthenticIndexQueue(image_view);
2566 for (x=0; x < (long) image->columns; x++)
2568 SetPixelPacket(image,background,q,indexes+x);
2571 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2573 if (status == MagickFalse)
2576 image_view=DestroyCacheView(image_view);
2577 if (status == MagickFalse)
2578 image=DestroyImage(image);
2583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2587 % R e f e r e n c e I m a g e %
2591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2593 % ReferenceImage() increments the reference count associated with an image
2594 % returning a pointer to the image.
2596 % The format of the ReferenceImage method is:
2598 % Image *ReferenceImage(Image *image)
2600 % A description of each parameter follows:
2602 % o image: the image.
2605 MagickExport Image *ReferenceImage(Image *image)
2607 assert(image != (Image *) NULL);
2608 if (image->debug != MagickFalse)
2609 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2610 assert(image->signature == MagickSignature);
2611 (void) LockSemaphoreInfo(image->semaphore);
2612 image->reference_count++;
2613 (void) UnlockSemaphoreInfo(image->semaphore);
2618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2622 % R e s e t I m a g e P a g e %
2626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2628 % ResetImagePage() resets the image page canvas and position.
2630 % The format of the ResetImagePage method is:
2632 % MagickBooleanType ResetImagePage(Image *image,const char *page)
2634 % A description of each parameter follows:
2636 % o image: the image.
2638 % o page: the relative page specification.
2641 MagickExport MagickBooleanType ResetImagePage(Image *image,const char *page)
2649 assert(image != (Image *) NULL);
2650 assert(image->signature == MagickSignature);
2651 if (image->debug != MagickFalse)
2652 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2653 flags=ParseAbsoluteGeometry(page,&geometry);
2654 if ((flags & WidthValue) != 0)
2656 if ((flags & HeightValue) == 0)
2657 geometry.height=geometry.width;
2658 image->page.width=geometry.width;
2659 image->page.height=geometry.height;
2661 if ((flags & AspectValue) != 0)
2663 if ((flags & XValue) != 0)
2664 image->page.x+=geometry.x;
2665 if ((flags & YValue) != 0)
2666 image->page.y+=geometry.y;
2670 if ((flags & XValue) != 0)
2672 image->page.x=geometry.x;
2673 if ((image->page.width == 0) && (geometry.x > 0))
2674 image->page.width=image->columns+geometry.x;
2676 if ((flags & YValue) != 0)
2678 image->page.y=geometry.y;
2679 if ((image->page.height == 0) && (geometry.y > 0))
2680 image->page.height=image->rows+geometry.y;
2687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2691 % S e p a r a t e I m a g e C h a n n e l %
2695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2697 % SeparateImageChannel() separates a channel from the image and returns it as
2698 % a grayscale image. A channel is a particular color component of each pixel
2701 % The format of the SeparateImageChannel method is:
2703 % MagickBooleanType SeparateImageChannel(Image *image,
2704 % const ChannelType channel)
2706 % A description of each parameter follows:
2708 % o image: the image.
2710 % o channel: Identify which channel to extract: RedChannel, GreenChannel,
2711 % BlueChannel, OpacityChannel, CyanChannel, MagentaChannel,
2712 % YellowChannel, or BlackChannel.
2715 MagickExport MagickBooleanType SeparateImageChannel(Image *image,
2716 const ChannelType channel)
2718 #define SeparateImageTag "Separate/Image"
2733 assert(image != (Image *) NULL);
2734 assert(image->signature == MagickSignature);
2735 if (image->debug != MagickFalse)
2736 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2737 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2738 return(MagickFalse);
2740 Separate image channels.
2743 if ( channel == GrayChannels )
2744 image->matte=MagickTrue;
2746 exception=(&image->exception);
2747 image_view=AcquireCacheView(image);
2748 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2749 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
2751 for (y=0; y < (long) image->rows; y++)
2753 register IndexPacket
2754 *__restrict indexes;
2759 register PixelPacket
2762 if (status == MagickFalse)
2764 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2765 if (q == (PixelPacket *) NULL)
2770 indexes=GetCacheViewAuthenticIndexQueue(image_view);
2775 for (x=0; x < (long) image->columns; x++)
2785 for (x=0; x < (long) image->columns; x++)
2795 for (x=0; x < (long) image->columns; x++)
2803 case OpacityChannel:
2805 for (x=0; x < (long) image->columns; x++)
2808 q->green=q->opacity;
2816 if ((image->storage_class != PseudoClass) &&
2817 (image->colorspace != CMYKColorspace))
2819 for (x=0; x < (long) image->columns; x++)
2822 q->green=indexes[x];
2828 case TrueAlphaChannel:
2830 for (x=0; x < (long) image->columns; x++)
2832 q->red=(Quantum) (QuantumRange-q->opacity);
2833 q->green=(Quantum) (QuantumRange-q->opacity);
2834 q->blue=(Quantum) (QuantumRange-q->opacity);
2841 for (x=0; x < (long) image->columns; x++)
2843 q->opacity=(Quantum) (QuantumRange-PixelIntensityToQuantum(q));
2851 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2853 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2858 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2859 #pragma omp critical (MagickCore_SeparateImageChannel)
2861 proceed=SetImageProgress(image,SeparateImageTag,progress++,image->rows);
2862 if (proceed == MagickFalse)
2866 image_view=DestroyCacheView(image_view);
2867 if ( channel != GrayChannels )
2868 image->matte=MagickFalse;
2869 (void) SetImageColorspace(image,RGBColorspace);
2874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2878 % S e p a r a t e I m a g e s %
2882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2884 % SeparateImages() returns a separate grayscale image for each channel
2887 % The format of the SeparateImages method is:
2889 % MagickBooleanType SeparateImages(const Image *image,
2890 % const ChannelType channel,ExceptionInfo *exception)
2892 % A description of each parameter follows:
2894 % o image: the image.
2896 % o channel: Identify which channels to extract: RedChannel, GreenChannel,
2897 % BlueChannel, OpacityChannel, CyanChannel, MagentaChannel,
2898 % YellowChannel, or BlackChannel.
2900 % o exception: return any errors or warnings in this structure.
2903 MagickExport Image *SeparateImages(const Image *image,const ChannelType channel,
2904 ExceptionInfo *exception)
2910 assert(image != (Image *) NULL);
2911 assert(image->signature == MagickSignature);
2912 if (image->debug != MagickFalse)
2913 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2914 images=NewImageList();
2915 if ((channel & RedChannel) != 0)
2917 separate_image=CloneImage(image,0,0,MagickTrue,exception);
2918 (void) SeparateImageChannel(separate_image,RedChannel);
2919 AppendImageToList(&images,separate_image);
2921 if ((channel & GreenChannel) != 0)
2923 separate_image=CloneImage(image,0,0,MagickTrue,exception);
2924 (void) SeparateImageChannel(separate_image,GreenChannel);
2925 AppendImageToList(&images,separate_image);
2927 if ((channel & BlueChannel) != 0)
2929 separate_image=CloneImage(image,0,0,MagickTrue,exception);
2930 (void) SeparateImageChannel(separate_image,BlueChannel);
2931 AppendImageToList(&images,separate_image);
2933 if (((channel & BlackChannel) != 0) && (image->colorspace == CMYKColorspace))
2935 separate_image=CloneImage(image,0,0,MagickTrue,exception);
2936 (void) SeparateImageChannel(separate_image,BlackChannel);
2937 AppendImageToList(&images,separate_image);
2939 if ((channel & OpacityChannel) != 0)
2941 separate_image=CloneImage(image,0,0,MagickTrue,exception);
2942 (void) SeparateImageChannel(separate_image,OpacityChannel);
2943 AppendImageToList(&images,separate_image);
2949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2953 % S e t I m a g e A l p h a C h a n n e l %
2957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2959 % SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
2962 % The format of the SetImageAlphaChannel method is:
2964 % MagickBooleanType SetImageAlphaChannel(Image *image,
2965 % const AlphaChannelType alpha_type)
2967 % A description of each parameter follows:
2969 % o image: the image.
2971 % o alpha_type: The alpha channel type: ActivateAlphaChannel,
2972 % CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
2973 % OpaqueAlphaChannel, ResetAlphaChannel, SetAlphaChannel,
2974 % ShapeAlphaChannel, and TransparentAlphaChannel.
2977 MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
2978 const AlphaChannelType alpha_type)
2983 assert(image != (Image *) NULL);
2984 if (image->debug != MagickFalse)
2985 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2986 assert(image->signature == MagickSignature);
2990 case ActivateAlphaChannel:
2992 image->matte=MagickTrue;
2995 case BackgroundAlphaChannel:
3019 Set transparent pixels to background color.
3021 if (image->matte == MagickFalse)
3023 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
3025 GetMagickPixelPacket(image,&background);
3026 SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
3028 if (image->colorspace == CMYKColorspace)
3029 ConvertRGBToCMYK(&background);
3031 SetPixelPacket(image,&background,&pixel,&index);
3033 exception=(&image->exception);
3034 image_view=AcquireCacheView(image);
3035 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3036 #pragma omp parallel for schedule(dynamic,4) shared(status)
3038 for (y=0; y < (long) image->rows; y++)
3040 register IndexPacket
3041 *__restrict indexes;
3046 register PixelPacket
3049 if (status == MagickFalse)
3051 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3053 if (q == (PixelPacket *) NULL)
3058 for (x=0; x < (long) image->columns; x++)
3060 if (q->opacity == TransparentOpacity)
3063 q->green=pixel.green;
3068 if (image->colorspace == CMYKColorspace)
3070 indexes=GetCacheViewAuthenticIndexQueue(image_view);
3071 for (x=0; x < (long) image->columns; x++)
3074 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3077 image_view=DestroyCacheView(image_view);
3080 case DeactivateAlphaChannel:
3082 image->matte=MagickFalse;
3085 case ShapeAlphaChannel:
3086 case CopyAlphaChannel:
3089 Special usage case for SeparateImageChannel(): copy grayscale color to
3092 status=SeparateImageChannel(image,GrayChannels);
3093 image->matte=MagickTrue; /* make sure transparency is now on! */
3094 if (alpha_type == ShapeAlphaChannel)
3100 Reset all color channels to background color.
3102 GetMagickPixelPacket(image,&background);
3103 SetMagickPixelPacket(image,&(image->background_color),(IndexPacket *)
3105 (void) LevelImageColors(image,DefaultChannels,&background,&background,
3110 case ExtractAlphaChannel:
3112 status=SeparateImageChannel(image,TrueAlphaChannel);
3113 image->matte=MagickFalse;
3116 case ResetAlphaChannel:
3117 case OpaqueAlphaChannel:
3119 status=SetImageOpacity(image,OpaqueOpacity);
3120 image->matte=MagickTrue;
3123 case TransparentAlphaChannel:
3125 status=SetImageOpacity(image,TransparentOpacity);
3126 image->matte=MagickTrue;
3129 case SetAlphaChannel:
3131 if (image->matte == MagickFalse)
3133 status=SetImageOpacity(image,OpaqueOpacity);
3134 image->matte=MagickTrue;
3138 case UndefinedAlphaChannel:
3145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3149 % S e t I m a g e B a c k g r o u n d C o l o r %
3153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3155 % SetImageBackgroundColor() initializes the image pixels to the image
3156 % background color. The background color is defined by the background_color
3157 % member of the image structure.
3159 % The format of the SetImage method is:
3161 % MagickBooleanType SetImageBackgroundColor(Image *image)
3163 % A description of each parameter follows:
3165 % o image: the image.
3168 MagickExport MagickBooleanType SetImageBackgroundColor(Image *image)
3191 assert(image != (Image *) NULL);
3192 if (image->debug != MagickFalse)
3193 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3194 assert(image->signature == MagickSignature);
3195 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
3196 return(MagickFalse);
3197 if (image->background_color.opacity != OpaqueOpacity)
3198 image->matte=MagickTrue;
3199 GetMagickPixelPacket(image,&background);
3200 SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
3202 if (image->colorspace == CMYKColorspace)
3203 ConvertRGBToCMYK(&background);
3205 SetPixelPacket(image,&background,&pixel,&index);
3207 Set image background color.
3210 exception=(&image->exception);
3211 image_view=AcquireCacheView(image);
3212 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3213 #pragma omp parallel for schedule(dynamic,4) shared(status)
3215 for (y=0; y < (long) image->rows; y++)
3217 register IndexPacket
3218 *__restrict indexes;
3223 register PixelPacket
3226 if (status == MagickFalse)
3228 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3229 if (q == (PixelPacket *) NULL)
3234 for (x=0; x < (long) image->columns; x++)
3236 if (image->colorspace == CMYKColorspace)
3238 indexes=GetCacheViewAuthenticIndexQueue(image_view);
3239 for (x=0; x < (long) image->columns; x++)
3242 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3245 image_view=DestroyCacheView(image_view);
3250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3254 % S e t I m a g e S t o r a g e C l a s s %
3258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3260 % SetImageStorageClass() sets the image class: DirectClass for true color
3261 % images or PseudoClass for colormapped images.
3263 % The format of the SetImageStorageClass method is:
3265 % MagickBooleanType SetImageStorageClass(Image *image,
3266 % const ClassType storage_class)
3268 % A description of each parameter follows:
3270 % o image: the image.
3272 % o storage_class: The image class.
3275 MagickExport MagickBooleanType SetImageStorageClass(Image *image,
3276 const ClassType storage_class)
3281 if (image->storage_class == storage_class)
3283 image->storage_class=storage_class;
3284 cache=GetImagePixelCache(image,MagickTrue,&image->exception);
3285 return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3293 % S e t I m a g e C l i p M a s k %
3297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3299 % SetImageClipMask() associates a clip path with the image. The clip path
3300 % must be the same dimensions as the image. Set any pixel component of
3301 % the clip path to TransparentOpacity to prevent that corresponding image
3302 % pixel component from being updated when SyncAuthenticPixels() is applied.
3304 % The format of the SetImageClipMask method is:
3306 % MagickBooleanType SetImageClipMask(Image *image,const Image *clip_mask)
3308 % A description of each parameter follows:
3310 % o image: the image.
3312 % o clip_mask: the image clip path.
3315 MagickExport MagickBooleanType SetImageClipMask(Image *image,
3316 const Image *clip_mask)
3318 assert(image != (Image *) NULL);
3319 if (image->debug != MagickFalse)
3320 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3321 assert(image->signature == MagickSignature);
3322 if (clip_mask != (const Image *) NULL)
3323 if ((clip_mask->columns != image->columns) ||
3324 (clip_mask->rows != image->rows))
3325 ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
3326 if (image->clip_mask != (Image *) NULL)
3327 image->clip_mask=DestroyImage(image->clip_mask);
3328 image->clip_mask=NewImageList();
3329 if (clip_mask == (Image *) NULL)
3331 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
3332 return(MagickFalse);
3333 image->clip_mask=CloneImage(clip_mask,0,0,MagickTrue,&image->exception);
3334 if (image->clip_mask == (Image *) NULL)
3335 return(MagickFalse);
3340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3344 % S e t I m a g e E x t e n t %
3348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3350 % SetImageExtent() sets the image size (i.e. columns & rows).
3352 % The format of the SetImageExtent method is:
3354 % MagickBooleanType SetImageExtent(Image *image,
3355 % const unsigned long columns,const unsigned long rows)
3357 % A description of each parameter follows:
3359 % o image: the image.
3361 % o columns: The image width in pixels.
3363 % o rows: The image height in pixels.
3366 MagickExport MagickBooleanType SetImageExtent(Image *image,
3367 const unsigned long columns,const unsigned long rows)
3372 if ((columns != 0) && (rows != 0))
3374 image->columns=columns;
3377 cache=GetImagePixelCache(image,MagickTrue,&image->exception);
3378 return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
3382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386 + S e t I m a g e I n f o %
3390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3392 % SetImageInfo() initializes the `magick' field of the ImageInfo structure.
3393 % It is set to a type of image format based on the prefix or suffix of the
3394 % filename. For example, `ps:image' returns PS indicating a Postscript image.
3395 % JPEG is returned for this filename: `image.jpg'. The filename prefix has
3396 % precendence over the suffix. Use an optional index enclosed in brackets
3397 % after a file name to specify a desired scene of a multi-resolution image
3398 % format like Photo CD (e.g. img0001.pcd[4]). A True (non-zero) return value
3399 % indicates success.
3401 % The format of the SetImageInfo method is:
3403 % MagickBooleanType SetImageInfo(ImageInfo *image_info,
3404 % const MagickBooleanType rectify,ExceptionInfo *exception)
3406 % A description of each parameter follows:
3408 % o image_info: the image info..
3410 % o rectify: an unsigned value other than zero rectifies the attribute for
3411 % multi-frame support (user may want multi-frame but image format may not
3414 % o exception: return any errors or warnings in this structure.
3417 MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info,
3418 const MagickBooleanType rectify,ExceptionInfo *exception)
3421 extension[MaxTextExtent],
3422 filename[MaxTextExtent],
3423 magic[MaxTextExtent],
3425 subimage[MaxTextExtent];
3449 magick[2*MaxTextExtent];
3452 Look for 'image.format' in filename.
3454 assert(image_info != (ImageInfo *) NULL);
3455 assert(image_info->signature == MagickSignature);
3456 if (image_info->debug != MagickFalse)
3457 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3458 image_info->filename);
3460 GetPathComponent(image_info->filename,SubimagePath,subimage);
3461 if (*subimage != '\0')
3464 Look for scene specification (e.g. img0001.pcd[4]).
3466 if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse)
3468 if (IsGeometry(subimage) != MagickFalse)
3469 (void) CloneString(&image_info->extract,subimage);
3477 (void) CloneString(&image_info->scenes,subimage);
3478 image_info->scene=(unsigned long) atol(image_info->scenes);
3479 image_info->number_scenes=image_info->scene;
3480 p=image_info->scenes;
3481 for (q=(char *) image_info->scenes; *q != '\0'; p++)
3483 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
3485 first=(unsigned long) strtol(p,&q,10);
3487 while (isspace((int) ((unsigned char) *q)) != 0)
3490 last=(unsigned long) strtol(q+1,&q,10);
3493 if (first < image_info->scene)
3494 image_info->scene=first;
3495 if (last > image_info->number_scenes)
3496 image_info->number_scenes=last;
3499 image_info->number_scenes-=image_info->scene-1;
3500 image_info->subimage=image_info->scene;
3501 image_info->subrange=image_info->number_scenes;
3505 GetPathComponent(image_info->filename,ExtensionPath,extension);
3506 #if defined(MAGICKCORE_ZLIB_DELEGATE)
3507 if (*extension != '\0')
3508 if ((LocaleCompare(extension,"gz") == 0) ||
3509 (LocaleCompare(extension,"Z") == 0) ||
3510 (LocaleCompare(extension,"wmz") == 0))
3513 path[MaxTextExtent];
3515 (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
3516 path[strlen(path)-strlen(extension)-1]='\0';
3517 GetPathComponent(path,ExtensionPath,extension);
3520 #if defined(MAGICKCORE_BZLIB_DELEGATE)
3521 if (*extension != '\0')
3522 if (LocaleCompare(extension,"bz2") == 0)
3525 path[MaxTextExtent];
3527 (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
3528 path[strlen(path)-strlen(extension)-1]='\0';
3529 GetPathComponent(path,ExtensionPath,extension);
3532 image_info->affirm=MagickFalse;
3533 sans_exception=AcquireExceptionInfo();
3534 if (*extension != '\0')
3543 *format_type_formats[] =
3566 User specified image format.
3568 (void) CopyMagickString(magic,extension,MaxTextExtent);
3571 Look for explicit image formats.
3573 format_type=UndefinedFormatType;
3575 while ((format_type != UndefinedFormatType) &&
3576 (format_type_formats[i] != (char *) NULL))
3578 if ((*magic == *format_type_formats[i]) &&
3579 (LocaleCompare(magic,format_type_formats[i]) == 0))
3580 format_type=ExplicitFormatType;
3583 magick_info=GetMagickInfo(magic,sans_exception);
3584 if ((magick_info != (const MagickInfo *) NULL) &&
3585 (magick_info->format_type != UndefinedFormatType))
3586 format_type=magick_info->format_type;
3587 if (format_type == UndefinedFormatType)
3588 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
3590 if (format_type == ExplicitFormatType)
3592 image_info->affirm=MagickTrue;
3593 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
3595 if (LocaleCompare(magic,"RGB") == 0)
3596 image_info->affirm=MagickFalse; /* maybe SGI disguised as RGB */
3599 Look for explicit 'format:image' in filename.
3602 GetPathComponent(image_info->filename,MagickPath,magic);
3604 (void) CopyMagickString(magic,image_info->magick,MaxTextExtent);
3608 User specified image format.
3611 if (IsMagickConflict(magic) == MagickFalse)
3613 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
3614 if (LocaleCompare(magic,"EPHEMERAL") != 0)
3615 image_info->affirm=MagickTrue;
3617 image_info->temporary=MagickTrue;
3620 magick_info=GetMagickInfo(magic,sans_exception);
3621 sans_exception=DestroyExceptionInfo(sans_exception);
3622 if ((magick_info == (const MagickInfo *) NULL) ||
3623 (GetMagickEndianSupport(magick_info) == MagickFalse))
3624 image_info->endian=UndefinedEndian;
3625 GetPathComponent(image_info->filename,CanonicalPath,filename);
3626 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
3627 if (rectify != MagickFalse)
3630 Rectify multi-image file support.
3632 (void) InterpretImageFilename(image_info,(Image *) NULL,
3633 image_info->filename,(int) image_info->scene,filename);
3634 if ((LocaleCompare(filename,image_info->filename) != 0) &&
3635 (strchr(filename,'%') == (char *) NULL))
3636 image_info->adjoin=MagickFalse;
3637 magick_info=GetMagickInfo(magic,exception);
3638 if (magick_info != (const MagickInfo *) NULL)
3639 if (GetMagickAdjoin(magick_info) == MagickFalse)
3640 image_info->adjoin=MagickFalse;
3643 if (image_info->affirm != MagickFalse)
3646 Determine the image format from the first few bytes of the file.
3648 image=AcquireImage(image_info);
3649 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
3650 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3651 if (status == MagickFalse)
3653 image=DestroyImage(image);
3654 return(MagickFalse);
3656 if ((IsBlobSeekable(image) == MagickFalse) ||
3657 (IsBlobExempt(image) != MagickFalse))
3660 Copy standard input or pipe to temporary file.
3663 status=ImageToFile(image,filename,exception);
3664 (void) CloseBlob(image);
3665 if (status == MagickFalse)
3667 image=DestroyImage(image);
3668 return(MagickFalse);
3670 SetImageInfoFile(image_info,(FILE *) NULL);
3671 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
3672 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3673 if (status == MagickFalse)
3675 image=DestroyImage(image);
3676 return(MagickFalse);
3678 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
3679 image_info->temporary=MagickTrue;
3681 (void) ResetMagickMemory(magick,0,sizeof(magick));
3682 count=ReadBlob(image,2*MaxTextExtent,magick);
3683 (void) CloseBlob(image);
3684 image=DestroyImage(image);
3686 Check magic.xml configuration file.
3688 sans_exception=AcquireExceptionInfo();
3689 magic_info=GetMagicInfo(magick,(size_t) count,sans_exception);
3690 if ((magic_info != (const MagicInfo *) NULL) &&
3691 (GetMagicName(magic_info) != (char *) NULL))
3693 (void) CopyMagickString(image_info->magick,GetMagicName(magic_info),
3695 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3696 if ((magick_info == (const MagickInfo *) NULL) ||
3697 (GetMagickEndianSupport(magick_info) == MagickFalse))
3698 image_info->endian=UndefinedEndian;
3699 sans_exception=DestroyExceptionInfo(sans_exception);
3702 magick_info=GetMagickInfo(image_info->magick,sans_exception);
3703 if ((magick_info == (const MagickInfo *) NULL) ||
3704 (GetMagickEndianSupport(magick_info) == MagickFalse))
3705 image_info->endian=UndefinedEndian;
3706 sans_exception=DestroyExceptionInfo(sans_exception);
3711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3715 % S e t I m a g e I n f o B l o b %
3719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3721 % SetImageInfoBlob() sets the image info blob member.
3723 % The format of the SetImageInfoBlob method is:
3725 % void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
3726 % const size_t length)
3728 % A description of each parameter follows:
3730 % o image_info: the image info.
3734 % o length: the blob length.
3737 MagickExport void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
3738 const size_t length)
3740 assert(image_info != (ImageInfo *) NULL);
3741 assert(image_info->signature == MagickSignature);
3742 if (image_info->debug != MagickFalse)
3743 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3744 image_info->filename);
3745 image_info->blob=(void *) blob;
3746 image_info->length=length;
3750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754 % S e t I m a g e I n f o F i l e %
3758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3760 % SetImageInfoFile() sets the image info file member.
3762 % The format of the SetImageInfoFile method is:
3764 % void SetImageInfoFile(ImageInfo *image_info,FILE *file)
3766 % A description of each parameter follows:
3768 % o image_info: the image info.
3773 MagickExport void SetImageInfoFile(ImageInfo *image_info,FILE *file)
3775 assert(image_info != (ImageInfo *) NULL);
3776 assert(image_info->signature == MagickSignature);
3777 if (image_info->debug != MagickFalse)
3778 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3779 image_info->filename);
3780 image_info->file=file;
3784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3788 % S e t I m a g e M a s k %
3792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3794 % SetImageMask() associates a mask with the image. The mask must be the same
3795 % dimensions as the image.
3797 % The format of the SetImageMask method is:
3799 % MagickBooleanType SetImageMask(Image *image,const Image *mask)
3801 % A description of each parameter follows:
3803 % o image: the image.
3805 % o mask: the image mask.
3808 MagickExport MagickBooleanType SetImageMask(Image *image,
3811 assert(image != (Image *) NULL);
3812 if (image->debug != MagickFalse)
3813 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3814 assert(image->signature == MagickSignature);
3815 if (mask != (const Image *) NULL)
3816 if ((mask->columns != image->columns) || (mask->rows != image->rows))
3817 ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
3818 if (image->mask != (Image *) NULL)
3819 image->mask=DestroyImage(image->mask);
3820 image->mask=NewImageList();
3821 if (mask == (Image *) NULL)
3823 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
3824 return(MagickFalse);
3825 image->mask=CloneImage(mask,0,0,MagickTrue,&image->exception);
3826 if (image->mask == (Image *) NULL)
3827 return(MagickFalse);
3832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3836 % S e t I m a g e O p a c i t y %
3840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3842 % SetImageOpacity() sets the opacity levels of the image.
3844 % The format of the SetImageOpacity method is:
3846 % MagickBooleanType SetImageOpacity(Image *image,const Quantum opacity)
3848 % A description of each parameter follows:
3850 % o image: the image.
3852 % o opacity: the level of transparency: 0 is fully opaque and QuantumRange is
3853 % fully transparent.
3856 MagickExport MagickBooleanType SetImageOpacity(Image *image,
3857 const Quantum opacity)
3871 assert(image != (Image *) NULL);
3872 if (image->debug != MagickFalse)
3873 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3874 assert(image->signature == MagickSignature);
3875 image->matte=opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
3877 exception=(&image->exception);
3878 image_view=AcquireCacheView(image);
3879 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3880 #pragma omp parallel for schedule(dynamic,4) shared(status)
3882 for (y=0; y < (long) image->rows; y++)
3887 register PixelPacket
3890 if (status == MagickFalse)
3892 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3893 if (q == (PixelPacket *) NULL)
3898 for (x=0; x < (long) image->columns; x++)
3903 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3906 image_view=DestroyCacheView(image_view);
3911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3915 % S e t I m a g e T y p e %
3919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3921 % SetImageType() sets the type of image. Choose from these types:
3923 % Bilevel Grayscale GrayscaleMatte
3924 % Palette PaletteMatte TrueColor
3925 % TrueColorMatte ColorSeparation ColorSeparationMatte
3928 % The format of the SetImageType method is:
3930 % MagickBooleanType SetImageType(Image *image,const ImageType type)
3932 % A description of each parameter follows:
3934 % o image: the image.
3936 % o type: Image type.
3939 MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type)
3953 assert(image != (Image *) NULL);
3954 if (image->debug != MagickFalse)
3955 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3956 assert(image->signature == MagickSignature);
3958 image_info=AcquireImageInfo();
3959 image_info->dither=image->dither;
3960 artifact=GetImageArtifact(image,"dither");
3961 if (artifact != (const char *) NULL)
3962 (void) SetImageOption(image_info,"dither",artifact);
3967 if (IsGrayImage(image,&image->exception) == MagickFalse)
3968 status=TransformImageColorspace(image,GRAYColorspace);
3969 if (IsMonochromeImage(image,&image->exception) == MagickFalse)
3971 quantize_info=AcquireQuantizeInfo(image_info);
3972 quantize_info->number_colors=2;
3973 quantize_info->colorspace=GRAYColorspace;
3974 status=QuantizeImage(quantize_info,image);
3975 quantize_info=DestroyQuantizeInfo(quantize_info);
3977 image->matte=MagickFalse;
3982 if (IsGrayImage(image,&image->exception) == MagickFalse)
3983 status=TransformImageColorspace(image,GRAYColorspace);
3984 image->matte=MagickFalse;
3987 case GrayscaleMatteType:
3989 if (IsGrayImage(image,&image->exception) == MagickFalse)
3990 status=TransformImageColorspace(image,GRAYColorspace);
3991 if (image->matte == MagickFalse)
3992 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
3997 if (image->colorspace != RGBColorspace)
3998 status=TransformImageColorspace(image,RGBColorspace);
3999 if ((image->storage_class == DirectClass) || (image->colors > 256))
4001 quantize_info=AcquireQuantizeInfo(image_info);
4002 quantize_info->number_colors=256;
4003 status=QuantizeImage(quantize_info,image);
4004 quantize_info=DestroyQuantizeInfo(quantize_info);
4006 image->matte=MagickFalse;
4009 case PaletteBilevelMatteType:
4011 if (image->colorspace != RGBColorspace)
4012 status=TransformImageColorspace(image,RGBColorspace);
4013 if (image->matte == MagickFalse)
4014 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
4015 (void) BilevelImageChannel(image,AlphaChannel,(double) QuantumRange/2.0);
4016 quantize_info=AcquireQuantizeInfo(image_info);
4017 status=QuantizeImage(quantize_info,image);
4018 quantize_info=DestroyQuantizeInfo(quantize_info);
4021 case PaletteMatteType:
4023 if (image->colorspace != RGBColorspace)
4024 status=TransformImageColorspace(image,RGBColorspace);
4025 if (image->matte == MagickFalse)
4026 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
4027 quantize_info=AcquireQuantizeInfo(image_info);
4028 quantize_info->colorspace=TransparentColorspace;
4029 status=QuantizeImage(quantize_info,image);
4030 quantize_info=DestroyQuantizeInfo(quantize_info);
4035 if (image->colorspace != RGBColorspace)
4036 status=TransformImageColorspace(image,RGBColorspace);
4037 if (image->storage_class != DirectClass)
4038 status=SetImageStorageClass(image,DirectClass);
4039 image->matte=MagickFalse;
4042 case TrueColorMatteType:
4044 if (image->colorspace != RGBColorspace)
4045 status=TransformImageColorspace(image,RGBColorspace);
4046 if (image->storage_class != DirectClass)
4047 status=SetImageStorageClass(image,DirectClass);
4048 if (image->matte == MagickFalse)
4049 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
4052 case ColorSeparationType:
4054 if (image->colorspace != CMYKColorspace)
4056 if (image->colorspace != RGBColorspace)
4057 status=TransformImageColorspace(image,RGBColorspace);
4058 status=TransformImageColorspace(image,CMYKColorspace);
4060 if (image->storage_class != DirectClass)
4061 status=SetImageStorageClass(image,DirectClass);
4062 image->matte=MagickFalse;
4065 case ColorSeparationMatteType:
4067 if (image->colorspace != CMYKColorspace)
4069 if (image->colorspace != RGBColorspace)
4070 status=TransformImageColorspace(image,RGBColorspace);
4071 status=TransformImageColorspace(image,CMYKColorspace);
4073 if (image->storage_class != DirectClass)
4074 status=SetImageStorageClass(image,DirectClass);
4075 if (image->matte == MagickFalse)
4076 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
4084 image_info=DestroyImageInfo(image_info);
4089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4093 % 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 %
4097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4099 % SetImageVirtualPixelMethod() sets the "virtual pixels" method for the
4100 % image and returns the previous setting. A virtual pixel is any pixel access
4101 % that is outside the boundaries of the image cache.
4103 % The format of the SetImageVirtualPixelMethod() method is:
4105 % VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
4106 % const VirtualPixelMethod virtual_pixel_method)
4108 % A description of each parameter follows:
4110 % o image: the image.
4112 % o virtual_pixel_method: choose the type of virtual pixel.
4115 MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
4116 const VirtualPixelMethod virtual_pixel_method)
4118 assert(image != (const Image *) NULL);
4119 assert(image->signature == MagickSignature);
4120 if (image->debug != MagickFalse)
4121 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4122 return(SetPixelCacheVirtualMethod(image,virtual_pixel_method));
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4130 + S o r t C o l o r m a p B y I n t e n s i t y %
4134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4136 % SortColormapByIntensity() sorts the colormap of a PseudoClass image by
4137 % decreasing color intensity.
4139 % The format of the SortColormapByIntensity method is:
4141 % MagickBooleanType SortColormapByIntensity(Image *image)
4143 % A description of each parameter follows:
4145 % o image: A pointer to an Image structure.
4149 #if defined(__cplusplus) || defined(c_plusplus)
4153 static int IntensityCompare(const void *x,const void *y)
4162 color_1=(const PixelPacket *) x;
4163 color_2=(const PixelPacket *) y;
4164 intensity=(int) PixelIntensityToQuantum(color_2)-
4165 (int) PixelIntensityToQuantum(color_1);
4169 #if defined(__cplusplus) || defined(c_plusplus)
4173 MagickExport MagickBooleanType SortColormapByIntensity(Image *image)
4193 assert(image != (Image *) NULL);
4194 if (image->debug != MagickFalse)
4195 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4196 assert(image->signature == MagickSignature);
4197 if (image->storage_class != PseudoClass)
4200 Allocate memory for pixel indexes.
4202 pixels=(unsigned short *) AcquireQuantumMemory((size_t) image->colors,
4204 if (pixels == (unsigned short *) NULL)
4205 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4208 Assign index values to colormap entries.
4210 #if defined(MAGICKCORE_OPENMP_SUPPORT)
4211 #pragma omp parallel for schedule(dynamic,4) shared(status)
4213 for (i=0; i < (long) image->colors; i++)
4214 image->colormap[i].opacity=(IndexPacket) i;
4216 Sort image colormap by decreasing color popularity.
4218 qsort((void *) image->colormap,(size_t) image->colors,
4219 sizeof(*image->colormap),IntensityCompare);
4221 Update image colormap indexes to sorted colormap order.
4223 #if defined(MAGICKCORE_OPENMP_SUPPORT)
4224 #pragma omp parallel for schedule(dynamic,4) shared(status)
4226 for (i=0; i < (long) image->colors; i++)
4227 pixels[(long) image->colormap[i].opacity]=(unsigned short) i;
4229 exception=(&image->exception);
4230 image_view=AcquireCacheView(image);
4231 for (y=0; y < (long) image->rows; y++)
4239 register IndexPacket
4240 *__restrict indexes;
4242 register PixelPacket
4245 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
4246 if (q == (PixelPacket *) NULL)
4251 indexes=GetCacheViewAuthenticIndexQueue(image_view);
4252 for (x=0; x < (long) image->columns; x++)
4254 index=(IndexPacket) pixels[(long) indexes[x]];
4256 *q++=image->colormap[(long) index];
4258 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4260 if (status == MagickFalse)
4263 image_view=DestroyCacheView(image_view);
4264 pixels=(unsigned short *) RelinquishMagickMemory(pixels);
4269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4273 % S t r i p I m a g e %
4277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4279 % StripImage() strips an image of all profiles and comments.
4281 % The format of the StripImage method is:
4283 % MagickBooleanType StripImage(Image *image)
4285 % A description of each parameter follows:
4287 % o image: the image.
4290 MagickExport MagickBooleanType StripImage(Image *image)
4292 assert(image != (Image *) NULL);
4293 if (image->debug != MagickFalse)
4294 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4295 DestroyImageProfiles(image);
4296 (void) DeleteImageProperty(image,"comment");
4301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4305 + S y n c I m a g e %
4309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4311 % SyncImage() initializes the red, green, and blue intensities of each pixel
4312 % as defined by the colormap index.
4314 % The format of the SyncImage method is:
4316 % MagickBooleanType SyncImage(Image *image)
4318 % A description of each parameter follows:
4320 % o image: the image.
4324 static inline IndexPacket PushColormapIndex(Image *image,
4325 const unsigned long index,MagickBooleanType *range_exception)
4327 if (index < image->colors)
4328 return((IndexPacket) index);
4329 *range_exception=MagickTrue;
4330 return((IndexPacket) 0);
4333 MagickExport MagickBooleanType SyncImage(Image *image)
4348 assert(image != (Image *) NULL);
4349 if (image->debug != MagickFalse)
4350 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4351 assert(image->signature == MagickSignature);
4352 if (image->storage_class == DirectClass)
4353 return(MagickFalse);
4354 range_exception=MagickFalse;
4356 exception=(&image->exception);
4357 image_view=AcquireCacheView(image);
4358 for (y=0; y < (long) image->rows; y++)
4366 register IndexPacket
4367 *__restrict indexes;
4372 register PixelPacket
4375 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
4376 if (q == (PixelPacket *) NULL)
4381 indexes=GetCacheViewAuthenticIndexQueue(image_view);
4382 for (x=0; x < (long) image->columns; x++)
4384 index=PushColormapIndex(image,(unsigned long) indexes[x],
4386 pixel=image->colormap[(long) index];
4388 q->green=pixel.green;
4392 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4394 if (status == MagickFalse)
4397 image_view=DestroyCacheView(image_view);
4398 if (range_exception != MagickFalse)
4399 (void) ThrowMagickException(&image->exception,GetMagickModule(),
4400 CorruptImageError,"InvalidColormapIndex","`%s'",image->filename);
4405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4409 % T e x t u r e I m a g e %
4413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4415 % TextureImage() repeatedly tiles the texture image across and down the image
4418 % The format of the TextureImage method is:
4420 % MagickBooleanType TextureImage(Image *image,const Image *texture)
4422 % A description of each parameter follows:
4424 % o image: the image.
4426 % o texture: This image is the texture to layer on the background.
4429 MagickExport MagickBooleanType TextureImage(Image *image,const Image *texture)
4431 #define TextureImageTag "Texture/Image"
4442 assert(image != (Image *) NULL);
4443 if (image->debug != MagickFalse)
4444 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4445 assert(image->signature == MagickSignature);
4446 if (texture == (const Image *) NULL)
4447 return(MagickFalse);
4448 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
4449 return(MagickFalse);
4451 Tile texture onto the image background.
4454 exception=(&image->exception);
4455 for (y=0; y < (long) image->rows; y+=texture->rows)
4460 for (x=0; x < (long) image->columns; x+=texture->columns)
4461 status|=CompositeImage(image,image->compose,texture,x+
4462 texture->tile_offset.x,y+texture->tile_offset.y);
4463 if (image->progress_monitor != (MagickProgressMonitor) NULL)
4468 proceed=SetImageProgress(image,TextureImageTag,y,image->rows);
4469 if (proceed == MagickFalse)
4473 (void) SetImageProgress(image,TextureImageTag,image->rows,image->rows);
4474 return(status != 0 ? MagickTrue : MagickFalse);