MagickCore  7.0.4
image.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % IIIII M M AAA GGGG EEEEE %
7 % I MM MM A A G E %
8 % I M M M AAAAA G GG EEE %
9 % I M M A A G G E %
10 % IIIII M M A A GGGG EEEEE %
11 % %
12 % %
13 % MagickCore Image Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % http://www.imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/animate.h"
45 #include "MagickCore/artifact.h"
46 #include "MagickCore/attribute.h"
47 #include "MagickCore/blob.h"
49 #include "MagickCore/cache.h"
51 #include "MagickCore/cache-view.h"
52 #include "MagickCore/channel.h"
53 #include "MagickCore/client.h"
54 #include "MagickCore/color.h"
56 #include "MagickCore/colormap.h"
57 #include "MagickCore/colorspace.h"
59 #include "MagickCore/composite.h"
61 #include "MagickCore/compress.h"
62 #include "MagickCore/constitute.h"
63 #include "MagickCore/delegate.h"
64 #include "MagickCore/display.h"
65 #include "MagickCore/draw.h"
66 #include "MagickCore/enhance.h"
67 #include "MagickCore/exception.h"
69 #include "MagickCore/gem.h"
70 #include "MagickCore/geometry.h"
71 #include "MagickCore/histogram.h"
73 #include "MagickCore/list.h"
74 #include "MagickCore/magic.h"
75 #include "MagickCore/magick.h"
77 #include "MagickCore/memory_.h"
78 #include "MagickCore/module.h"
79 #include "MagickCore/monitor.h"
81 #include "MagickCore/option.h"
82 #include "MagickCore/paint.h"
84 #include "MagickCore/profile.h"
85 #include "MagickCore/property.h"
86 #include "MagickCore/quantize.h"
87 #include "MagickCore/random_.h"
88 #include "MagickCore/resource_.h"
89 #include "MagickCore/segment.h"
90 #include "MagickCore/semaphore.h"
92 #include "MagickCore/statistic.h"
93 #include "MagickCore/string_.h"
96 #include "MagickCore/threshold.h"
97 #include "MagickCore/timer.h"
98 #include "MagickCore/token.h"
99 #include "MagickCore/utility.h"
101 #include "MagickCore/version.h"
103 
104 /*
105  Constant declaration.
106 */
107 const char
108  AlphaColor[] = "#bdbdbd", /* gray */
109  BackgroundColor[] = "#ffffff", /* white */
110  BorderColor[] = "#dfdfdf", /* gray */
111  DefaultTileFrame[] = "15x15+3+3",
112  DefaultTileGeometry[] = "120x120+4+3>",
113  DefaultTileLabel[] = "%f\n%G\n%b",
114  ForegroundColor[] = "#000", /* black */
115  LoadImageTag[] = "Load/Image",
116  LoadImagesTag[] = "Load/Images",
117  PSDensityGeometry[] = "72.0x72.0",
118  PSPageGeometry[] = "612x792",
119  SaveImageTag[] = "Save/Image",
120  SaveImagesTag[] = "Save/Images",
121  TransparentColor[] = "#00000000"; /* transparent black */
122 
123 const double
125 
126 /*
127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % %
129 % %
130 % %
131 % A c q u i r e I m a g e %
132 % %
133 % %
134 % %
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 %
137 % AcquireImage() returns a pointer to an image structure initialized to
138 % default values.
139 %
140 % The format of the AcquireImage method is:
141 %
142 % Image *AcquireImage(const ImageInfo *image_info,ExceptionInfo *exception)
143 %
144 % A description of each parameter follows:
145 %
146 % o image_info: Many of the image default values are set from this
147 % structure. For example, filename, compression, depth, background color,
148 % and others.
149 %
150 % o exception: return any errors or warnings in this structure.
151 %
152 */
155 {
156  const char
157  *option;
158 
159  Image
160  *image;
161 
163  flags;
164 
165  /*
166  Allocate image structure.
167  */
168  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
169  image=(Image *) AcquireMagickMemory(sizeof(*image));
170  if (image == (Image *) NULL)
171  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
172  (void) ResetMagickMemory(image,0,sizeof(*image));
173  /*
174  Initialize Image structure.
175  */
176  (void) CopyMagickString(image->magick,"MIFF",MagickPathExtent);
177  image->storage_class=DirectClass;
179  image->colorspace=sRGBColorspace;
181  image->gamma=1.000f/2.200f;
182  image->chromaticity.red_primary.x=0.6400f;
183  image->chromaticity.red_primary.y=0.3300f;
184  image->chromaticity.red_primary.z=0.0300f;
185  image->chromaticity.green_primary.x=0.3000f;
186  image->chromaticity.green_primary.y=0.6000f;
187  image->chromaticity.green_primary.z=0.1000f;
188  image->chromaticity.blue_primary.x=0.1500f;
189  image->chromaticity.blue_primary.y=0.0600f;
190  image->chromaticity.blue_primary.z=0.7900f;
191  image->chromaticity.white_point.x=0.3127f;
192  image->chromaticity.white_point.y=0.3290f;
193  image->chromaticity.white_point.z=0.3583f;
194  image->interlace=NoInterlace;
196  image->compose=OverCompositeOp;
198  exception);
200  &image->background_color,exception);
202  exception);
204  &image->transparent_color,exception);
205  GetTimerInfo(&image->timer);
206  image->cache=AcquirePixelCache(0);
209  image->blob=CloneBlobInfo((BlobInfo *) NULL);
210  image->timestamp=time((time_t *) NULL);
211  image->debug=IsEventLogging();
212  image->reference_count=1;
215  if (image_info == (ImageInfo *) NULL)
216  return(image);
217  /*
218  Transfer image info.
219  */
220  SetBlobExempt(image,image_info->file != (FILE *) NULL ? MagickTrue :
221  MagickFalse);
222  (void) CopyMagickString(image->filename,image_info->filename,
224  (void) CopyMagickString(image->magick_filename,image_info->filename,
226  (void) CopyMagickString(image->magick,image_info->magick,MagickPathExtent);
227  if (image_info->size != (char *) NULL)
228  {
229  (void) ParseAbsoluteGeometry(image_info->size,&image->extract_info);
230  image->columns=image->extract_info.width;
231  image->rows=image->extract_info.height;
232  image->offset=image->extract_info.x;
233  image->extract_info.x=0;
234  image->extract_info.y=0;
235  }
236  if (image_info->extract != (char *) NULL)
237  {
239  geometry;
240 
241  flags=ParseAbsoluteGeometry(image_info->extract,&geometry);
242  if (((flags & XValue) != 0) || ((flags & YValue) != 0))
243  {
244  image->extract_info=geometry;
245  Swap(image->columns,image->extract_info.width);
246  Swap(image->rows,image->extract_info.height);
247  }
248  }
249  image->compression=image_info->compression;
250  image->quality=image_info->quality;
251  image->endian=image_info->endian;
252  image->interlace=image_info->interlace;
253  image->units=image_info->units;
254  if (image_info->density != (char *) NULL)
255  {
257  geometry_info;
258 
259  flags=ParseGeometry(image_info->density,&geometry_info);
260  image->resolution.x=geometry_info.rho;
261  image->resolution.y=geometry_info.sigma;
262  if ((flags & SigmaValue) == 0)
263  image->resolution.y=image->resolution.x;
264  }
265  if (image_info->page != (char *) NULL)
266  {
267  char
268  *geometry;
269 
270  image->page=image->extract_info;
271  geometry=GetPageGeometry(image_info->page);
272  (void) ParseAbsoluteGeometry(geometry,&image->page);
273  geometry=DestroyString(geometry);
274  }
275  if (image_info->depth != 0)
276  image->depth=image_info->depth;
277  image->dither=image_info->dither;
278  image->alpha_color=image_info->alpha_color;
279  image->background_color=image_info->background_color;
280  image->border_color=image_info->border_color;
281  image->transparent_color=image_info->transparent_color;
282  image->ping=image_info->ping;
283  image->progress_monitor=image_info->progress_monitor;
284  image->client_data=image_info->client_data;
285  if (image_info->cache != (void *) NULL)
286  ClonePixelCacheMethods(image->cache,image_info->cache);
287  /*
288  Set all global options that map to per-image settings.
289  */
290  (void) SyncImageSettings(image_info,image,exception);
291  /*
292  Global options that are only set for new images.
293  */
294  option=GetImageOption(image_info,"delay");
295  if (option != (const char *) NULL)
296  {
298  geometry_info;
299 
300  flags=ParseGeometry(option,&geometry_info);
301  if ((flags & GreaterValue) != 0)
302  {
303  if (image->delay > (size_t) floor(geometry_info.rho+0.5))
304  image->delay=(size_t) floor(geometry_info.rho+0.5);
305  }
306  else
307  if ((flags & LessValue) != 0)
308  {
309  if (image->delay < (size_t) floor(geometry_info.rho+0.5))
310  image->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
311  }
312  else
313  image->delay=(size_t) floor(geometry_info.rho+0.5);
314  if ((flags & SigmaValue) != 0)
315  image->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5);
316  }
317  option=GetImageOption(image_info,"dispose");
318  if (option != (const char *) NULL)
320  MagickFalse,option);
321  return(image);
322 }
323 
324 /*
325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 % %
327 % %
328 % %
329 % A c q u i r e I m a g e I n f o %
330 % %
331 % %
332 % %
333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334 %
335 % AcquireImageInfo() allocates the ImageInfo structure.
336 %
337 % The format of the AcquireImageInfo method is:
338 %
339 % ImageInfo *AcquireImageInfo(void)
340 %
341 */
343 {
344  ImageInfo
345  *image_info;
346 
347  image_info=(ImageInfo *) AcquireMagickMemory(sizeof(*image_info));
348  if (image_info == (ImageInfo *) NULL)
349  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
350  GetImageInfo(image_info);
351  return(image_info);
352 }
353 
354 /*
355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 % %
357 % %
358 % %
359 % A c q u i r e N e x t I m a g e %
360 % %
361 % %
362 % %
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 %
365 % AcquireNextImage() initializes the next image in a sequence to
366 % default values. The next member of image points to the newly allocated
367 % image. If there is a memory shortage, next is assigned NULL.
368 %
369 % The format of the AcquireNextImage method is:
370 %
371 % void AcquireNextImage(const ImageInfo *image_info,Image *image,
372 % ExceptionInfo *exception)
373 %
374 % A description of each parameter follows:
375 %
376 % o image_info: Many of the image default values are set from this
377 % structure. For example, filename, compression, depth, background color,
378 % and others.
379 %
380 % o image: the image.
381 %
382 % o exception: return any errors or warnings in this structure.
383 %
384 */
387 {
388  /*
389  Allocate image structure.
390  */
391  assert(image != (Image *) NULL);
392  assert(image->signature == MagickCoreSignature);
393  if (image->debug != MagickFalse)
394  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
395  image->next=AcquireImage(image_info,exception);
396  if (GetNextImageInList(image) == (Image *) NULL)
397  return;
400  if (image_info != (ImageInfo *) NULL)
401  (void) CopyMagickString(GetNextImageInList(image)->filename,
402  image_info->filename,MagickPathExtent);
404  image->next->blob=ReferenceBlob(image->blob);
405  image->next->endian=image->endian;
406  image->next->scene=image->scene+1;
407  image->next->previous=image;
408 }
409 
410 /*
411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 % %
413 % %
414 % %
415 % A p p e n d I m a g e s %
416 % %
417 % %
418 % %
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420 %
421 % AppendImages() takes all images from the current image pointer to the end
422 % of the image list and appends them to each other top-to-bottom if the
423 % stack parameter is true, otherwise left-to-right.
424 %
425 % The current gravity setting effects how the image is justified in the
426 % final image.
427 %
428 % The format of the AppendImages method is:
429 %
430 % Image *AppendImages(const Image *images,const MagickBooleanType stack,
431 % ExceptionInfo *exception)
432 %
433 % A description of each parameter follows:
434 %
435 % o images: the image sequence.
436 %
437 % o stack: A value other than 0 stacks the images top-to-bottom.
438 %
439 % o exception: return any errors or warnings in this structure.
440 %
441 */
444 {
445 #define AppendImageTag "Append/Image"
446 
447  CacheView
448  *append_view;
449 
450  Image
451  *append_image;
452 
454  homogeneous_colorspace,
455  status;
456 
458  n;
459 
460  PixelTrait
461  alpha_trait;
462 
464  geometry;
465 
466  register const Image
467  *next;
468 
469  size_t
470  depth,
471  height,
472  number_images,
473  width;
474 
475  ssize_t
476  x_offset,
477  y,
478  y_offset;
479 
480  /*
481  Compute maximum area of appended area.
482  */
483  assert(images != (Image *) NULL);
484  assert(images->signature == MagickCoreSignature);
485  if (images->debug != MagickFalse)
486  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
487  assert(exception != (ExceptionInfo *) NULL);
488  assert(exception->signature == MagickCoreSignature);
489  alpha_trait=images->alpha_trait;
490  number_images=1;
491  width=images->columns;
492  height=images->rows;
493  depth=images->depth;
494  homogeneous_colorspace=MagickTrue;
495  next=GetNextImageInList(images);
496  for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
497  {
498  if (next->depth > depth)
499  depth=next->depth;
500  if (next->colorspace != images->colorspace)
501  homogeneous_colorspace=MagickFalse;
502  if (next->alpha_trait != UndefinedPixelTrait)
503  alpha_trait=BlendPixelTrait;
504  number_images++;
505  if (stack != MagickFalse)
506  {
507  if (next->columns > width)
508  width=next->columns;
509  height+=next->rows;
510  continue;
511  }
512  width+=next->columns;
513  if (next->rows > height)
514  height=next->rows;
515  }
516  /*
517  Append images.
518  */
519  append_image=CloneImage(images,width,height,MagickTrue,exception);
520  if (append_image == (Image *) NULL)
521  return((Image *) NULL);
522  if (SetImageStorageClass(append_image,DirectClass,exception) == MagickFalse)
523  {
524  append_image=DestroyImage(append_image);
525  return((Image *) NULL);
526  }
527  if (homogeneous_colorspace == MagickFalse)
528  (void) SetImageColorspace(append_image,sRGBColorspace,exception);
529  append_image->depth=depth;
530  append_image->alpha_trait=alpha_trait;
531  append_image->page=images->page;
532  (void) SetImageBackgroundColor(append_image,exception);
533  status=MagickTrue;
534  x_offset=0;
535  y_offset=0;
536  next=images;
537  append_view=AcquireAuthenticCacheView(append_image,exception);
538  for (n=0; n < (MagickOffsetType) number_images; n++)
539  {
540  CacheView
541  *image_view;
542 
544  proceed;
545 
546  SetGeometry(append_image,&geometry);
547  GravityAdjustGeometry(next->columns,next->rows,next->gravity,&geometry);
548  if (stack != MagickFalse)
549  x_offset-=geometry.x;
550  else
551  y_offset-=geometry.y;
552  image_view=AcquireVirtualCacheView(next,exception);
553 #if defined(MAGICKCORE_OPENMP_SUPPORT)
554  #pragma omp parallel for schedule(static,4) shared(status) \
555  magick_threads(next,next,next->rows,1)
556 #endif
557  for (y=0; y < (ssize_t) next->rows; y++)
558  {
560  sync;
561 
562  PixelInfo
563  pixel;
564 
565  register const Quantum
566  *magick_restrict p;
567 
568  register Quantum
569  *magick_restrict q;
570 
571  register ssize_t
572  x;
573 
574  if (status == MagickFalse)
575  continue;
576  p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
577  q=QueueCacheViewAuthenticPixels(append_view,x_offset,y+y_offset,
578  next->columns,1,exception);
579  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
580  {
581  status=MagickFalse;
582  continue;
583  }
584  GetPixelInfo(next,&pixel);
585  for (x=0; x < (ssize_t) next->columns; x++)
586  {
587  if (GetPixelWriteMask(next,p) == 0)
588  {
589  SetPixelBackgoundColor(append_image,q);
590  p+=GetPixelChannels(next);
591  q+=GetPixelChannels(append_image);
592  continue;
593  }
594  GetPixelInfoPixel(next,p,&pixel);
595  SetPixelViaPixelInfo(append_image,&pixel,q);
596  p+=GetPixelChannels(next);
597  q+=GetPixelChannels(append_image);
598  }
599  sync=SyncCacheViewAuthenticPixels(append_view,exception);
600  if (sync == MagickFalse)
601  status=MagickFalse;
602  }
603  image_view=DestroyCacheView(image_view);
604  if (stack == MagickFalse)
605  {
606  x_offset+=(ssize_t) next->columns;
607  y_offset=0;
608  }
609  else
610  {
611  x_offset=0;
612  y_offset+=(ssize_t) next->rows;
613  }
614  proceed=SetImageProgress(append_image,AppendImageTag,n,number_images);
615  if (proceed == MagickFalse)
616  break;
617  next=GetNextImageInList(next);
618  }
619  append_view=DestroyCacheView(append_view);
620  if (status == MagickFalse)
621  append_image=DestroyImage(append_image);
622  return(append_image);
623 }
624 
625 /*
626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
627 % %
628 % %
629 % %
630 % C a t c h I m a g e E x c e p t i o n %
631 % %
632 % %
633 % %
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 %
636 % CatchImageException() returns if no exceptions are found in the image
637 % sequence, otherwise it determines the most severe exception and reports
638 % it as a warning or error depending on the severity.
639 %
640 % The format of the CatchImageException method is:
641 %
642 % ExceptionType CatchImageException(Image *image)
643 %
644 % A description of each parameter follows:
645 %
646 % o image: An image sequence.
647 %
648 */
650 {
652  *exception;
653 
655  severity;
656 
657  assert(image != (const Image *) NULL);
658  assert(image->signature == MagickCoreSignature);
659  if (image->debug != MagickFalse)
660  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
661  exception=AcquireExceptionInfo();
662  CatchException(exception);
663  severity=exception->severity;
664  exception=DestroyExceptionInfo(exception);
665  return(severity);
666 }
667 
668 /*
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 % %
671 % %
672 % %
673 % C l i p I m a g e P a t h %
674 % %
675 % %
676 % %
677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 %
679 % ClipImagePath() sets the image clip mask based any clipping path information
680 % if it exists.
681 %
682 % The format of the ClipImagePath method is:
683 %
684 % MagickBooleanType ClipImagePath(Image *image,const char *pathname,
685 % const MagickBooleanType inside,ExceptionInfo *exception)
686 %
687 % A description of each parameter follows:
688 %
689 % o image: the image.
690 %
691 % o pathname: name of clipping path resource. If name is preceded by #, use
692 % clipping path numbered by name.
693 %
694 % o inside: if non-zero, later operations take effect inside clipping path.
695 % Otherwise later operations take effect outside clipping path.
696 %
697 % o exception: return any errors or warnings in this structure.
698 %
699 */
700 
702 {
703  return(ClipImagePath(image,"#1",MagickTrue,exception));
704 }
705 
708 {
709 #define ClipImagePathTag "ClipPath/Image"
710 
711  char
712  *property;
713 
714  const char
715  *value;
716 
717  Image
718  *clip_mask;
719 
720  ImageInfo
721  *image_info;
722 
723  assert(image != (const Image *) NULL);
724  assert(image->signature == MagickCoreSignature);
725  if (image->debug != MagickFalse)
726  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
727  assert(pathname != NULL);
728  property=AcquireString(pathname);
729  (void) FormatLocaleString(property,MagickPathExtent,"8BIM:1999,2998:%s",
730  pathname);
731  value=GetImageProperty(image,property,exception);
732  property=DestroyString(property);
733  if (value == (const char *) NULL)
734  {
735  ThrowFileException(exception,OptionError,"NoClipPathDefined",
736  image->filename);
737  return(MagickFalse);
738  }
739  image_info=AcquireImageInfo();
740  (void) CopyMagickString(image_info->filename,image->filename,
742  (void) ConcatenateMagickString(image_info->filename,pathname,
744  clip_mask=BlobToImage(image_info,value,strlen(value),exception);
745  image_info=DestroyImageInfo(image_info);
746  if (clip_mask == (Image *) NULL)
747  return(MagickFalse);
748  if (clip_mask->storage_class == PseudoClass)
749  {
750  (void) SyncImage(clip_mask,exception);
751  if (SetImageStorageClass(clip_mask,DirectClass,exception) == MagickFalse)
752  return(MagickFalse);
753  }
754  if (inside == MagickFalse)
755  (void) NegateImage(clip_mask,MagickFalse,exception);
757  "8BIM:1999,2998:%s\nPS",pathname);
758  (void) SetImageMask(image,WritePixelMask,clip_mask,exception);
759  clip_mask=DestroyImage(clip_mask);
760  return(MagickTrue);
761 }
762 
763 /*
764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765 % %
766 % %
767 % %
768 % C l o n e I m a g e %
769 % %
770 % %
771 % %
772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 %
774 % CloneImage() copies an image and returns the copy as a new image object.
775 %
776 % If the specified columns and rows is 0, an exact copy of the image is
777 % returned, otherwise the pixel data is undefined and must be initialized
778 % with the QueueAuthenticPixels() and SyncAuthenticPixels() methods. On
779 % failure, a NULL image is returned and exception describes the reason for the
780 % failure.
781 %
782 % The format of the CloneImage method is:
783 %
784 % Image *CloneImage(const Image *image,const size_t columns,
785 % const size_t rows,const MagickBooleanType orphan,
786 % ExceptionInfo *exception)
787 %
788 % A description of each parameter follows:
789 %
790 % o image: the image.
791 %
792 % o columns: the number of columns in the cloned image.
793 %
794 % o rows: the number of rows in the cloned image.
795 %
796 % o detach: With a value other than 0, the cloned image is detached from
797 % its parent I/O stream.
798 %
799 % o exception: return any errors or warnings in this structure.
800 %
801 */
802 MagickExport Image *CloneImage(const Image *image,const size_t columns,
803  const size_t rows,const MagickBooleanType detach,ExceptionInfo *exception)
804 {
805  Image
806  *clone_image;
807 
808  double
809  scale;
810 
811  size_t
812  length;
813 
814  /*
815  Clone the image.
816  */
817  assert(image != (const Image *) NULL);
818  assert(image->signature == MagickCoreSignature);
819  if (image->debug != MagickFalse)
820  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
821  assert(exception != (ExceptionInfo *) NULL);
822  assert(exception->signature == MagickCoreSignature);
823  if ((image->columns == 0) || (image->rows == 0))
824  {
826  "NegativeOrZeroImageSize","`%s'",image->filename);
827  return((Image *) NULL);
828  }
829  clone_image=(Image *) AcquireMagickMemory(sizeof(*clone_image));
830  if (clone_image == (Image *) NULL)
831  ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
832  (void) ResetMagickMemory(clone_image,0,sizeof(*clone_image));
833  clone_image->signature=MagickCoreSignature;
834  clone_image->storage_class=image->storage_class;
835  clone_image->number_channels=image->number_channels;
836  clone_image->number_meta_channels=image->number_meta_channels;
837  clone_image->metacontent_extent=image->metacontent_extent;
838  clone_image->colorspace=image->colorspace;
839  clone_image->read_mask=image->read_mask;
840  clone_image->write_mask=image->write_mask;
841  clone_image->alpha_trait=image->alpha_trait;
842  clone_image->columns=image->columns;
843  clone_image->rows=image->rows;
844  clone_image->dither=image->dither;
845  if (image->colormap != (PixelInfo *) NULL)
846  {
847  /*
848  Allocate and copy the image colormap.
849  */
850  clone_image->colors=image->colors;
851  length=(size_t) image->colors;
852  clone_image->colormap=(PixelInfo *) AcquireQuantumMemory(length,
853  sizeof(*clone_image->colormap));
854  if (clone_image->colormap == (PixelInfo *) NULL)
855  {
856  clone_image=DestroyImage(clone_image);
857  ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
858  }
859  (void) CopyMagickMemory(clone_image->colormap,image->colormap,length*
860  sizeof(*clone_image->colormap));
861  }
862  clone_image->image_info=CloneImageInfo(image->image_info);
863  (void) CloneImageProfiles(clone_image,image);
864  (void) CloneImageProperties(clone_image,image);
865  (void) CloneImageArtifacts(clone_image,image);
866  GetTimerInfo(&clone_image->timer);
867  if (image->ascii85 != (void *) NULL)
868  Ascii85Initialize(clone_image);
869  clone_image->magick_columns=image->magick_columns;
870  clone_image->magick_rows=image->magick_rows;
871  clone_image->type=image->type;
872  clone_image->channel_mask=image->channel_mask;
873  clone_image->channel_map=ClonePixelChannelMap(image->channel_map);
874  (void) CopyMagickString(clone_image->magick_filename,image->magick_filename,
876  (void) CopyMagickString(clone_image->magick,image->magick,MagickPathExtent);
877  (void) CopyMagickString(clone_image->filename,image->filename,
879  clone_image->progress_monitor=image->progress_monitor;
880  clone_image->client_data=image->client_data;
881  clone_image->reference_count=1;
882  clone_image->next=image->next;
883  clone_image->previous=image->previous;
884  clone_image->list=NewImageList();
885  if (detach == MagickFalse)
886  clone_image->blob=ReferenceBlob(image->blob);
887  else
888  {
889  clone_image->next=NewImageList();
890  clone_image->previous=NewImageList();
891  clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
892  }
893  clone_image->ping=image->ping;
894  clone_image->debug=IsEventLogging();
895  clone_image->semaphore=AcquireSemaphoreInfo();
896  if ((columns == 0) || (rows == 0))
897  {
898  if (image->montage != (char *) NULL)
899  (void) CloneString(&clone_image->montage,image->montage);
900  if (image->directory != (char *) NULL)
901  (void) CloneString(&clone_image->directory,image->directory);
902  clone_image->cache=ReferencePixelCache(image->cache);
903  return(clone_image);
904  }
905  scale=1.0;
906  if (image->columns != 0)
907  scale=(double) columns/(double) image->columns;
908  clone_image->page.width=(size_t) floor(scale*image->page.width+0.5);
909  clone_image->page.x=(ssize_t) ceil(scale*image->page.x-0.5);
910  clone_image->tile_offset.x=(ssize_t) ceil(scale*image->tile_offset.x-0.5);
911  scale=1.0;
912  if (image->rows != 0)
913  scale=(double) rows/(double) image->rows;
914  clone_image->page.height=(size_t) floor(scale*image->page.height+0.5);
915  clone_image->page.y=(ssize_t) ceil(scale*image->page.y-0.5);
916  clone_image->tile_offset.y=(ssize_t) ceil(scale*image->tile_offset.y-0.5);
917  clone_image->cache=ClonePixelCache(image->cache);
918  if (SetImageExtent(clone_image,columns,rows,exception) == MagickFalse)
919  clone_image=DestroyImage(clone_image);
920  return(clone_image);
921 }
922 
923 /*
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
925 % %
926 % %
927 % %
928 % C l o n e I m a g e I n f o %
929 % %
930 % %
931 % %
932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933 %
934 % CloneImageInfo() makes a copy of the given image info structure. If
935 % NULL is specified, a new image info structure is created initialized to
936 % default values.
937 %
938 % The format of the CloneImageInfo method is:
939 %
940 % ImageInfo *CloneImageInfo(const ImageInfo *image_info)
941 %
942 % A description of each parameter follows:
943 %
944 % o image_info: the image info.
945 %
946 */
948 {
949  ImageInfo
950  *clone_info;
951 
952  clone_info=AcquireImageInfo();
953  if (image_info == (ImageInfo *) NULL)
954  return(clone_info);
955  clone_info->compression=image_info->compression;
956  clone_info->temporary=image_info->temporary;
957  clone_info->adjoin=image_info->adjoin;
958  clone_info->antialias=image_info->antialias;
959  clone_info->scene=image_info->scene;
960  clone_info->number_scenes=image_info->number_scenes;
961  clone_info->depth=image_info->depth;
962  (void) CloneString(&clone_info->size,image_info->size);
963  (void) CloneString(&clone_info->extract,image_info->extract);
964  (void) CloneString(&clone_info->scenes,image_info->scenes);
965  (void) CloneString(&clone_info->page,image_info->page);
966  clone_info->interlace=image_info->interlace;
967  clone_info->endian=image_info->endian;
968  clone_info->units=image_info->units;
969  clone_info->quality=image_info->quality;
970  (void) CloneString(&clone_info->sampling_factor,image_info->sampling_factor);
971  (void) CloneString(&clone_info->server_name,image_info->server_name);
972  (void) CloneString(&clone_info->font,image_info->font);
973  (void) CloneString(&clone_info->texture,image_info->texture);
974  (void) CloneString(&clone_info->density,image_info->density);
975  clone_info->pointsize=image_info->pointsize;
976  clone_info->fuzz=image_info->fuzz;
977  clone_info->alpha_color=image_info->alpha_color;
978  clone_info->background_color=image_info->background_color;
979  clone_info->border_color=image_info->border_color;
980  clone_info->transparent_color=image_info->transparent_color;
981  clone_info->dither=image_info->dither;
982  clone_info->monochrome=image_info->monochrome;
983  clone_info->colorspace=image_info->colorspace;
984  clone_info->type=image_info->type;
985  clone_info->orientation=image_info->orientation;
986  clone_info->ping=image_info->ping;
987  clone_info->verbose=image_info->verbose;
988  clone_info->progress_monitor=image_info->progress_monitor;
989  clone_info->client_data=image_info->client_data;
990  clone_info->cache=image_info->cache;
991  if (image_info->cache != (void *) NULL)
992  clone_info->cache=ReferencePixelCache(image_info->cache);
993  if (image_info->profile != (void *) NULL)
994  clone_info->profile=(void *) CloneStringInfo((StringInfo *)
995  image_info->profile);
996  SetImageInfoFile(clone_info,image_info->file);
997  SetImageInfoBlob(clone_info,image_info->blob,image_info->length);
998  clone_info->stream=image_info->stream;
999  (void) CopyMagickString(clone_info->magick,image_info->magick,
1001  (void) CopyMagickString(clone_info->unique,image_info->unique,
1003  (void) CopyMagickString(clone_info->filename,image_info->filename,
1005  clone_info->channel=image_info->channel;
1006  (void) CloneImageOptions(clone_info,image_info);
1007  clone_info->debug=IsEventLogging();
1008  clone_info->signature=image_info->signature;
1009  return(clone_info);
1010 }
1011 
1012 /*
1013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1014 % %
1015 % %
1016 % %
1017 % C o p y I m a g e P i x e l s %
1018 % %
1019 % %
1020 % %
1021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1022 %
1023 % CopyImagePixels() copies pixels from the source image as defined by the
1024 % geometry the destination image at the specified offset.
1025 %
1026 % The format of the CopyImagePixels method is:
1027 %
1028 % MagickBooleanType CopyImagePixels(Image *image,const Image *source_image,
1029 % const RectangleInfo *geometry,const OffsetInfo *offset,
1030 % ExceptionInfo *exception);
1031 %
1032 % A description of each parameter follows:
1033 %
1034 % o image: the destination image.
1035 %
1036 % o source_image: the source image.
1037 %
1038 % o geometry: define the dimensions of the source pixel rectangle.
1039 %
1040 % o offset: define the offset in the destination image.
1041 %
1042 % o exception: return any errors or warnings in this structure.
1043 %
1044 */
1046  const Image *source_image,const RectangleInfo *geometry,
1047  const OffsetInfo *offset,ExceptionInfo *exception)
1048 {
1049 #define CopyImageTag "Copy/Image"
1050 
1051  CacheView
1052  *image_view,
1053  *source_view;
1054 
1056  status;
1057 
1059  progress;
1060 
1061  ssize_t
1062  y;
1063 
1064  assert(image != (Image *) NULL);
1065  if (image->debug != MagickFalse)
1066  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1067  assert(source_image != (Image *) NULL);
1068  assert(geometry != (RectangleInfo *) NULL);
1069  assert(offset != (OffsetInfo *) NULL);
1070  if ((offset->x < 0) || (offset->y < 0) ||
1071  ((ssize_t) (offset->x+geometry->width) > (ssize_t) image->columns) ||
1072  ((ssize_t) (offset->y+geometry->height) > (ssize_t) image->rows))
1073  ThrowBinaryException(OptionError,"GeometryDoesNotContainImage",
1074  image->filename);
1075  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1076  return(MagickFalse);
1077  /*
1078  Copy image pixels.
1079  */
1080  status=MagickTrue;
1081  progress=0;
1082  source_view=AcquireVirtualCacheView(source_image,exception);
1083  image_view=AcquireAuthenticCacheView(image,exception);
1084 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1085  #pragma omp parallel for schedule(static,4) shared(progress,status) \
1086  magick_threads(image,source_image,geometry->height,1)
1087 #endif
1088  for (y=0; y < (ssize_t) geometry->height; y++)
1089  {
1091  sync;
1092 
1093  register const Quantum
1094  *magick_restrict p;
1095 
1096  register ssize_t
1097  x;
1098 
1099  register Quantum
1100  *magick_restrict q;
1101 
1102  if (status == MagickFalse)
1103  continue;
1104  p=GetCacheViewVirtualPixels(source_view,geometry->x,y+geometry->y,
1105  geometry->width,1,exception);
1106  q=QueueCacheViewAuthenticPixels(image_view,offset->x,y+offset->y,
1107  geometry->width,1,exception);
1108  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
1109  {
1110  status=MagickFalse;
1111  continue;
1112  }
1113  for (x=0; x < (ssize_t) geometry->width; x++)
1114  {
1115  register ssize_t
1116  i;
1117 
1118  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1119  {
1120  PixelChannel channel=GetPixelChannelChannel(image,i);
1121  PixelTrait traits=GetPixelChannelTraits(image,channel);
1122  PixelTrait source_traits=GetPixelChannelTraits(source_image,channel);
1123  if ((traits == UndefinedPixelTrait) ||
1124  ((traits & UpdatePixelTrait) == 0) ||
1125  (source_traits == UndefinedPixelTrait))
1126  continue;
1127  SetPixelChannel(image,channel,p[i],q);
1128  }
1129  p+=GetPixelChannels(source_image);
1130  q+=GetPixelChannels(image);
1131  }
1132  sync=SyncCacheViewAuthenticPixels(image_view,exception);
1133  if (sync == MagickFalse)
1134  status=MagickFalse;
1135  if (image->progress_monitor != (MagickProgressMonitor) NULL)
1136  {
1138  proceed;
1139 
1140 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1141  #pragma omp critical (MagickCore_CopyImage)
1142 #endif
1143  proceed=SetImageProgress(image,CopyImageTag,progress++,image->rows);
1144  if (proceed == MagickFalse)
1145  status=MagickFalse;
1146  }
1147  }
1148  source_view=DestroyCacheView(source_view);
1149  image_view=DestroyCacheView(image_view);
1150  return(status);
1151 }
1152 
1153 /*
1154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 % %
1156 % %
1157 % %
1158 % D e s t r o y I m a g e %
1159 % %
1160 % %
1161 % %
1162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163 %
1164 % DestroyImage() dereferences an image, deallocating memory associated with
1165 % the image if the reference count becomes zero.
1166 %
1167 % The format of the DestroyImage method is:
1168 %
1169 % Image *DestroyImage(Image *image)
1170 %
1171 % A description of each parameter follows:
1172 %
1173 % o image: the image.
1174 %
1175 */
1177 {
1179  destroy;
1180 
1181  /*
1182  Dereference image.
1183  */
1184  assert(image != (Image *) NULL);
1185  assert(image->signature == MagickCoreSignature);
1186  if (image->debug != MagickFalse)
1187  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1188  destroy=MagickFalse;
1189  LockSemaphoreInfo(image->semaphore);
1190  image->reference_count--;
1191  if (image->reference_count == 0)
1192  destroy=MagickTrue;
1194  if (destroy == MagickFalse)
1195  return((Image *) NULL);
1196  /*
1197  Destroy image.
1198  */
1199  DestroyImagePixels(image);
1201  if (image->montage != (char *) NULL)
1202  image->montage=DestroyString(image->montage);
1203  if (image->directory != (char *) NULL)
1204  image->directory=DestroyString(image->directory);
1205  if (image->colormap != (PixelInfo *) NULL)
1207  if (image->geometry != (char *) NULL)
1208  image->geometry=DestroyString(image->geometry);
1209  DestroyImageProfiles(image);
1210  DestroyImageProperties(image);
1211  DestroyImageArtifacts(image);
1212  if (image->ascii85 != (Ascii85Info *) NULL)
1214  if (image->image_info != (ImageInfo *) NULL)
1215  image->image_info=DestroyImageInfo(image->image_info);
1216  DestroyBlob(image);
1217  if (image->semaphore != (SemaphoreInfo *) NULL)
1219  image->signature=(~MagickCoreSignature);
1220  image=(Image *) RelinquishMagickMemory(image);
1221  return(image);
1222 }
1223 
1224 /*
1225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 % %
1227 % %
1228 % %
1229 % D e s t r o y I m a g e I n f o %
1230 % %
1231 % %
1232 % %
1233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1234 %
1235 % DestroyImageInfo() deallocates memory associated with an ImageInfo
1236 % structure.
1237 %
1238 % The format of the DestroyImageInfo method is:
1239 %
1240 % ImageInfo *DestroyImageInfo(ImageInfo *image_info)
1241 %
1242 % A description of each parameter follows:
1243 %
1244 % o image_info: the image info.
1245 %
1246 */
1248 {
1249  assert(image_info != (ImageInfo *) NULL);
1250  assert(image_info->signature == MagickCoreSignature);
1251  if (image_info->debug != MagickFalse)
1253  image_info->filename);
1254  if (image_info->size != (char *) NULL)
1255  image_info->size=DestroyString(image_info->size);
1256  if (image_info->extract != (char *) NULL)
1257  image_info->extract=DestroyString(image_info->extract);
1258  if (image_info->scenes != (char *) NULL)
1259  image_info->scenes=DestroyString(image_info->scenes);
1260  if (image_info->page != (char *) NULL)
1261  image_info->page=DestroyString(image_info->page);
1262  if (image_info->sampling_factor != (char *) NULL)
1263  image_info->sampling_factor=DestroyString(
1264  image_info->sampling_factor);
1265  if (image_info->server_name != (char *) NULL)
1266  image_info->server_name=DestroyString(
1267  image_info->server_name);
1268  if (image_info->font != (char *) NULL)
1269  image_info->font=DestroyString(image_info->font);
1270  if (image_info->texture != (char *) NULL)
1271  image_info->texture=DestroyString(image_info->texture);
1272  if (image_info->density != (char *) NULL)
1273  image_info->density=DestroyString(image_info->density);
1274  if (image_info->cache != (void *) NULL)
1275  image_info->cache=DestroyPixelCache(image_info->cache);
1276  if (image_info->profile != (StringInfo *) NULL)
1277  image_info->profile=(void *) DestroyStringInfo((StringInfo *)
1278  image_info->profile);
1279  DestroyImageOptions(image_info);
1280  image_info->signature=(~MagickCoreSignature);
1281  image_info=(ImageInfo *) RelinquishMagickMemory(image_info);
1282  return(image_info);
1283 }
1284 
1285 /*
1286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287 % %
1288 % %
1289 % %
1290 + D i s a s s o c i a t e I m a g e S t r e a m %
1291 % %
1292 % %
1293 % %
1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295 %
1296 % DisassociateImageStream() disassociates the image stream. It checks if the
1297 % blob of the specified image is referenced by other images. If the reference
1298 % count is higher then 1 a new blob is assigned to the specified image.
1299 %
1300 % The format of the DisassociateImageStream method is:
1301 %
1302 % void DisassociateImageStream(const Image *image)
1303 %
1304 % A description of each parameter follows:
1305 %
1306 % o image: the image.
1307 %
1308 */
1310 {
1311  assert(image != (Image *) NULL);
1312  assert(image->signature == MagickCoreSignature);
1313  if (image->debug != MagickFalse)
1314  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1315  DisassociateBlob(image);
1316 }
1317 
1318 /*
1319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320 % %
1321 % %
1322 % %
1323 % G e t I m a g e I n f o %
1324 % %
1325 % %
1326 % %
1327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1328 %
1329 % GetImageInfo() initializes image_info to default values.
1330 %
1331 % The format of the GetImageInfo method is:
1332 %
1333 % void GetImageInfo(ImageInfo *image_info)
1334 %
1335 % A description of each parameter follows:
1336 %
1337 % o image_info: the image info.
1338 %
1339 */
1341 {
1342  char
1343  *synchronize;
1344 
1346  *exception;
1347 
1348  /*
1349  File and image dimension members.
1350  */
1351  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1352  assert(image_info != (ImageInfo *) NULL);
1353  (void) ResetMagickMemory(image_info,0,sizeof(*image_info));
1354  image_info->adjoin=MagickTrue;
1355  image_info->interlace=NoInterlace;
1356  image_info->channel=DefaultChannels;
1358  image_info->antialias=MagickTrue;
1359  image_info->dither=MagickTrue;
1360  synchronize=GetEnvironmentValue("MAGICK_SYNCHRONIZE");
1361  if (synchronize != (const char *) NULL)
1362  {
1363  image_info->synchronize=IsStringTrue(synchronize);
1364  synchronize=DestroyString(synchronize);
1365  }
1366  exception=AcquireExceptionInfo();
1368  exception);
1370  &image_info->background_color,exception);
1372  &image_info->border_color,exception);
1374  &image_info->transparent_color,exception);
1375  exception=DestroyExceptionInfo(exception);
1376  image_info->debug=IsEventLogging();
1377  image_info->signature=MagickCoreSignature;
1378 }
1379 
1380 /*
1381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1382 % %
1383 % %
1384 % %
1385 % G e t I m a g e I n f o F i l e %
1386 % %
1387 % %
1388 % %
1389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1390 %
1391 % GetImageInfoFile() returns the image info file member.
1392 %
1393 % The format of the GetImageInfoFile method is:
1394 %
1395 % FILE *GetImageInfoFile(const ImageInfo *image_info)
1396 %
1397 % A description of each parameter follows:
1398 %
1399 % o image_info: the image info.
1400 %
1401 */
1402 MagickExport FILE *GetImageInfoFile(const ImageInfo *image_info)
1403 {
1404  return(image_info->file);
1405 }
1406 
1407 /*
1408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 % %
1410 % %
1411 % %
1412 % G e t I m a g e M a s k %
1413 % %
1414 % %
1415 % %
1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 %
1418 % GetImageMask() returns the mask associated with the image.
1419 %
1420 % The format of the GetImageMask method is:
1421 %
1422 % Image *GetImageMask(const Image *image,const PixelMask type,
1423 % ExceptionInfo *exception)
1424 %
1425 % A description of each parameter follows:
1426 %
1427 % o image: the image.
1428 %
1429 % o type: the mask type, ReadPixelMask or WritePixelMask.
1430 %
1431 */
1434 {
1435  CacheView
1436  *mask_view,
1437  *image_view;
1438 
1439  Image
1440  *mask_image;
1441 
1443  status;
1444 
1445  ssize_t
1446  y;
1447 
1448  /*
1449  Get image mask.
1450  */
1451  assert(image != (Image *) NULL);
1452  if (image->debug != MagickFalse)
1453  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1454  assert(image->signature == MagickCoreSignature);
1455  mask_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
1456  if (mask_image == (Image *) NULL)
1457  return((Image *) NULL);
1458  status=MagickTrue;
1459  mask_image->alpha_trait=UndefinedPixelTrait;
1460  (void) SetImageColorspace(mask_image,GRAYColorspace,exception);
1461  mask_image->read_mask=MagickFalse;
1462  image_view=AcquireVirtualCacheView(image,exception);
1463  mask_view=AcquireAuthenticCacheView(mask_image,exception);
1464  for (y=0; y < (ssize_t) image->rows; y++)
1465  {
1466  register const Quantum
1467  *magick_restrict p;
1468 
1469  register Quantum
1470  *magick_restrict q;
1471 
1472  register ssize_t
1473  x;
1474 
1475  if (status == MagickFalse)
1476  continue;
1477  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1478  q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1479  exception);
1480  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
1481  {
1482  status=MagickFalse;
1483  continue;
1484  }
1485  for (x=0; x < (ssize_t) image->columns; x++)
1486  {
1487  switch (type)
1488  {
1489  case WritePixelMask:
1490  {
1491  SetPixelGray(mask_image,GetPixelWriteMask(image,p),q);
1492  break;
1493  }
1494  default:
1495  {
1496  SetPixelGray(mask_image,GetPixelReadMask(image,p),q);
1497  break;
1498  }
1499  }
1500  p+=GetPixelChannels(image);
1501  q+=GetPixelChannels(mask_image);
1502  }
1503  if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1504  status=MagickFalse;
1505  }
1506  mask_view=DestroyCacheView(mask_view);
1507  image_view=DestroyCacheView(image_view);
1508  if (status == MagickFalse)
1509  mask_image=DestroyImage(mask_image);
1510  return(mask_image);
1511 }
1512 
1513 /*
1514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515 % %
1516 % %
1517 % %
1518 + G e t I m a g e R e f e r e n c e C o u n t %
1519 % %
1520 % %
1521 % %
1522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1523 %
1524 % GetImageReferenceCount() returns the image reference count.
1525 %
1526 % The format of the GetReferenceCount method is:
1527 %
1528 % ssize_t GetImageReferenceCount(Image *image)
1529 %
1530 % A description of each parameter follows:
1531 %
1532 % o image: the image.
1533 %
1534 */
1536 {
1537  ssize_t
1538  reference_count;
1539 
1540  assert(image != (Image *) NULL);
1541  assert(image->signature == MagickCoreSignature);
1542  if (image->debug != MagickFalse)
1543  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1544  LockSemaphoreInfo(image->semaphore);
1545  reference_count=image->reference_count;
1547  return(reference_count);
1548 }
1549 
1550 /*
1551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1552 % %
1553 % %
1554 % %
1555 % 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 %
1556 % %
1557 % %
1558 % %
1559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1560 %
1561 % GetImageVirtualPixelMethod() gets the "virtual pixels" method for the
1562 % image. A virtual pixel is any pixel access that is outside the boundaries
1563 % of the image cache.
1564 %
1565 % The format of the GetImageVirtualPixelMethod() method is:
1566 %
1567 % VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
1568 %
1569 % A description of each parameter follows:
1570 %
1571 % o image: the image.
1572 %
1573 */
1575 {
1576  assert(image != (Image *) NULL);
1577  assert(image->signature == MagickCoreSignature);
1578  if (image->debug != MagickFalse)
1579  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1580  return(GetPixelCacheVirtualMethod(image));
1581 }
1582 
1583 /*
1584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1585 % %
1586 % %
1587 % %
1588 % I n t e r p r e t I m a g e F i l e n a m e %
1589 % %
1590 % %
1591 % %
1592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1593 %
1594 % InterpretImageFilename() interprets embedded characters in an image filename.
1595 % The filename length is returned.
1596 %
1597 % The format of the InterpretImageFilename method is:
1598 %
1599 % size_t InterpretImageFilename(const ImageInfo *image_info,Image *image,
1600 % const char *format,int value,char *filename,ExceptionInfo *exception)
1601 %
1602 % A description of each parameter follows.
1603 %
1604 % o image_info: the image info..
1605 %
1606 % o image: the image.
1607 %
1608 % o format: A filename describing the format to use to write the numeric
1609 % argument. Only the first numeric format identifier is replaced.
1610 %
1611 % o value: Numeric value to substitute into format filename.
1612 %
1613 % o filename: return the formatted filename in this character buffer.
1614 %
1615 % o exception: return any errors or warnings in this structure.
1616 %
1617 */
1619  Image *image,const char *format,int value,char *filename,
1621 {
1622  char
1623  *q;
1624 
1625  int
1626  c;
1627 
1629  canonical;
1630 
1631  register const char
1632  *p;
1633 
1634  size_t
1635  length;
1636 
1637  canonical=MagickFalse;
1638  length=0;
1639  (void) CopyMagickString(filename,format,MagickPathExtent);
1640  for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
1641  {
1642  q=(char *) p+1;
1643  if (*q == '%')
1644  {
1645  p=q+1;
1646  continue;
1647  }
1648  if (*q == '0')
1649  {
1650  ssize_t
1651  foo;
1652 
1653  foo=(ssize_t) strtol(q,&q,10);
1654  (void) foo;
1655  }
1656  switch (*q)
1657  {
1658  case 'd':
1659  case 'o':
1660  case 'x':
1661  {
1662  q++;
1663  c=(*q);
1664  *q='\0';
1665  (void) FormatLocaleString(filename+(p-format),(size_t)
1666  (MagickPathExtent-(p-format)),p,value);
1667  *q=c;
1668  (void) ConcatenateMagickString(filename,q,MagickPathExtent);
1669  canonical=MagickTrue;
1670  if (*(q-1) != '%')
1671  break;
1672  p++;
1673  break;
1674  }
1675  case '[':
1676  {
1677  char
1678  pattern[MagickPathExtent];
1679 
1680  const char
1681  *option;
1682 
1683  register char
1684  *r;
1685 
1686  register ssize_t
1687  i;
1688 
1689  ssize_t
1690  depth;
1691 
1692  /*
1693  Image option.
1694  */
1695  /* FUTURE: Compare update with code from InterpretImageProperties()
1696  Note that a 'filename:' property should not need depth recursion.
1697  */
1698  if (strchr(p,']') == (char *) NULL)
1699  break;
1700  depth=1;
1701  r=q+1;
1702  for (i=0; (i < (MagickPathExtent-1L)) && (*r != '\0'); i++)
1703  {
1704  if (*r == '[')
1705  depth++;
1706  if (*r == ']')
1707  depth--;
1708  if (depth <= 0)
1709  break;
1710  pattern[i]=(*r++);
1711  }
1712  pattern[i]='\0';
1713  if (LocaleNCompare(pattern,"filename:",9) != 0)
1714  break;
1715  option=(const char *) NULL;
1716  if (image != (Image *) NULL)
1717  option=GetImageProperty(image,pattern,exception);
1718  if ((option == (const char *) NULL) && (image != (Image *) NULL))
1719  option=GetImageArtifact(image,pattern);
1720  if ((option == (const char *) NULL) &&
1721  (image_info != (ImageInfo *) NULL))
1722  option=GetImageOption(image_info,pattern);
1723  if (option == (const char *) NULL)
1724  break;
1725  q--;
1726  c=(*q);
1727  *q='\0';
1728  (void) CopyMagickString(filename+(p-format-length),option,(size_t)
1729  (MagickPathExtent-(p-format-length)));
1730  length+=strlen(pattern)-1;
1731  *q=c;
1732  (void) ConcatenateMagickString(filename,r+1,MagickPathExtent);
1733  canonical=MagickTrue;
1734  if (*(q-1) != '%')
1735  break;
1736  p++;
1737  break;
1738  }
1739  default:
1740  break;
1741  }
1742  }
1743  for (q=filename; *q != '\0'; q++)
1744  if ((*q == '%') && (*(q+1) == '%'))
1745  {
1746  (void) CopyMagickString(q,q+1,(size_t) (MagickPathExtent-(q-filename)));
1747  canonical=MagickTrue;
1748  }
1749  if (canonical == MagickFalse)
1750  (void) CopyMagickString(filename,format,MagickPathExtent);
1751  return(strlen(filename));
1752 }
1753 
1754 /*
1755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1756 % %
1757 % %
1758 % %
1759 % I s H i g h D y n a m i c R a n g e I m a g e %
1760 % %
1761 % %
1762 % %
1763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1764 %
1765 % IsHighDynamicRangeImage() returns MagickTrue if any pixel component is
1766 % non-integer or exceeds the bounds of the quantum depth (e.g. for Q16
1767 % 0..65535.
1768 %
1769 % The format of the IsHighDynamicRangeImage method is:
1770 %
1771 % MagickBooleanType IsHighDynamicRangeImage(const Image *image,
1772 % ExceptionInfo *exception)
1773 %
1774 % A description of each parameter follows:
1775 %
1776 % o image: the image.
1777 %
1778 % o exception: return any errors or warnings in this structure.
1779 %
1780 */
1783 {
1784 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1785  (void) image;
1786  (void) exception;
1787  return(MagickFalse);
1788 #else
1789  CacheView
1790  *image_view;
1791 
1793  status;
1794 
1795  ssize_t
1796  y;
1797 
1798  assert(image != (Image *) NULL);
1799  assert(image->signature == MagickCoreSignature);
1800  if (image->debug != MagickFalse)
1801  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1802  status=MagickTrue;
1803  image_view=AcquireVirtualCacheView(image,exception);
1804 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1805  #pragma omp parallel for schedule(static,4) shared(status) \
1806  magick_threads(image,image,image->rows,1)
1807 #endif
1808  for (y=0; y < (ssize_t) image->rows; y++)
1809  {
1810  register const Quantum
1811  *p;
1812 
1813  register ssize_t
1814  x;
1815 
1816  if (status == MagickFalse)
1817  continue;
1818  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1819  if (p == (const Quantum *) NULL)
1820  {
1821  status=MagickFalse;
1822  continue;
1823  }
1824  for (x=0; x < (ssize_t) image->columns; x++)
1825  {
1826  register ssize_t
1827  i;
1828 
1829  if (GetPixelWriteMask(image,p) == 0)
1830  {
1831  p+=GetPixelChannels(image);
1832  continue;
1833  }
1834  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1835  {
1836  double
1837  pixel;
1838 
1839  PixelTrait
1840  traits;
1841 
1842  traits=GetPixelChannelTraits(image,(PixelChannel) i);
1843  if (traits == UndefinedPixelTrait)
1844  continue;
1845  pixel=(double) p[i];
1846  if ((pixel < 0.0) || (pixel > QuantumRange) ||
1847  (pixel != (double) ((QuantumAny) pixel)))
1848  break;
1849  }
1850  p+=GetPixelChannels(image);
1851  if (i < (ssize_t) GetPixelChannels(image))
1852  status=MagickFalse;
1853  }
1854  if (x < (ssize_t) image->columns)
1855  status=MagickFalse;
1856  }
1857  image_view=DestroyCacheView(image_view);
1858  return(status != MagickFalse ? MagickFalse : MagickTrue);
1859 #endif
1860 }
1861 
1862 /*
1863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864 % %
1865 % %
1866 % %
1867 % I s I m a g e O b j e c t %
1868 % %
1869 % %
1870 % %
1871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1872 %
1873 % IsImageObject() returns MagickTrue if the image sequence contains a valid
1874 % set of image objects.
1875 %
1876 % The format of the IsImageObject method is:
1877 %
1878 % MagickBooleanType IsImageObject(const Image *image)
1879 %
1880 % A description of each parameter follows:
1881 %
1882 % o image: the image.
1883 %
1884 */
1886 {
1887  register const Image
1888  *p;
1889 
1890  assert(image != (Image *) NULL);
1891  if (image->debug != MagickFalse)
1892  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1893  for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
1894  if (p->signature != MagickCoreSignature)
1895  return(MagickFalse);
1896  return(MagickTrue);
1897 }
1898 
1899 /*
1900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1901 % %
1902 % %
1903 % %
1904 % I s T a i n t I m a g e %
1905 % %
1906 % %
1907 % %
1908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1909 %
1910 % IsTaintImage() returns MagickTrue any pixel in the image has been altered
1911 % since it was first constituted.
1912 %
1913 % The format of the IsTaintImage method is:
1914 %
1915 % MagickBooleanType IsTaintImage(const Image *image)
1916 %
1917 % A description of each parameter follows:
1918 %
1919 % o image: the image.
1920 %
1921 */
1923 {
1924  char
1925  magick[MagickPathExtent],
1926  filename[MagickPathExtent];
1927 
1928  register const Image
1929  *p;
1930 
1931  assert(image != (Image *) NULL);
1932  if (image->debug != MagickFalse)
1933  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1934  assert(image->signature == MagickCoreSignature);
1935  (void) CopyMagickString(magick,image->magick,MagickPathExtent);
1936  (void) CopyMagickString(filename,image->filename,MagickPathExtent);
1937  for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
1938  {
1939  if (p->taint != MagickFalse)
1940  return(MagickTrue);
1941  if (LocaleCompare(p->magick,magick) != 0)
1942  return(MagickTrue);
1943  if (LocaleCompare(p->filename,filename) != 0)
1944  return(MagickTrue);
1945  }
1946  return(MagickFalse);
1947 }
1948 
1949 /*
1950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951 % %
1952 % %
1953 % %
1954 % M o d i f y I m a g e %
1955 % %
1956 % %
1957 % %
1958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1959 %
1960 % ModifyImage() ensures that there is only a single reference to the image
1961 % to be modified, updating the provided image pointer to point to a clone of
1962 % the original image if necessary.
1963 %
1964 % The format of the ModifyImage method is:
1965 %
1966 % MagickBooleanType ModifyImage(Image *image,ExceptionInfo *exception)
1967 %
1968 % A description of each parameter follows:
1969 %
1970 % o image: the image.
1971 %
1972 % o exception: return any errors or warnings in this structure.
1973 %
1974 */
1977 {
1978  Image
1979  *clone_image;
1980 
1981  assert(image != (Image **) NULL);
1982  assert(*image != (Image *) NULL);
1983  assert((*image)->signature == MagickCoreSignature);
1984  if ((*image)->debug != MagickFalse)
1985  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1986  if (GetImageReferenceCount(*image) <= 1)
1987  return(MagickTrue);
1988  clone_image=CloneImage(*image,0,0,MagickTrue,exception);
1989  LockSemaphoreInfo((*image)->semaphore);
1990  (*image)->reference_count--;
1991  UnlockSemaphoreInfo((*image)->semaphore);
1992  *image=clone_image;
1993  return(MagickTrue);
1994 }
1995 
1996 /*
1997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1998 % %
1999 % %
2000 % %
2001 % N e w M a g i c k I m a g e %
2002 % %
2003 % %
2004 % %
2005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2006 %
2007 % NewMagickImage() creates a blank image canvas of the specified size and
2008 % background color.
2009 %
2010 % The format of the NewMagickImage method is:
2011 %
2012 % Image *NewMagickImage(const ImageInfo *image_info,const size_t width,
2013 % const size_t height,const PixelInfo *background,
2014 % ExceptionInfo *exception)
2015 %
2016 % A description of each parameter follows:
2017 %
2018 % o image: the image.
2019 %
2020 % o width: the image width.
2021 %
2022 % o height: the image height.
2023 %
2024 % o background: the image color.
2025 %
2026 % o exception: return any errors or warnings in this structure.
2027 %
2028 */
2030  const size_t width,const size_t height,const PixelInfo *background,
2032 {
2033  CacheView
2034  *image_view;
2035 
2036  Image
2037  *image;
2038 
2040  status;
2041 
2042  ssize_t
2043  y;
2044 
2045  assert(image_info != (const ImageInfo *) NULL);
2046  if (image_info->debug != MagickFalse)
2047  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2048  assert(image_info->signature == MagickCoreSignature);
2049  assert(background != (const PixelInfo *) NULL);
2050  image=AcquireImage(image_info,exception);
2051  image->columns=width;
2052  image->rows=height;
2053  image->colorspace=background->colorspace;
2054  image->alpha_trait=background->alpha_trait;
2055  image->fuzz=background->fuzz;
2056  image->depth=background->depth;
2057  status=MagickTrue;
2058  image_view=AcquireAuthenticCacheView(image,exception);
2059 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2060  #pragma omp parallel for schedule(static,4) shared(status) \
2061  magick_threads(image,image,image->rows,1)
2062 #endif
2063  for (y=0; y < (ssize_t) image->rows; y++)
2064  {
2065  register Quantum
2066  *magick_restrict q;
2067 
2068  register ssize_t
2069  x;
2070 
2071  if (status == MagickFalse)
2072  continue;
2073  q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2074  if (q == (Quantum *) NULL)
2075  {
2076  status=MagickFalse;
2077  continue;
2078  }
2079  for (x=0; x < (ssize_t) image->columns; x++)
2080  {
2081  SetPixelViaPixelInfo(image,background,q);
2082  q+=GetPixelChannels(image);
2083  }
2084  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2085  status=MagickFalse;
2086  }
2087  image_view=DestroyCacheView(image_view);
2088  if (status == MagickFalse)
2089  image=DestroyImage(image);
2090  return(image);
2091 }
2092 
2093 /*
2094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 % %
2096 % %
2097 % %
2098 % R e f e r e n c e I m a g e %
2099 % %
2100 % %
2101 % %
2102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2103 %
2104 % ReferenceImage() increments the reference count associated with an image
2105 % returning a pointer to the image.
2106 %
2107 % The format of the ReferenceImage method is:
2108 %
2109 % Image *ReferenceImage(Image *image)
2110 %
2111 % A description of each parameter follows:
2112 %
2113 % o image: the image.
2114 %
2115 */
2117 {
2118  assert(image != (Image *) NULL);
2119  if (image->debug != MagickFalse)
2120  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2121  assert(image->signature == MagickCoreSignature);
2122  LockSemaphoreInfo(image->semaphore);
2123  image->reference_count++;
2125  return(image);
2126 }
2127 
2128 /*
2129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2130 % %
2131 % %
2132 % %
2133 % R e s e t I m a g e P a g e %
2134 % %
2135 % %
2136 % %
2137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2138 %
2139 % ResetImagePage() resets the image page canvas and position.
2140 %
2141 % The format of the ResetImagePage method is:
2142 %
2143 % MagickBooleanType ResetImagePage(Image *image,const char *page)
2144 %
2145 % A description of each parameter follows:
2146 %
2147 % o image: the image.
2148 %
2149 % o page: the relative page specification.
2150 %
2151 */
2153 {
2155  flags;
2156 
2158  geometry;
2159 
2160  assert(image != (Image *) NULL);
2161  assert(image->signature == MagickCoreSignature);
2162  if (image->debug != MagickFalse)
2163  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2164  flags=ParseAbsoluteGeometry(page,&geometry);
2165  if ((flags & WidthValue) != 0)
2166  {
2167  if ((flags & HeightValue) == 0)
2168  geometry.height=geometry.width;
2169  image->page.width=geometry.width;
2170  image->page.height=geometry.height;
2171  }
2172  if ((flags & AspectValue) != 0)
2173  {
2174  if ((flags & XValue) != 0)
2175  image->page.x+=geometry.x;
2176  if ((flags & YValue) != 0)
2177  image->page.y+=geometry.y;
2178  }
2179  else
2180  {
2181  if ((flags & XValue) != 0)
2182  {
2183  image->page.x=geometry.x;
2184  if ((image->page.width == 0) && (geometry.x > 0))
2185  image->page.width=image->columns+geometry.x;
2186  }
2187  if ((flags & YValue) != 0)
2188  {
2189  image->page.y=geometry.y;
2190  if ((image->page.height == 0) && (geometry.y > 0))
2191  image->page.height=image->rows+geometry.y;
2192  }
2193  }
2194  return(MagickTrue);
2195 }
2196 
2197 /*
2198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2199 % %
2200 % %
2201 % %
2202 % S e t I m a g e B a c k g r o u n d C o l o r %
2203 % %
2204 % %
2205 % %
2206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2207 %
2208 % SetImageBackgroundColor() initializes the image pixels to the image
2209 % background color. The background color is defined by the background_color
2210 % member of the image structure.
2211 %
2212 % The format of the SetImage method is:
2213 %
2214 % MagickBooleanType SetImageBackgroundColor(Image *image,
2215 % ExceptionInfo *exception)
2216 %
2217 % A description of each parameter follows:
2218 %
2219 % o image: the image.
2220 %
2221 % o exception: return any errors or warnings in this structure.
2222 %
2223 */
2226 {
2227  CacheView
2228  *image_view;
2229 
2231  status;
2232 
2233  PixelInfo
2234  background;
2235 
2236  ssize_t
2237  y;
2238 
2239  assert(image != (Image *) NULL);
2240  if (image->debug != MagickFalse)
2241  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2242  assert(image->signature == MagickCoreSignature);
2243  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2244  return(MagickFalse);
2245  if ((image->background_color.alpha != OpaqueAlpha) &&
2246  (image->alpha_trait == UndefinedPixelTrait))
2247  (void) SetImageAlphaChannel(image,OnAlphaChannel,exception);
2248  ConformPixelInfo(image,&image->background_color,&background,exception);
2249  /*
2250  Set image background color.
2251  */
2252  status=MagickTrue;
2253  image_view=AcquireAuthenticCacheView(image,exception);
2254  for (y=0; y < (ssize_t) image->rows; y++)
2255  {
2256  register Quantum
2257  *magick_restrict q;
2258 
2259  register ssize_t
2260  x;
2261 
2262  if (status == MagickFalse)
2263  continue;
2264  q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2265  if (q == (Quantum *) NULL)
2266  {
2267  status=MagickFalse;
2268  continue;
2269  }
2270  for (x=0; x < (ssize_t) image->columns; x++)
2271  {
2272  SetPixelViaPixelInfo(image,&background,q);
2273  q+=GetPixelChannels(image);
2274  }
2275  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2276  status=MagickFalse;
2277  }
2278  image_view=DestroyCacheView(image_view);
2279  return(status);
2280 }
2281 
2282 /*
2283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284 % %
2285 % %
2286 % %
2287 % S e t I m a g e C h a n n e l M a s k %
2288 % %
2289 % %
2290 % %
2291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2292 %
2293 % SetImageChannelMask() sets the image channel mask from the specified channel
2294 % mask.
2295 %
2296 % The format of the SetImageChannelMask method is:
2297 %
2298 % ChannelType SetImageChannelMask(Image *image,
2299 % const ChannelType channel_mask)
2300 %
2301 % A description of each parameter follows:
2302 %
2303 % o image: the image.
2304 %
2305 % o channel_mask: the channel mask.
2306 %
2307 */
2309  const ChannelType channel_mask)
2310 {
2311  return(SetPixelChannelMask(image,channel_mask));
2312 }
2313 
2314 /*
2315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2316 % %
2317 % %
2318 % %
2319 % S e t I m a g e C o l o r %
2320 % %
2321 % %
2322 % %
2323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2324 %
2325 % SetImageColor() set the entire image canvas to the specified color.
2326 %
2327 % The format of the SetImageColor method is:
2328 %
2329 % MagickBooleanType SetImageColor(Image *image,const PixelInfo *color,
2330 % ExeptionInfo *exception)
2331 %
2332 % A description of each parameter follows:
2333 %
2334 % o image: the image.
2335 %
2336 % o background: the image color.
2337 %
2338 % o exception: return any errors or warnings in this structure.
2339 %
2340 */
2342  const PixelInfo *color,ExceptionInfo *exception)
2343 {
2344  CacheView
2345  *image_view;
2346 
2348  status;
2349 
2350  ssize_t
2351  y;
2352 
2353  assert(image != (Image *) NULL);
2354  if (image->debug != MagickFalse)
2355  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2356  assert(image->signature == MagickCoreSignature);
2357  assert(color != (const PixelInfo *) NULL);
2358  image->colorspace=color->colorspace;
2359  image->alpha_trait=color->alpha_trait;
2360  image->fuzz=color->fuzz;
2361  image->depth=color->depth;
2362  status=MagickTrue;
2363  image_view=AcquireAuthenticCacheView(image,exception);
2364 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2365  #pragma omp parallel for schedule(static,4) shared(status) \
2366  magick_threads(image,image,image->rows,1)
2367 #endif
2368  for (y=0; y < (ssize_t) image->rows; y++)
2369  {
2370  register Quantum
2371  *magick_restrict q;
2372 
2373  register ssize_t
2374  x;
2375 
2376  if (status == MagickFalse)
2377  continue;
2378  q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2379  if (q == (Quantum *) NULL)
2380  {
2381  status=MagickFalse;
2382  continue;
2383  }
2384  for (x=0; x < (ssize_t) image->columns; x++)
2385  {
2386  SetPixelViaPixelInfo(image,color,q);
2387  q+=GetPixelChannels(image);
2388  }
2389  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2390  status=MagickFalse;
2391  }
2392  image_view=DestroyCacheView(image_view);
2393  return(status);
2394 }
2395 
2396 /*
2397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2398 % %
2399 % %
2400 % %
2401 % S e t I m a g e S t o r a g e C l a s s %
2402 % %
2403 % %
2404 % %
2405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2406 %
2407 % SetImageStorageClass() sets the image class: DirectClass for true color
2408 % images or PseudoClass for colormapped images.
2409 %
2410 % The format of the SetImageStorageClass method is:
2411 %
2412 % MagickBooleanType SetImageStorageClass(Image *image,
2413 % const ClassType storage_class,ExceptionInfo *exception)
2414 %
2415 % A description of each parameter follows:
2416 %
2417 % o image: the image.
2418 %
2419 % o storage_class: The image class.
2420 %
2421 % o exception: return any errors or warnings in this structure.
2422 %
2423 */
2425  const ClassType storage_class,ExceptionInfo *exception)
2426 {
2427  assert(image != (Image *) NULL);
2428  assert(image->signature == MagickCoreSignature);
2429  if (image->debug != MagickFalse)
2430  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2431  assert(exception != (ExceptionInfo *) NULL);
2432  assert(exception->signature == MagickCoreSignature);
2433  image->storage_class=storage_class;
2434  return(SyncImagePixelCache(image,exception));
2435 }
2436 
2437 /*
2438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2439 % %
2440 % %
2441 % %
2442 % S e t I m a g e E x t e n t %
2443 % %
2444 % %
2445 % %
2446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2447 %
2448 % SetImageExtent() sets the image size (i.e. columns & rows).
2449 %
2450 % The format of the SetImageExtent method is:
2451 %
2452 % MagickBooleanType SetImageExtent(Image *image,const size_t columns,
2453 % const size_t rows,ExceptionInfo *exception)
2454 %
2455 % A description of each parameter follows:
2456 %
2457 % o image: the image.
2458 %
2459 % o columns: The image width in pixels.
2460 %
2461 % o rows: The image height in pixels.
2462 %
2463 % o exception: return any errors or warnings in this structure.
2464 %
2465 */
2467  const size_t rows,ExceptionInfo *exception)
2468 {
2469  if ((columns == 0) || (rows == 0))
2470  ThrowBinaryException(ImageError,"NegativeOrZeroImageSize",image->filename);
2471  image->columns=columns;
2472  image->rows=rows;
2473  if (image->depth > (8*sizeof(MagickSizeType)))
2474  ThrowBinaryException(ImageError,"ImageDepthNotSupported",image->filename);
2475  return(SyncImagePixelCache(image,exception));
2476 }
2477 
2478 /*
2479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2480 % %
2481 % %
2482 % %
2483 + S e t I m a g e I n f o %
2484 % %
2485 % %
2486 % %
2487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2488 %
2489 % SetImageInfo() initializes the 'magick' field of the ImageInfo structure.
2490 % It is set to a type of image format based on the prefix or suffix of the
2491 % filename. For example, 'ps:image' returns PS indicating a Postscript image.
2492 % JPEG is returned for this filename: 'image.jpg'. The filename prefix has
2493 % precendence over the suffix. Use an optional index enclosed in brackets
2494 % after a file name to specify a desired scene of a multi-resolution image
2495 % format like Photo CD (e.g. img0001.pcd[4]). A True (non-zero) return value
2496 % indicates success.
2497 %
2498 % The format of the SetImageInfo method is:
2499 %
2500 % MagickBooleanType SetImageInfo(ImageInfo *image_info,
2501 % const unsigned int frames,ExceptionInfo *exception)
2502 %
2503 % A description of each parameter follows:
2504 %
2505 % o image_info: the image info.
2506 %
2507 % o frames: the number of images you intend to write.
2508 %
2509 % o exception: return any errors or warnings in this structure.
2510 %
2511 */
2513  const unsigned int frames,ExceptionInfo *exception)
2514 {
2515  char
2516  component[MagickPathExtent],
2517  magic[MagickPathExtent],
2518  *q;
2519 
2520  const MagicInfo
2521  *magic_info;
2522 
2523  const MagickInfo
2524  *magick_info;
2525 
2527  *sans_exception;
2528 
2529  Image
2530  *image;
2531 
2533  status;
2534 
2535  register const char
2536  *p;
2537 
2538  ssize_t
2539  count;
2540 
2541  /*
2542  Look for 'image.format' in filename.
2543  */
2544  assert(image_info != (ImageInfo *) NULL);
2545  assert(image_info->signature == MagickCoreSignature);
2546  if (image_info->debug != MagickFalse)
2548  image_info->filename);
2549  *component='\0';
2550  GetPathComponent(image_info->filename,SubimagePath,component);
2551  if (*component != '\0')
2552  {
2553  /*
2554  Look for scene specification (e.g. img0001.pcd[4]).
2555  */
2556  if (IsSceneGeometry(component,MagickFalse) == MagickFalse)
2557  {
2558  if (IsGeometry(component) != MagickFalse)
2559  (void) CloneString(&image_info->extract,component);
2560  }
2561  else
2562  {
2563  size_t
2564  first,
2565  last;
2566 
2567  (void) CloneString(&image_info->scenes,component);
2568  image_info->scene=StringToUnsignedLong(image_info->scenes);
2569  image_info->number_scenes=image_info->scene;
2570  p=image_info->scenes;
2571  for (q=(char *) image_info->scenes; *q != '\0'; p++)
2572  {
2573  while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2574  p++;
2575  first=(size_t) strtol(p,&q,10);
2576  last=first;
2577  while (isspace((int) ((unsigned char) *q)) != 0)
2578  q++;
2579  if (*q == '-')
2580  last=(size_t) strtol(q+1,&q,10);
2581  if (first > last)
2582  Swap(first,last);
2583  if (first < image_info->scene)
2584  image_info->scene=first;
2585  if (last > image_info->number_scenes)
2586  image_info->number_scenes=last;
2587  p=q;
2588  }
2589  image_info->number_scenes-=image_info->scene-1;
2590  }
2591  }
2592  *component='\0';
2593  if (*image_info->magick == '\0')
2594  GetPathComponent(image_info->filename,ExtensionPath,component);
2595 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2596  if (*component != '\0')
2597  if ((LocaleCompare(component,"gz") == 0) ||
2598  (LocaleCompare(component,"Z") == 0) ||
2599  (LocaleCompare(component,"svgz") == 0) ||
2600  (LocaleCompare(component,"wmz") == 0))
2601  {
2602  char
2603  path[MagickPathExtent];
2604 
2605  (void) CopyMagickString(path,image_info->filename,MagickPathExtent);
2606  path[strlen(path)-strlen(component)-1]='\0';
2607  GetPathComponent(path,ExtensionPath,component);
2608  }
2609 #endif
2610 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2611  if (*component != '\0')
2612  if (LocaleCompare(component,"bz2") == 0)
2613  {
2614  char
2615  path[MagickPathExtent];
2616 
2617  (void) CopyMagickString(path,image_info->filename,MagickPathExtent);
2618  path[strlen(path)-strlen(component)-1]='\0';
2619  GetPathComponent(path,ExtensionPath,component);
2620  }
2621 #endif
2622  image_info->affirm=MagickFalse;
2623  sans_exception=AcquireExceptionInfo();
2624  if (*component != '\0')
2625  {
2627  format_type;
2628 
2629  register ssize_t
2630  i;
2631 
2632  static const char
2633  *format_type_formats[] =
2634  {
2635  "AUTOTRACE",
2636  "BROWSE",
2637  "DCRAW",
2638  "EDIT",
2639  "LAUNCH",
2640  "MPEG:DECODE",
2641  "MPEG:ENCODE",
2642  "PRINT",
2643  "PS:ALPHA",
2644  "PS:CMYK",
2645  "PS:COLOR",
2646  "PS:GRAY",
2647  "PS:MONO",
2648  "SCAN",
2649  "SHOW",
2650  "WIN",
2651  (char *) NULL
2652  };
2653 
2654  /*
2655  User specified image format.
2656  */
2657  (void) CopyMagickString(magic,component,MagickPathExtent);
2658  LocaleUpper(magic);
2659  /*
2660  Look for explicit image formats.
2661  */
2662  format_type=UndefinedFormatType;
2663  magick_info=GetMagickInfo(magic,sans_exception);
2664  if ((magick_info != (const MagickInfo *) NULL) &&
2665  (magick_info->format_type != UndefinedFormatType))
2666  format_type=magick_info->format_type;
2667  i=0;
2668  while ((format_type == UndefinedFormatType) &&
2669  (format_type_formats[i] != (char *) NULL))
2670  {
2671  if ((*magic == *format_type_formats[i]) &&
2672  (LocaleCompare(magic,format_type_formats[i]) == 0))
2673  format_type=ExplicitFormatType;
2674  i++;
2675  }
2676  if (format_type == UndefinedFormatType)
2677  (void) CopyMagickString(image_info->magick,magic,MagickPathExtent);
2678  else
2679  if (format_type == ExplicitFormatType)
2680  {
2681  image_info->affirm=MagickTrue;
2682  (void) CopyMagickString(image_info->magick,magic,MagickPathExtent);
2683  }
2684  if (LocaleCompare(magic,"RGB") == 0)
2685  image_info->affirm=MagickFalse; /* maybe SGI disguised as RGB */
2686  }
2687  /*
2688  Look for explicit 'format:image' in filename.
2689  */
2690  *magic='\0';
2691  GetPathComponent(image_info->filename,MagickPath,magic);
2692  if (*magic == '\0')
2693  {
2694  (void) CopyMagickString(magic,image_info->magick,MagickPathExtent);
2695  magick_info=GetMagickInfo(magic,sans_exception);
2696  GetPathComponent(image_info->filename,CanonicalPath,component);
2697  (void) CopyMagickString(image_info->filename,component,MagickPathExtent);
2698  }
2699  else
2700  {
2701  const DelegateInfo
2702  *delegate_info;
2703 
2704  /*
2705  User specified image format.
2706  */
2707  LocaleUpper(magic);
2708  magick_info=GetMagickInfo(magic,sans_exception);
2709  delegate_info=GetDelegateInfo(magic,"*",sans_exception);
2710  if (delegate_info == (const DelegateInfo *) NULL)
2711  delegate_info=GetDelegateInfo("*",magic,sans_exception);
2712  if (((magick_info != (const MagickInfo *) NULL) ||
2713  (delegate_info != (const DelegateInfo *) NULL)) &&
2714  (IsMagickConflict(magic) == MagickFalse))
2715  {
2716  image_info->affirm=MagickTrue;
2717  (void) CopyMagickString(image_info->magick,magic,MagickPathExtent);
2718  GetPathComponent(image_info->filename,CanonicalPath,component);
2719  (void) CopyMagickString(image_info->filename,component,
2721  }
2722  }
2723  sans_exception=DestroyExceptionInfo(sans_exception);
2724  if ((magick_info == (const MagickInfo *) NULL) ||
2725  (GetMagickEndianSupport(magick_info) == MagickFalse))
2726  image_info->endian=UndefinedEndian;
2727  if ((image_info->adjoin != MagickFalse) && (frames > 1))
2728  {
2729  /*
2730  Test for multiple image support (e.g. image%02d.png).
2731  */
2732  (void) InterpretImageFilename(image_info,(Image *) NULL,
2733  image_info->filename,(int) image_info->scene,component,exception);
2734  if ((LocaleCompare(component,image_info->filename) != 0) &&
2735  (strchr(component,'%') == (char *) NULL))
2736  image_info->adjoin=MagickFalse;
2737  }
2738  if ((image_info->adjoin != MagickFalse) && (frames > 0))
2739  {
2740  /*
2741  Some image formats do not support multiple frames per file.
2742  */
2743  magick_info=GetMagickInfo(magic,exception);
2744  if (magick_info != (const MagickInfo *) NULL)
2745  if (GetMagickAdjoin(magick_info) == MagickFalse)
2746  image_info->adjoin=MagickFalse;
2747  }
2748  if (image_info->affirm != MagickFalse)
2749  return(MagickTrue);
2750  if (frames == 0)
2751  {
2752  unsigned char
2753  *magick;
2754 
2755  size_t
2756  magick_size;
2757 
2758  /*
2759  Determine the image format from the first few bytes of the file.
2760  */
2761  magick_size=GetMagicPatternExtent(exception);
2762  if (magick_size == 0)
2763  return(MagickFalse);
2764  image=AcquireImage(image_info,exception);
2765  (void) CopyMagickString(image->filename,image_info->filename,
2767  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
2768  if (status == MagickFalse)
2769  {
2770  image=DestroyImage(image);
2771  return(MagickFalse);
2772  }
2773  if ((IsBlobSeekable(image) == MagickFalse) ||
2774  (IsBlobExempt(image) != MagickFalse))
2775  {
2776  /*
2777  Copy standard input or pipe to temporary file.
2778  */
2779  *component='\0';
2780  status=ImageToFile(image,component,exception);
2781  (void) CloseBlob(image);
2782  if (status == MagickFalse)
2783  {
2784  image=DestroyImage(image);
2785  return(MagickFalse);
2786  }
2787  SetImageInfoFile(image_info,(FILE *) NULL);
2788  (void) CopyMagickString(image->filename,component,MagickPathExtent);
2789  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
2790  if (status == MagickFalse)
2791  {
2792  image=DestroyImage(image);
2793  return(MagickFalse);
2794  }
2795  (void) CopyMagickString(image_info->filename,component,
2797  image_info->temporary=MagickTrue;
2798  }
2799  magick=(unsigned char *) AcquireMagickMemory(magick_size);
2800  if (magick == (unsigned char *) NULL)
2801  {
2802  (void) CloseBlob(image);
2803  image=DestroyImage(image);
2804  return(MagickFalse);
2805  }
2806  (void) ResetMagickMemory(magick,0,magick_size);
2807  count=ReadBlob(image,magick_size,magick);
2808  (void) SeekBlob(image,-((MagickOffsetType) count),SEEK_CUR);
2809  (void) CloseBlob(image);
2810  image=DestroyImage(image);
2811  /*
2812  Check magic.xml configuration file.
2813  */
2814  sans_exception=AcquireExceptionInfo();
2815  magic_info=GetMagicInfo(magick,(size_t) count,sans_exception);
2816  magick=(unsigned char *) RelinquishMagickMemory(magick);
2817  if ((magic_info != (const MagicInfo *) NULL) &&
2818  (GetMagicName(magic_info) != (char *) NULL))
2819  {
2820  /*
2821  Try to use magick_info that was determined earlier by the extension
2822  */
2823  if ((magick_info != (const MagickInfo *) NULL) &&
2824  (GetMagickUseExtension(magick_info) != MagickFalse) &&
2825  (LocaleCompare(magick_info->module,GetMagicName(
2826  magic_info)) == 0))
2827  (void) CopyMagickString(image_info->magick,magick_info->name,
2829  else
2830  {
2831  (void) CopyMagickString(image_info->magick,GetMagicName(
2832  magic_info),MagickPathExtent);
2833  magick_info=GetMagickInfo(image_info->magick,sans_exception);
2834  }
2835  if ((magick_info == (const MagickInfo *) NULL) ||
2836  (GetMagickEndianSupport(magick_info) == MagickFalse))
2837  image_info->endian=UndefinedEndian;
2838  sans_exception=DestroyExceptionInfo(sans_exception);
2839  return(MagickTrue);
2840  }
2841  magick_info=GetMagickInfo(image_info->magick,sans_exception);
2842  if ((magick_info == (const MagickInfo *) NULL) ||
2843  (GetMagickEndianSupport(magick_info) == MagickFalse))
2844  image_info->endian=UndefinedEndian;
2845  sans_exception=DestroyExceptionInfo(sans_exception);
2846  }
2847  return(MagickTrue);
2848 }
2849 
2850 /*
2851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2852 % %
2853 % %
2854 % %
2855 % S e t I m a g e I n f o B l o b %
2856 % %
2857 % %
2858 % %
2859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2860 %
2861 % SetImageInfoBlob() sets the image info blob member.
2862 %
2863 % The format of the SetImageInfoBlob method is:
2864 %
2865 % void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
2866 % const size_t length)
2867 %
2868 % A description of each parameter follows:
2869 %
2870 % o image_info: the image info.
2871 %
2872 % o blob: the blob.
2873 %
2874 % o length: the blob length.
2875 %
2876 */
2877 MagickExport void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
2878  const size_t length)
2879 {
2880  assert(image_info != (ImageInfo *) NULL);
2881  assert(image_info->signature == MagickCoreSignature);
2882  if (image_info->debug != MagickFalse)
2884  image_info->filename);
2885  image_info->blob=(void *) blob;
2886  image_info->length=length;
2887 }
2888 
2889 /*
2890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2891 % %
2892 % %
2893 % %
2894 % S e t I m a g e I n f o F i l e %
2895 % %
2896 % %
2897 % %
2898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2899 %
2900 % SetImageInfoFile() sets the image info file member.
2901 %
2902 % The format of the SetImageInfoFile method is:
2903 %
2904 % void SetImageInfoFile(ImageInfo *image_info,FILE *file)
2905 %
2906 % A description of each parameter follows:
2907 %
2908 % o image_info: the image info.
2909 %
2910 % o file: the file.
2911 %
2912 */
2913 MagickExport void SetImageInfoFile(ImageInfo *image_info,FILE *file)
2914 {
2915  assert(image_info != (ImageInfo *) NULL);
2916  assert(image_info->signature == MagickCoreSignature);
2917  if (image_info->debug != MagickFalse)
2919  image_info->filename);
2920  image_info->file=file;
2921 }
2922 
2923 /*
2924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2925 % %
2926 % %
2927 % %
2928 % S e t I m a g e A l p h a %
2929 % %
2930 % %
2931 % %
2932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2933 %
2934 % SetImageAlpha() sets the alpha levels of the image.
2935 %
2936 % The format of the SetImageAlpha method is:
2937 %
2938 % MagickBooleanType SetImageAlpha(Image *image,const Quantum alpha,
2939 % ExceptionInfo *exception)
2940 %
2941 % A description of each parameter follows:
2942 %
2943 % o image: the image.
2944 %
2945 % o Alpha: the level of transparency: 0 is fully opaque and QuantumRange is
2946 % fully transparent.
2947 %
2948 */
2951 {
2952  CacheView
2953  *image_view;
2954 
2956  status;
2957 
2958  ssize_t
2959  y;
2960 
2961  assert(image != (Image *) NULL);
2962  if (image->debug != MagickFalse)
2963  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2964  assert(image->signature == MagickCoreSignature);
2966  status=MagickTrue;
2967  image_view=AcquireAuthenticCacheView(image,exception);
2968 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2969  #pragma omp parallel for schedule(static,4) shared(status) \
2970  magick_threads(image,image,image->rows,1)
2971 #endif
2972  for (y=0; y < (ssize_t) image->rows; y++)
2973  {
2974  register Quantum
2975  *magick_restrict q;
2976 
2977  register ssize_t
2978  x;
2979 
2980  if (status == MagickFalse)
2981  continue;
2982  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2983  if (q == (Quantum *) NULL)
2984  {
2985  status=MagickFalse;
2986  continue;
2987  }
2988  for (x=0; x < (ssize_t) image->columns; x++)
2989  {
2990  if (GetPixelWriteMask(image,q) != 0)
2991  SetPixelAlpha(image,alpha,q);
2992  q+=GetPixelChannels(image);
2993  }
2994  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
2995  status=MagickFalse;
2996  }
2997  image_view=DestroyCacheView(image_view);
2998  return(status);
2999 }
3000 
3001 /*
3002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3003 % %
3004 % %
3005 % %
3006 % S e t I m a g e M a s k %
3007 % %
3008 % %
3009 % %
3010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3011 %
3012 % SetImageMask() associates a mask with the image. The mask must be the same
3013 % dimensions as the image.
3014 %
3015 % The format of the SetImageMask method is:
3016 %
3017 % MagickBooleanType SetImageMask(Image *image,const PixelMask type,
3018 % const Image *mask,ExceptionInfo *exception)
3019 %
3020 % A description of each parameter follows:
3021 %
3022 % o image: the image.
3023 %
3024 % o type: the mask type, ReadPixelMask or WritePixelMask.
3025 %
3026 % o mask: the image mask.
3027 %
3028 % o exception: return any errors or warnings in this structure.
3029 %
3030 */
3032  const Image *mask,ExceptionInfo *exception)
3033 {
3034  CacheView
3035  *mask_view,
3036  *image_view;
3037 
3039  status;
3040 
3041  ssize_t
3042  y;
3043 
3044  /*
3045  Set image mask.
3046  */
3047  assert(image != (Image *) NULL);
3048  if (image->debug != MagickFalse)
3049  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3050  assert(image->signature == MagickCoreSignature);
3051  if (mask == (const Image *) NULL)
3052  {
3053  switch (type)
3054  {
3055  case WritePixelMask: image->write_mask=MagickFalse; break;
3056  default: image->read_mask=MagickFalse; break;
3057  }
3058  return(SyncImagePixelCache(image,exception));
3059  }
3060  switch (type)
3061  {
3062  case WritePixelMask: image->write_mask=MagickTrue; break;
3063  default: image->read_mask=MagickTrue; break;
3064  }
3065  if (SyncImagePixelCache(image,exception) == MagickFalse)
3066  return(MagickFalse);
3067  status=MagickTrue;
3068  mask_view=AcquireVirtualCacheView(mask,exception);
3069  image_view=AcquireAuthenticCacheView(image,exception);
3070 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3071  #pragma omp parallel for schedule(static,4) shared(status) \
3072  magick_threads(mask,image,1,1)
3073 #endif
3074  for (y=0; y < (ssize_t) image->rows; y++)
3075  {
3076  register const Quantum
3077  *magick_restrict p;
3078 
3079  register Quantum
3080  *magick_restrict q;
3081 
3082  register ssize_t
3083  x;
3084 
3085  if (status == MagickFalse)
3086  continue;
3087  p=GetCacheViewVirtualPixels(mask_view,0,y,mask->columns,1,exception);
3088  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3089  if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
3090  {
3091  status=MagickFalse;
3092  continue;
3093  }
3094  for (x=0; x < (ssize_t) image->columns; x++)
3095  {
3097  intensity;
3098 
3099  intensity=0;
3100  if ((x < (ssize_t) mask->columns) && (y < (ssize_t) mask->rows))
3101  intensity=GetPixelIntensity(mask,p);
3102  switch (type)
3103  {
3104  case WritePixelMask:
3105  {
3106  SetPixelWriteMask(image,ClampToQuantum(intensity),q);
3107  break;
3108  }
3109  default:
3110  {
3111  SetPixelReadMask(image,ClampToQuantum(intensity),q);
3112  break;
3113  }
3114  }
3115  p+=GetPixelChannels(mask);
3116  q+=GetPixelChannels(image);
3117  }
3118  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3119  status=MagickFalse;
3120  }
3121  mask_view=DestroyCacheView(mask_view);
3122  image_view=DestroyCacheView(image_view);
3123  return(status);
3124 }
3125 
3126 /*
3127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3128 % %
3129 % %
3130 % %
3131 % S e t I m a g e R e g i o n M a s k %
3132 % %
3133 % %
3134 % %
3135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136 %
3137 % SetImageRegionMask() associates a mask with the image as defined by the
3138 % specified region.
3139 %
3140 % The format of the SetImageRegionMask method is:
3141 %
3142 % MagickBooleanType SetImageRegionMask(Image *image,const PixelMask type,
3143 % const RectangleInfo *region,ExceptionInfo *exception)
3144 %
3145 % A description of each parameter follows:
3146 %
3147 % o image: the image.
3148 %
3149 % o type: the mask type, ReadPixelMask or WritePixelMask.
3150 %
3151 % o geometry: the mask region.
3152 %
3153 % o exception: return any errors or warnings in this structure.
3154 %
3155 */
3157  const PixelMask type,const RectangleInfo *region,ExceptionInfo *exception)
3158 {
3159  CacheView
3160  *image_view;
3161 
3163  status;
3164 
3165  ssize_t
3166  y;
3167 
3168  /*
3169  Set image mask as defined by the region.
3170  */
3171  assert(image != (Image *) NULL);
3172  if (image->debug != MagickFalse)
3173  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3174  assert(image->signature == MagickCoreSignature);
3175  if (region == (const RectangleInfo *) NULL)
3176  {
3177  switch (type)
3178  {
3179  case WritePixelMask: image->write_mask=MagickFalse; break;
3180  default: image->read_mask=MagickFalse; break;
3181  }
3182  return(SyncImagePixelCache(image,exception));
3183  }
3184  switch (type)
3185  {
3186  case WritePixelMask: image->write_mask=MagickTrue; break;
3187  default: image->read_mask=MagickTrue; break;
3188  }
3189  if (SyncImagePixelCache(image,exception) == MagickFalse)
3190  return(MagickFalse);
3191  status=MagickTrue;
3192  image_view=AcquireAuthenticCacheView(image,exception);
3193 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3194  #pragma omp parallel for schedule(static,4) shared(status) \
3195  magick_threads(image,image,1,1)
3196 #endif
3197  for (y=0; y < (ssize_t) image->rows; y++)
3198  {
3199  register Quantum
3200  *magick_restrict q;
3201 
3202  register ssize_t
3203  x;
3204 
3205  if (status == MagickFalse)
3206  continue;
3207  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3208  if (q == (Quantum *) NULL)
3209  {
3210  status=MagickFalse;
3211  continue;
3212  }
3213  for (x=0; x < (ssize_t) image->columns; x++)
3214  {
3215  Quantum
3216  pixel;
3217 
3218  pixel=0;
3219  if (((x >= region->x) && (x < (region->x+(ssize_t) region->width))) &&
3220  ((y >= region->y) && (y < (region->y+(ssize_t) region->height))))
3221  pixel=QuantumRange;
3222  switch (type)
3223  {
3224  case WritePixelMask:
3225  {
3226  SetPixelWriteMask(image,pixel,q);
3227  break;
3228  }
3229  default:
3230  {
3231  SetPixelReadMask(image,pixel,q);
3232  break;
3233  }
3234  }
3235  q+=GetPixelChannels(image);
3236  }
3237  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3238  status=MagickFalse;
3239  }
3240  image_view=DestroyCacheView(image_view);
3241  return(status);
3242 }
3243 
3244 /*
3245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3246 % %
3247 % %
3248 % %
3249 % 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 %
3250 % %
3251 % %
3252 % %
3253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3254 %
3255 % SetImageVirtualPixelMethod() sets the "virtual pixels" method for the
3256 % image and returns the previous setting. A virtual pixel is any pixel access
3257 % that is outside the boundaries of the image cache.
3258 %
3259 % The format of the SetImageVirtualPixelMethod() method is:
3260 %
3261 % VirtualPixelMethod SetImageVirtualPixelMethod(Image *image,
3262 % const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
3263 %
3264 % A description of each parameter follows:
3265 %
3266 % o image: the image.
3267 %
3268 % o virtual_pixel_method: choose the type of virtual pixel.
3269 %
3270 % o exception: return any errors or warnings in this structure.
3271 %
3272 */
3274  const VirtualPixelMethod virtual_pixel_method,ExceptionInfo *exception)
3275 {
3276  assert(image != (const Image *) NULL);
3277  assert(image->signature == MagickCoreSignature);
3278  if (image->debug != MagickFalse)
3279  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3280  return(SetPixelCacheVirtualMethod(image,virtual_pixel_method,exception));
3281 }
3282 
3283 /*
3284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285 % %
3286 % %
3287 % %
3288 % S m u s h I m a g e s %
3289 % %
3290 % %
3291 % %
3292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3293 %
3294 % SmushImages() takes all images from the current image pointer to the end
3295 % of the image list and smushes them to each other top-to-bottom if the
3296 % stack parameter is true, otherwise left-to-right.
3297 %
3298 % The current gravity setting now effects how the image is justified in the
3299 % final image.
3300 %
3301 % The format of the SmushImages method is:
3302 %
3303 % Image *SmushImages(const Image *images,const MagickBooleanType stack,
3304 % ExceptionInfo *exception)
3305 %
3306 % A description of each parameter follows:
3307 %
3308 % o images: the image sequence.
3309 %
3310 % o stack: A value other than 0 stacks the images top-to-bottom.
3311 %
3312 % o offset: minimum distance in pixels between images.
3313 %
3314 % o exception: return any errors or warnings in this structure.
3315 %
3316 */
3317 
3318 static ssize_t SmushXGap(const Image *smush_image,const Image *images,
3319  const ssize_t offset,ExceptionInfo *exception)
3320 {
3321  CacheView
3322  *left_view,
3323  *right_view;
3324 
3325  const Image
3326  *left_image,
3327  *right_image;
3328 
3330  left_geometry,
3331  right_geometry;
3332 
3333  register const Quantum
3334  *p;
3335 
3336  register ssize_t
3337  i,
3338  y;
3339 
3340  size_t
3341  gap;
3342 
3343  ssize_t
3344  x;
3345 
3346  if (images->previous == (Image *) NULL)
3347  return(0);
3348  right_image=images;
3349  SetGeometry(smush_image,&right_geometry);
3350  GravityAdjustGeometry(right_image->columns,right_image->rows,
3351  right_image->gravity,&right_geometry);
3352  left_image=images->previous;
3353  SetGeometry(smush_image,&left_geometry);
3354  GravityAdjustGeometry(left_image->columns,left_image->rows,
3355  left_image->gravity,&left_geometry);
3356  gap=right_image->columns;
3357  left_view=AcquireVirtualCacheView(left_image,exception);
3358  right_view=AcquireVirtualCacheView(right_image,exception);
3359  for (y=0; y < (ssize_t) smush_image->rows; y++)
3360  {
3361  for (x=(ssize_t) left_image->columns-1; x > 0; x--)
3362  {
3363  p=GetCacheViewVirtualPixels(left_view,x,left_geometry.y+y,1,1,exception);
3364  if ((p == (const Quantum *) NULL) ||
3365  (GetPixelAlpha(left_image,p) != TransparentAlpha) ||
3366  ((left_image->columns-x-1) >= gap))
3367  break;
3368  }
3369  i=(ssize_t) left_image->columns-x-1;
3370  for (x=0; x < (ssize_t) right_image->columns; x++)
3371  {
3372  p=GetCacheViewVirtualPixels(right_view,x,right_geometry.y+y,1,1,
3373  exception);
3374  if ((p == (const Quantum *) NULL) ||
3375  (GetPixelAlpha(right_image,p) != TransparentAlpha) ||
3376  ((x+i) >= (ssize_t) gap))
3377  break;
3378  }
3379  if ((x+i) < (ssize_t) gap)
3380  gap=(size_t) (x+i);
3381  }
3382  right_view=DestroyCacheView(right_view);
3383  left_view=DestroyCacheView(left_view);
3384  if (y < (ssize_t) smush_image->rows)
3385  return(offset);
3386  return((ssize_t) gap-offset);
3387 }
3388 
3389 static ssize_t SmushYGap(const Image *smush_image,const Image *images,
3390  const ssize_t offset,ExceptionInfo *exception)
3391 {
3392  CacheView
3393  *bottom_view,
3394  *top_view;
3395 
3396  const Image
3397  *bottom_image,
3398  *top_image;
3399 
3401  bottom_geometry,
3402  top_geometry;
3403 
3404  register const Quantum
3405  *p;
3406 
3407  register ssize_t
3408  i,
3409  x;
3410 
3411  size_t
3412  gap;
3413 
3414  ssize_t
3415  y;
3416 
3417  if (images->previous == (Image *) NULL)
3418  return(0);
3419  bottom_image=images;
3420  SetGeometry(smush_image,&bottom_geometry);
3421  GravityAdjustGeometry(bottom_image->columns,bottom_image->rows,
3422  bottom_image->gravity,&bottom_geometry);
3423  top_image=images->previous;
3424  SetGeometry(smush_image,&top_geometry);
3425  GravityAdjustGeometry(top_image->columns,top_image->rows,top_image->gravity,
3426  &top_geometry);
3427  gap=bottom_image->rows;
3428  top_view=AcquireVirtualCacheView(top_image,exception);
3429  bottom_view=AcquireVirtualCacheView(bottom_image,exception);
3430  for (x=0; x < (ssize_t) smush_image->columns; x++)
3431  {
3432  for (y=(ssize_t) top_image->rows-1; y > 0; y--)
3433  {
3434  p=GetCacheViewVirtualPixels(top_view,top_geometry.x+x,y,1,1,exception);
3435  if ((p == (const Quantum *) NULL) ||
3436  (GetPixelAlpha(top_image,p) != TransparentAlpha) ||
3437  ((top_image->rows-y-1) >= gap))
3438  break;
3439  }
3440  i=(ssize_t) top_image->rows-y-1;
3441  for (y=0; y < (ssize_t) bottom_image->rows; y++)
3442  {
3443  p=GetCacheViewVirtualPixels(bottom_view,bottom_geometry.x+x,y,1,1,
3444  exception);
3445  if ((p == (const Quantum *) NULL) ||
3446  (GetPixelAlpha(bottom_image,p) != TransparentAlpha) ||
3447  ((y+i) >= (ssize_t) gap))
3448  break;
3449  }
3450  if ((y+i) < (ssize_t) gap)
3451  gap=(size_t) (y+i);
3452  }
3453  bottom_view=DestroyCacheView(bottom_view);
3454  top_view=DestroyCacheView(top_view);
3455  if (x < (ssize_t) smush_image->columns)
3456  return(offset);
3457  return((ssize_t) gap-offset);
3458 }
3459 
3461  const MagickBooleanType stack,const ssize_t offset,ExceptionInfo *exception)
3462 {
3463 #define SmushImageTag "Smush/Image"
3464 
3465  const Image
3466  *image;
3467 
3468  Image
3469  *smush_image;
3470 
3472  proceed,
3473  status;
3474 
3476  n;
3477 
3478  PixelTrait
3479  alpha_trait;
3480 
3482  geometry;
3483 
3484  register const Image
3485  *next;
3486 
3487  size_t
3488  height,
3489  number_images,
3490  width;
3491 
3492  ssize_t
3493  x_offset,
3494  y_offset;
3495 
3496  /*
3497  Compute maximum area of smushed area.
3498  */
3499  assert(images != (Image *) NULL);
3500  assert(images->signature == MagickCoreSignature);
3501  if (images->debug != MagickFalse)
3502  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
3503  assert(exception != (ExceptionInfo *) NULL);
3504  assert(exception->signature == MagickCoreSignature);
3505  image=images;
3506  alpha_trait=image->alpha_trait;
3507  number_images=1;
3508  width=image->columns;
3509  height=image->rows;
3510  next=GetNextImageInList(image);
3511  for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
3512  {
3513  if (next->alpha_trait != UndefinedPixelTrait)
3514  alpha_trait=BlendPixelTrait;
3515  number_images++;
3516  if (stack != MagickFalse)
3517  {
3518  if (next->columns > width)
3519  width=next->columns;
3520  height+=next->rows;
3521  if (next->previous != (Image *) NULL)
3522  height+=offset;
3523  continue;
3524  }
3525  width+=next->columns;
3526  if (next->previous != (Image *) NULL)
3527  width+=offset;
3528  if (next->rows > height)
3529  height=next->rows;
3530  }
3531  /*
3532  Smush images.
3533  */
3534  smush_image=CloneImage(image,width,height,MagickTrue,exception);
3535  if (smush_image == (Image *) NULL)
3536  return((Image *) NULL);
3537  if (SetImageStorageClass(smush_image,DirectClass,exception) == MagickFalse)
3538  {
3539  smush_image=DestroyImage(smush_image);
3540  return((Image *) NULL);
3541  }
3542  smush_image->alpha_trait=alpha_trait;
3543  (void) SetImageBackgroundColor(smush_image,exception);
3544  status=MagickTrue;
3545  x_offset=0;
3546  y_offset=0;
3547  for (n=0; n < (MagickOffsetType) number_images; n++)
3548  {
3549  SetGeometry(smush_image,&geometry);
3550  GravityAdjustGeometry(image->columns,image->rows,image->gravity,&geometry);
3551  if (stack != MagickFalse)
3552  {
3553  x_offset-=geometry.x;
3554  y_offset-=SmushYGap(smush_image,image,offset,exception);
3555  }
3556  else
3557  {
3558  x_offset-=SmushXGap(smush_image,image,offset,exception);
3559  y_offset-=geometry.y;
3560  }
3561  status=CompositeImage(smush_image,image,OverCompositeOp,MagickTrue,x_offset,
3562  y_offset,exception);
3563  proceed=SetImageProgress(image,SmushImageTag,n,number_images);
3564  if (proceed == MagickFalse)
3565  break;
3566  if (stack == MagickFalse)
3567  {
3568  x_offset+=(ssize_t) image->columns;
3569  y_offset=0;
3570  }
3571  else
3572  {
3573  x_offset=0;
3574  y_offset+=(ssize_t) image->rows;
3575  }
3576  image=GetNextImageInList(image);
3577  }
3578  if (stack == MagickFalse)
3579  smush_image->columns=(size_t) x_offset;
3580  else
3581  smush_image->rows=(size_t) y_offset;
3582  if (status == MagickFalse)
3583  smush_image=DestroyImage(smush_image);
3584  return(smush_image);
3585 }
3586 
3587 /*
3588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3589 % %
3590 % %
3591 % %
3592 % S t r i p I m a g e %
3593 % %
3594 % %
3595 % %
3596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3597 %
3598 % StripImage() strips an image of all profiles and comments.
3599 %
3600 % The format of the StripImage method is:
3601 %
3602 % MagickBooleanType StripImage(Image *image,ExceptionInfo *exception)
3603 %
3604 % A description of each parameter follows:
3605 %
3606 % o image: the image.
3607 %
3608 % o exception: return any errors or warnings in this structure.
3609 %
3610 */
3612 {
3614  status;
3615 
3616  assert(image != (Image *) NULL);
3617  if (image->debug != MagickFalse)
3618  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3619  (void) exception;
3620  DestroyImageProfiles(image);
3621  (void) DeleteImageProperty(image,"comment");
3622  (void) DeleteImageProperty(image,"date:create");
3623  (void) DeleteImageProperty(image,"date:modify");
3624  status=SetImageArtifact(image,"png:exclude-chunk",
3625  "bKGD,cHRM,EXIF,gAMA,iCCP,iTXt,sRGB,tEXt,zCCP,zTXt,date");
3626  return(status);
3627 }
3628 
3629 /*
3630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3631 % %
3632 % %
3633 % %
3634 + S y n c I m a g e %
3635 % %
3636 % %
3637 % %
3638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3639 %
3640 % SyncImage() initializes the red, green, and blue intensities of each pixel
3641 % as defined by the colormap index.
3642 %
3643 % The format of the SyncImage method is:
3644 %
3645 % MagickBooleanType SyncImage(Image *image,ExceptionInfo *exception)
3646 %
3647 % A description of each parameter follows:
3648 %
3649 % o image: the image.
3650 %
3651 % o exception: return any errors or warnings in this structure.
3652 %
3653 */
3654 
3655 static inline Quantum PushColormapIndex(Image *image,const Quantum index,
3656  MagickBooleanType *range_exception)
3657 {
3658  if ((size_t) index < image->colors)
3659  return(index);
3660  *range_exception=MagickTrue;
3661  return((Quantum) 0);
3662 }
3663 
3665 {
3666  CacheView
3667  *image_view;
3668 
3670  range_exception,
3671  status,
3672  taint;
3673 
3674  ssize_t
3675  y;
3676 
3677  assert(image != (Image *) NULL);
3678  if (image->debug != MagickFalse)
3679  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3680  assert(image->signature == MagickCoreSignature);
3681  if (image->ping != MagickFalse)
3682  return(MagickTrue);
3683  if (image->storage_class != PseudoClass)
3684  return(MagickFalse);
3685  assert(image->colormap != (PixelInfo *) NULL);
3686  range_exception=MagickFalse;
3687  status=MagickTrue;
3688  taint=image->taint;
3689  image_view=AcquireAuthenticCacheView(image,exception);
3690 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3691  #pragma omp parallel for schedule(static,4) shared(range_exception,status) \
3692  magick_threads(image,image,image->rows,1)
3693 #endif
3694  for (y=0; y < (ssize_t) image->rows; y++)
3695  {
3696  Quantum
3697  index;
3698 
3699  register Quantum
3700  *magick_restrict q;
3701 
3702  register ssize_t
3703  x;
3704 
3705  if (status == MagickFalse)
3706  continue;
3707  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3708  if (q == (Quantum *) NULL)
3709  {
3710  status=MagickFalse;
3711  continue;
3712  }
3713  for (x=0; x < (ssize_t) image->columns; x++)
3714  {
3715  index=PushColormapIndex(image,GetPixelIndex(image,q),&range_exception);
3716  SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
3717  q+=GetPixelChannels(image);
3718  }
3719  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3720  status=MagickFalse;
3721  }
3722  image_view=DestroyCacheView(image_view);
3723  image->taint=taint;
3724  if ((image->ping == MagickFalse) && (range_exception != MagickFalse))
3725  (void) ThrowMagickException(exception,GetMagickModule(),
3726  CorruptImageWarning,"InvalidColormapIndex","`%s'",image->filename);
3727  return(status);
3728 }
3729 
3730 /*
3731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3732 % %
3733 % %
3734 % %
3735 % S y n c I m a g e S e t t i n g s %
3736 % %
3737 % %
3738 % %
3739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 %
3741 % SyncImageSettings() syncs any image_info global options into per-image
3742 % attributes.
3743 %
3744 % Note: in IMv6 free form 'options' were always mapped into 'artifacts', so
3745 % that operations and coders can find such settings. In IMv7 if a desired
3746 % per-image artifact is not set, then it will directly look for a global
3747 % option as a fallback, as such this copy is no longer needed, only the
3748 % link set up.
3749 %
3750 % The format of the SyncImageSettings method is:
3751 %
3752 % MagickBooleanType SyncImageSettings(const ImageInfo *image_info,
3753 % Image *image,ExceptionInfo *exception)
3754 % MagickBooleanType SyncImagesSettings(const ImageInfo *image_info,
3755 % Image *image,ExceptionInfo *exception)
3756 %
3757 % A description of each parameter follows:
3758 %
3759 % o image_info: the image info.
3760 %
3761 % o image: the image.
3762 %
3763 % o exception: return any errors or warnings in this structure.
3764 %
3765 */
3766 
3768  Image *images,ExceptionInfo *exception)
3769 {
3770  Image
3771  *image;
3772 
3773  assert(image_info != (const ImageInfo *) NULL);
3774  assert(image_info->signature == MagickCoreSignature);
3775  assert(images != (Image *) NULL);
3776  assert(images->signature == MagickCoreSignature);
3777  if (images->debug != MagickFalse)
3778  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
3779  image=images;
3780  for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
3781  (void) SyncImageSettings(image_info,image,exception);
3782  (void) DeleteImageOption(image_info,"page");
3783  return(MagickTrue);
3784 }
3785 
3788 {
3789  const char
3790  *option;
3791 
3792  GeometryInfo
3793  geometry_info;
3794 
3796  flags;
3797 
3799  units;
3800 
3801  /*
3802  Sync image options.
3803  */
3804  assert(image_info != (const ImageInfo *) NULL);
3805  assert(image_info->signature == MagickCoreSignature);
3806  assert(image != (Image *) NULL);
3807  assert(image->signature == MagickCoreSignature);
3808  if (image->debug != MagickFalse)
3809  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3810  option=GetImageOption(image_info,"alpha-color");
3811  if (option != (const char *) NULL)
3812  (void) QueryColorCompliance(option,AllCompliance,&image->alpha_color,
3813  exception);
3814  option=GetImageOption(image_info,"background");
3815  if (option != (const char *) NULL)
3816  (void) QueryColorCompliance(option,AllCompliance,&image->background_color,
3817  exception);
3818  option=GetImageOption(image_info,"black-point-compensation");
3819  if (option != (const char *) NULL)
3822  option=GetImageOption(image_info,"blue-primary");
3823  if (option != (const char *) NULL)
3824  {
3825  flags=ParseGeometry(option,&geometry_info);
3826  image->chromaticity.blue_primary.x=geometry_info.rho;
3827  image->chromaticity.blue_primary.y=geometry_info.sigma;
3828  if ((flags & SigmaValue) == 0)
3830  }
3831  option=GetImageOption(image_info,"bordercolor");
3832  if (option != (const char *) NULL)
3833  (void) QueryColorCompliance(option,AllCompliance,&image->border_color,
3834  exception);
3835  /* FUTURE: do not sync compose to per-image compose setting here */
3836  option=GetImageOption(image_info,"compose");
3837  if (option != (const char *) NULL)
3839  MagickFalse,option);
3840  /* -- */
3841  option=GetImageOption(image_info,"compress");
3842  if (option != (const char *) NULL)
3845  option=GetImageOption(image_info,"debug");
3846  if (option != (const char *) NULL)
3848  MagickFalse,option);
3849  option=GetImageOption(image_info,"density");
3850  if (option != (const char *) NULL)
3851  {
3852  flags=ParseGeometry(option,&geometry_info);
3853  image->resolution.x=geometry_info.rho;
3854  image->resolution.y=geometry_info.sigma;
3855  if ((flags & SigmaValue) == 0)
3856  image->resolution.y=image->resolution.x;
3857  }
3858  option=GetImageOption(image_info,"depth");
3859  if (option != (const char *) NULL)
3860  image->depth=StringToUnsignedLong(option);
3861  option=GetImageOption(image_info,"endian");
3862  if (option != (const char *) NULL)
3864  MagickFalse,option);
3865  option=GetImageOption(image_info,"filter");
3866  if (option != (const char *) NULL)
3868  MagickFalse,option);
3869  option=GetImageOption(image_info,"fuzz");
3870  if (option != (const char *) NULL)
3871  image->fuzz=StringToDoubleInterval(option,(double) QuantumRange+1.0);
3872  option=GetImageOption(image_info,"gravity");
3873  if (option != (const char *) NULL)
3875  MagickFalse,option);
3876  option=GetImageOption(image_info,"green-primary");
3877  if (option != (const char *) NULL)
3878  {
3879  flags=ParseGeometry(option,&geometry_info);
3880  image->chromaticity.green_primary.x=geometry_info.rho;
3881  image->chromaticity.green_primary.y=geometry_info.sigma;
3882  if ((flags & SigmaValue) == 0)
3884  }
3885  option=GetImageOption(image_info,"intent");
3886  if (option != (const char *) NULL)
3889  option=GetImageOption(image_info,"intensity");
3890  if (option != (const char *) NULL)
3893  option=GetImageOption(image_info,"interlace");
3894  if (option != (const char *) NULL)
3896  MagickFalse,option);
3897  option=GetImageOption(image_info,"interpolate");
3898  if (option != (const char *) NULL)
3901  option=GetImageOption(image_info,"loop");
3902  if (option != (const char *) NULL)
3903  image->iterations=StringToUnsignedLong(option);
3904  option=GetImageOption(image_info,"orient");
3905  if (option != (const char *) NULL)
3908  option=GetImageOption(image_info,"page");
3909  if (option != (const char *) NULL)
3910  {
3911  char
3912  *geometry;
3913 
3914  geometry=GetPageGeometry(option);
3915  flags=ParseAbsoluteGeometry(geometry,&image->page);
3916  geometry=DestroyString(geometry);
3917  }
3918  option=GetImageOption(image_info,"quality");
3919  if (option != (const char *) NULL)
3920  image->quality=StringToUnsignedLong(option);
3921  option=GetImageOption(image_info,"red-primary");
3922  if (option != (const char *) NULL)
3923  {
3924  flags=ParseGeometry(option,&geometry_info);
3925  image->chromaticity.red_primary.x=geometry_info.rho;
3926  image->chromaticity.red_primary.y=geometry_info.sigma;
3927  if ((flags & SigmaValue) == 0)
3929  }
3930  if (image_info->quality != UndefinedCompressionQuality)
3931  image->quality=image_info->quality;
3932  option=GetImageOption(image_info,"scene");
3933  if (option != (const char *) NULL)
3934  image->scene=StringToUnsignedLong(option);
3935  option=GetImageOption(image_info,"taint");
3936  if (option != (const char *) NULL)
3938  MagickFalse,option);
3939  option=GetImageOption(image_info,"tile-offset");
3940  if (option != (const char *) NULL)
3941  {
3942  char
3943  *geometry;
3944 
3945  geometry=GetPageGeometry(option);
3946  flags=ParseAbsoluteGeometry(geometry,&image->tile_offset);
3947  geometry=DestroyString(geometry);
3948  }
3949  option=GetImageOption(image_info,"transparent-color");
3950  if (option != (const char *) NULL)
3952  exception);
3953  option=GetImageOption(image_info,"type");
3954  if (option != (const char *) NULL)
3956  option);
3957  option=GetImageOption(image_info,"units");
3958  units=image_info->units;
3959  if (option != (const char *) NULL)
3961  MagickFalse,option);
3962  if (units != UndefinedResolution)
3963  {
3964  if (image->units != units)
3965  switch (image->units)
3966  {
3968  {
3969  if (units == PixelsPerCentimeterResolution)
3970  {
3971  image->resolution.x/=2.54;
3972  image->resolution.y/=2.54;
3973  }
3974  break;
3975  }
3977  {
3978  if (units == PixelsPerInchResolution)
3979  {
3980  image->resolution.x=(double) ((size_t) (100.0*2.54*
3981  image->resolution.x+0.5))/100.0;
3982  image->resolution.y=(double) ((size_t) (100.0*2.54*
3983  image->resolution.y+0.5))/100.0;
3984  }
3985  break;
3986  }
3987  default:
3988  break;
3989  }
3990  image->units=units;
3991  }
3992  option=GetImageOption(image_info,"virtual-pixel");
3993  if (option != (const char *) NULL)
3996  exception);
3997  option=GetImageOption(image_info,"white-point");
3998  if (option != (const char *) NULL)
3999  {
4000  flags=ParseGeometry(option,&geometry_info);
4001  image->chromaticity.white_point.x=geometry_info.rho;
4002  image->chromaticity.white_point.y=geometry_info.sigma;
4003  if ((flags & SigmaValue) == 0)
4005  }
4006  /*
4007  Pointer to allow the lookup of pre-image artifact will fallback to a global
4008  option setting/define. This saves a lot of duplication of global options
4009  into per-image artifacts, while ensuring only specifically set per-image
4010  artifacts are preserved when parenthesis ends.
4011  */
4012  if (image->image_info != (ImageInfo *) NULL)
4013  image->image_info=DestroyImageInfo(image->image_info);
4014  image->image_info=CloneImageInfo(image_info);
4015  return(MagickTrue);
4016 }
MagickExport Image * GetImageMask(const Image *image, const PixelMask type, ExceptionInfo *exception)
Definition: image.c:1432
size_t rows
Definition: image.h:175
#define magick_restrict
Definition: MagickCore.h:41
MagickExport FILE * GetImageInfoFile(const ImageInfo *image_info)
Definition: image.c:1402
MagickPrivate Cache DestroyPixelCache(Cache)
MagickExport MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
Definition: magick.c:935
MagickExport MagickBooleanType NegateImage(Image *image, const MagickBooleanType grayscale, ExceptionInfo *exception)
Definition: enhance.c:3433
PixelIntensityMethod intensity
Definition: image.h:225
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
Definition: cache-view.c:252
#define TransparentAlpha
Definition: image.h:29
EndianType endian
Definition: image.h:395
double fuzz
Definition: pixel.h:179
size_t signature
Definition: image.h:479
static MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
struct _Image * list
Definition: image.h:351
const char DefaultTileGeometry[]
Definition: image.c:112
PixelInfo * colormap
Definition: image.h:182
MagickExport ImageInfo * AcquireImageInfo(void)
Definition: image.c:342
InterlaceType interlace
Definition: image.h:228
MagickExport void DestroyImagePixels(Image *image)
Definition: cache.c:810
DisposeType dispose
Definition: image.h:240
Ascii85Info * ascii85
Definition: image.h:312
char magick[MagickPathExtent]
Definition: image.h:471
MagickProgressMonitor progress_monitor
Definition: image.h:306
MagickExport PixelChannelMap * AcquirePixelChannelMap(void)
Definition: pixel.c:93
char * scenes
Definition: image.h:381
ImageType type
Definition: image.h:267
size_t iterations
Definition: image.h:251
MagickExport ExceptionType CatchImageException(Image *image)
Definition: image.c:649
MagickExport MagickBooleanType SyncImage(Image *image, ExceptionInfo *exception)
Definition: image.c:3664
ssize_t ticks_per_second
Definition: image.h:248
static void SetPixelBackgoundColor(const Image *magick_restrict image, Quantum *magick_restrict pixel)
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
FilterType
Definition: resample.h:32
MagickExport Image * ReferenceImage(Image *image)
Definition: image.c:2116
FilterType filter
Definition: image.h:222
MagickExport MagickBooleanType DeleteImageOption(ImageInfo *image_info, const char *option)
Definition: option.c:1920
PixelTrait alpha_trait
Definition: pixel.h:176
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:449
MagickExport void Ascii85Initialize(Image *image)
Definition: compress.c:264
double pointsize
Definition: image.h:411
const char LoadImageTag[]
Definition: image.c:115
ssize_t y
Definition: geometry.h:115
static unsigned long StringToUnsignedLong(const char *magick_restrict value)
const char TransparentColor[]
Definition: image.c:121
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:2656
const char SaveImageTag[]
Definition: image.c:119
OrientationType
Definition: image.h:79
MagickBooleanType ping
Definition: image.h:276
char * extract
Definition: image.h:381
PixelInfo border_color
Definition: image.h:182
PixelInterpolateMethod
Definition: pixel.h:108
#define ThrowFatalException(severity, tag)
PixelInterpolateMethod interpolate
Definition: image.h:258
double x
Definition: image.h:102
size_t signature
Definition: exception.h:123
#define SmushImageTag
MagickExport Image * NewMagickImage(const ImageInfo *image_info, const size_t width, const size_t height, const PixelInfo *background, ExceptionInfo *exception)
Definition: image.c:2029
size_t number_scenes
Definition: image.h:387
char * sampling_factor
Definition: image.h:404
const char ForegroundColor[]
Definition: image.c:114
double rho
Definition: geometry.h:105
MagickExport MagickStatusType ParseAbsoluteGeometry(const char *geometry, RectangleInfo *region_info)
Definition: geometry.c:686
MagickExport const char * GetMagicName(const MagicInfo *magic_info)
Definition: magic.c:667
EndianType endian
Definition: image.h:231
MagickBooleanType taint
Definition: image.h:172
MagickExport size_t ConcatenateMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:411
PixelIntensityMethod
Definition: pixel.h:94
MagickBooleanType debug
Definition: image.h:476
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:191
MagickExport MagickBooleanType SyncImageSettings(const ImageInfo *image_info, Image *image, ExceptionInfo *exception)
Definition: image.c:3786
static void SetPixelGray(const Image *magick_restrict image, const Quantum gray, Quantum *magick_restrict pixel)
char * font
Definition: image.h:404
MagickExport MagickBooleanType SetImageArtifact(Image *image, const char *artifact, const char *value)
Definition: artifact.c:449
#define OpaqueAlpha
Definition: image.h:28
MagickExport const DelegateInfo * GetDelegateInfo(const char *decode, const char *encode, ExceptionInfo *exception)
Definition: delegate.c:1159
MagickPrivate MagickBooleanType SyncImagePixelCache(Image *, ExceptionInfo *)
Definition: cache.c:5194
InterlaceType
Definition: image.h:67
VirtualPixelMethod
Definition: cache-view.h:27
const char BorderColor[]
Definition: image.c:110
ColorspaceType colorspace
Definition: image.h:427
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
Definition: artifact.c:273
MagickPrivate Cache ReferencePixelCache(Cache)
Definition: cache.c:4469
char * module
Definition: magick.h:61
double z
Definition: image.h:102
MagickBooleanType antialias
Definition: image.h:375
char * name
Definition: magick.h:61
MagickExport MagickBooleanType SetImageAlpha(Image *image, const Quantum alpha, ExceptionInfo *exception)
Definition: image.c:2949
MagickBooleanType read_mask
Definition: image.h:279
const char PSDensityGeometry[]
Definition: image.c:117
PixelInfo transparent_color
Definition: image.h:415
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
MagickPrivate MagickBooleanType IsMagickConflict(const char *)
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:107
MagickExport void DestroyImageProfiles(Image *image)
Definition: profile.c:218
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:474
static void SetPixelViaPixelInfo(const Image *magick_restrict image, const PixelInfo *magick_restrict pixel_info, Quantum *magick_restrict pixel)
static Quantum GetPixelReadMask(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport void SetImageInfoBlob(ImageInfo *image_info, const void *blob, const size_t length)
Definition: image.c:2877
ResolutionType units
Definition: image.h:201
size_t delay
Definition: image.h:243
float_t MagickRealType
Definition: magick-type.h:63
char magick[MagickPathExtent]
Definition: image.h:322
size_t magick_rows
Definition: image.h:327
#define MAGICKCORE_QUANTUM_DEPTH
Definition: magick-type.h:28
MagickExport MagickBooleanType ImageToFile(Image *image, char *filename, ExceptionInfo *exception)
Definition: blob.c:1649
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:651
MagickBooleanType verbose
Definition: image.h:436
PixelInfo alpha_color
Definition: image.h:182
MagickRealType alpha
Definition: pixel.h:188
MagickExport const char * GetImageOption(const ImageInfo *image_info, const char *option)
Definition: option.c:1995
MagickExport char * GetPageGeometry(const char *page_geometry)
Definition: geometry.c:349
MagickPrivate VirtualPixelMethod GetPixelCacheVirtualMethod(const Image *)
Image * image
Definition: image-view.c:66
MagickFormatType format_type
Definition: magick.h:81
char * montage
Definition: image.h:204
CompressionType compression
Definition: image.h:163
double sigma
Definition: geometry.h:105
InterlaceType interlace
Definition: image.h:392
ClassType storage_class
Definition: image.h:157
MagickExport MagickBooleanType CompositeImage(Image *image, const Image *composite, const CompositeOperator compose, const MagickBooleanType clip_to_self, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
Definition: composite.c:515
size_t width
Definition: geometry.h:129
MagickExport BlobInfo * CloneBlobInfo(const BlobInfo *)
RectangleInfo tile_offset
Definition: image.h:264
MagickPrivate Cache ClonePixelCache(const Cache)
#define ThrowBinaryException(severity, tag, context)
Definition: log.h:52
ssize_t MagickOffsetType
Definition: magick-type.h:116
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
Definition: pixel.c:2162
MagickExport void DestroyImageOptions(ImageInfo *image_info)
Definition: option.c:1956
EndianType
Definition: quantum.h:28
char * size
Definition: image.h:381
MagickExport void SetImageInfoFile(ImageInfo *image_info, FILE *file)
Definition: image.c:2913
Definition: image.h:154
void * cache
Definition: image.h:455
MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
Definition: image.c:1574
ExceptionType
Definition: exception.h:27
ImageType type
Definition: image.h:433
const char SaveImagesTag[]
Definition: image.c:120
StreamHandler stream
Definition: image.h:459
size_t number_meta_channels
Definition: image.h:286
double x
Definition: geometry.h:122
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:292
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:299
MagickExport MagickBooleanType CloneImageProperties(Image *image, const Image *clone_image)
Definition: property.c:134
MagickExport MagickBooleanType SetImageMask(Image *image, const PixelMask type, const Image *mask, ExceptionInfo *exception)
Definition: image.c:3031
#define UndefinedTicksPerSecond
Definition: image-private.h:35
MagickExport MagickBooleanType IsGeometry(const char *geometry)
Definition: geometry.c:593
MagickExport Image * BlobToImage(const ImageInfo *image_info, const void *blob, const size_t length, ExceptionInfo *exception)
Definition: blob.c:317
const double DefaultResolution
Definition: image.c:124
static ssize_t SmushXGap(const Image *smush_image, const Image *images, const ssize_t offset, ExceptionInfo *exception)
Definition: image.c:3318
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1198
ChannelType channel
Definition: image.h:440
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelOption alpha_type, ExceptionInfo *exception)
Definition: channel.c:950
MagickBooleanType
Definition: magick-type.h:145
MagickExport PixelChannelMap * ClonePixelChannelMap(PixelChannelMap *channel_map)
Definition: pixel.c:133
MagickPrivate void ClonePixelCacheMethods(Cache, const Cache)
MagickExport Image * NewImageList(void)
Definition: list.c:916
PrimaryInfo red_primary
Definition: image.h:128
size_t scene
Definition: image.h:243
unsigned int MagickStatusType
Definition: magick-type.h:108
MagickExport char * AcquireString(const char *source)
Definition: string.c:123
ClassType
Definition: magick-type.h:138
ExceptionInfo * exception
Definition: image-view.c:72
const char PSPageGeometry[]
Definition: image.c:118
MagickBooleanType black_point_compensation
Definition: image.h:261
MagickExport MagickBooleanType IsImageObject(const Image *image)
Definition: image.c:1885
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1128
size_t length
Definition: image.h:468
struct _ImageInfo * image_info
Definition: image.h:345
MagickExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition: string.c:838
static Quantum GetPixelWriteMask(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:525
char filename[MagickPathExtent]
Definition: image.h:471
MagickExport MagickBooleanType CloneImageProfiles(Image *image, const Image *clone_image)
Definition: profile.c:141
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1512
double y
Definition: geometry.h:122
void * blob
Definition: image.h:465
const char BackgroundColor[]
Definition: image.c:109
MagickExport ssize_t ReadBlob(Image *, const size_t, void *)
const char AlphaColor[]
Definition: image.c:108
MagickExport MagickBooleanType ClipImagePath(Image *image, const char *pathname, const MagickBooleanType inside, ExceptionInfo *exception)
Definition: image.c:706
double fuzz
Definition: image.h:411
ChannelType channel_mask
Definition: image.h:291
GravityType gravity
Definition: image.h:234
MagickExport MagickBooleanType CloseBlob(Image *)
volatile ssize_t reference_count
Definition: image.h:340
size_t scene
Definition: image.h:387
RectangleInfo page
Definition: image.h:215
MagickExport void DestroyImageProperties(Image *image)
Definition: property.c:314
size_t magick_columns
Definition: image.h:327
#define UndefinedCompressionQuality
Definition: image-private.h:36
size_t MagickSizeType
Definition: magick-type.h:117
#define MagickPathExtent
void * cache
Definition: image.h:297
ResolutionType units
Definition: image.h:398
MagickExport PixelChannelMap * DestroyPixelChannelMap(PixelChannelMap *channel_map)
Definition: pixel.c:351
const char LoadImagesTag[]
Definition: image.c:116
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1456
static void GetPixelInfoPixel(const Image *magick_restrict image, const Quantum *magick_restrict pixel, PixelInfo *magick_restrict pixel_info)
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:692
CompressionType compression
Definition: image.h:369
PixelInfo alpha_color
Definition: image.h:415
const char DefaultTileLabel[]
Definition: image.c:113
PrimaryInfo blue_primary
Definition: image.h:128
#define ThrowFileException(exception, severity, tag, context)
OrientationType orientation
Definition: image.h:372
PixelTrait alpha_trait
Definition: image.h:283
MagickExport void AcquireNextImage(const ImageInfo *image_info, Image *image, ExceptionInfo *exception)
Definition: image.c:385
MagickExport ChannelType SetPixelChannelMask(Image *image, const ChannelType channel_mask)
Definition: pixel.c:6254
static Quantum GetPixelIndex(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport void DisassociateBlob(Image *)
MagickExport void SetBlobExempt(Image *image, const MagickBooleanType exempt)
Definition: blob.c:4054
MagickExport ChannelType SetImageChannelMask(Image *image, const ChannelType channel_mask)
Definition: image.c:2308
MagickBooleanType monochrome
Definition: image.h:423
MagickExport Quantum * QueueCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:977
MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1384
MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, const unsigned int frames, ExceptionInfo *exception)
Definition: image.c:2512
MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(Image *image, const VirtualPixelMethod virtual_pixel_method, ExceptionInfo *exception)
Definition: image.c:3273
GravityType
Definition: geometry.h:76
char magick_filename[MagickPathExtent]
Definition: image.h:322
struct _Image * previous
Definition: image.h:351
MagickBooleanType dither
Definition: image.h:270
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1061
MagickExport MagickOffsetType SeekBlob(Image *, const MagickOffsetType, const int)
MagickExport MagickBooleanType SetImageBackgroundColor(Image *image, ExceptionInfo *exception)
Definition: image.c:2224
size_t signature
Definition: image.h:357
size_t columns
Definition: image.h:175
MagickExport const MagickInfo * GetMagickInfo(const char *name, ExceptionInfo *exception)
Definition: magick.c:529
MagickExport Image * SmushImages(const Image *images, const MagickBooleanType stack, const ssize_t offset, ExceptionInfo *exception)
Definition: image.c:3460
MagickExport MagickBooleanType SetImageColor(Image *image, const PixelInfo *color, ExceptionInfo *exception)
Definition: image.c:2341
MagickExport Image * AcquireImage(const ImageInfo *image_info, ExceptionInfo *exception)
Definition: image.c:153
MagickExport MagickBooleanType OpenBlob(const ImageInfo *, Image *, const BlobMode, ExceptionInfo *)
MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
Definition: magick.c:337
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
Definition: monitor.h:26
ssize_t x
Definition: geometry.h:133
static Quantum PushColormapIndex(Image *image, const Quantum index, MagickBooleanType *range_exception)
Definition: image.c:3655
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1242
SemaphoreInfo * semaphore
Definition: image.h:343
struct _Image * next
Definition: image.h:351
size_t height
Definition: geometry.h:129
const char DefaultTileFrame[]
Definition: image.c:111
MagickExport MagickBooleanType QueryColorCompliance(const char *name, const ComplianceType compliance, PixelInfo *color, ExceptionInfo *exception)
Definition: color.c:2218
ChannelType
Definition: pixel.h:33
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
Definition: image.c:2424
MagickExport void CatchException(ExceptionInfo *exception)
Definition: exception.c:197
static void SetPixelWriteMask(const Image *magick_restrict image, const Quantum mask, Quantum *magick_restrict pixel)
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:743
ssize_t offset
Definition: image.h:209
RectangleInfo extract_info
Definition: image.h:215
MagickExport MagickBooleanType ResetImagePage(Image *image, const char *page)
Definition: image.c:2152
MagickExport MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
Definition: magick.c:494
MagickExport size_t InterpretImageFilename(const ImageInfo *image_info, Image *image, const char *format, int value, char *filename, ExceptionInfo *exception)
Definition: image.c:1618
PixelChannel
Definition: pixel.h:66
MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
Definition: blob.c:2087
MagickExport MagickBooleanType CopyImagePixels(Image *image, const Image *source_image, const RectangleInfo *geometry, const OffsetInfo *offset, ExceptionInfo *exception)
Definition: image.c:1045
char * texture
Definition: image.h:404
MagickExport MagickBooleanType SetImageExtent(Image *image, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: image.c:2466
RenderingIntent
Definition: profile.h:30
double y
Definition: image.h:102
size_t quality
Definition: image.h:166
size_t colors
Definition: image.h:175
size_t depth
Definition: pixel.h:182
TimerInfo timer
Definition: image.h:303
MagickExport MagickBooleanType SyncImagesSettings(ImageInfo *image_info, Image *images, ExceptionInfo *exception)
Definition: image.c:3767
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1412
PixelInfo border_color
Definition: image.h:415
DisposeType
Definition: layer.h:27
char filename[MagickPathExtent]
Definition: image.h:322
#define GetMagickModule()
Definition: log.h:28
PrimaryInfo green_primary
Definition: image.h:128
MagickFormatType
Definition: magick.h:28
MagickExport void GetTimerInfo(TimerInfo *time_info)
Definition: timer.c:281
size_t quality
Definition: image.h:401
MagickBooleanType affirm
Definition: image.h:375
MagickExport void ConformPixelInfo(Image *image, const PixelInfo *source, PixelInfo *destination, ExceptionInfo *exception)
Definition: pixel.c:213
#define ThrowImageException(severity, tag)
static Quantum ClampToQuantum(const MagickRealType value)
Definition: quantum.h:84
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:149
PrimaryInfo white_point
Definition: image.h:128
void * client_data
Definition: image.h:455
char * density
Definition: image.h:404
char unique[MagickPathExtent]
Definition: image.h:471
static double StringToDoubleInterval(const char *string, const double interval)
MagickExport ImageInfo * DestroyImageInfo(ImageInfo *image_info)
Definition: image.c:1247
CompressionType
Definition: compress.h:25
RenderingIntent rendering_intent
Definition: image.h:195
MagickExport Image * AppendImages(const Image *images, const MagickBooleanType stack, ExceptionInfo *exception)
Definition: image.c:442
MagickExport MagickBooleanType IsTaintImage(const Image *image)
Definition: image.c:1922
MagickExport MagickBooleanType CloneImageOptions(ImageInfo *image_info, const ImageInfo *clone_info)
Definition: option.c:1823
MagickBooleanType synchronize
Definition: image.h:449
unsigned short Quantum
Definition: magick-type.h:70
MagickExport MagickBooleanType SetImageColorspace(Image *image, const ColorspaceType colorspace, ExceptionInfo *exception)
Definition: colorspace.c:1075
char * server_name
Definition: image.h:404
MagickExport void DestroyImageArtifacts(Image *image)
Definition: artifact.c:233
MagickExport Image * GetNextImageInList(const Image *images)
Definition: list.c:752
MagickExport char * DestroyString(char *string)
Definition: string.c:811
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:454
char * geometry
Definition: image.h:204
MagickExport MagickBooleanType DeleteImageProperty(Image *image, const char *property)
Definition: property.c:279
MagickExport const char * GetImageProperty(const Image *image, const char *property, ExceptionInfo *exception)
Definition: property.c:2185
MagickExport MagickBooleanType ModifyImage(Image **image, ExceptionInfo *exception)
Definition: image.c:1975
MagickPrivate VirtualPixelMethod SetPixelCacheVirtualMethod(Image *, const VirtualPixelMethod, ExceptionInfo *)
Definition: cache.c:4902
MagickExport MagickBooleanType IsBlobExempt(const Image *image)
Definition: blob.c:2056
MagickExport MagickBooleanType StripImage(Image *image, ExceptionInfo *exception)
Definition: image.c:3611
MagickExport ImageInfo * CloneImageInfo(const ImageInfo *image_info)
Definition: image.c:947
size_t number_channels
Definition: image.h:286
#define CopyImageTag
time_t timestamp
Definition: image.h:334
MagickExport MagickStatusType ParseGeometry(const char *geometry, GeometryInfo *geometry_info)
Definition: geometry.c:836
static void SetPixelChannel(const Image *magick_restrict image, const PixelChannel channel, const Quantum quantum, Quantum *magick_restrict pixel)
MagickBooleanType dither
Definition: image.h:423
char * directory
Definition: image.h:204
ChromaticityInfo chromaticity
Definition: image.h:192
BlobInfo * blob
Definition: image.h:331
FILE * file
Definition: image.h:462
static void SetPixelAlpha(const Image *magick_restrict image, const Quantum alpha, Quantum *magick_restrict pixel)
size_t metacontent_extent
Definition: image.h:286
MagickExport void SetGeometry(const Image *image, RectangleInfo *geometry)
Definition: geometry.c:1571
ssize_t x
Definition: geometry.h:115
MagickExport const MagicInfo * GetMagicInfo(const unsigned char *magic, const size_t length, ExceptionInfo *exception)
Definition: magic.c:368
MagickExport void GetImageInfo(ImageInfo *image_info)
Definition: image.c:1340
MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image, ExceptionInfo *exception)
Definition: image.c:1781
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:997
PointInfo resolution
Definition: image.h:212
MagickExport size_t GetMagicPatternExtent(ExceptionInfo *exception)
Definition: magic.c:426
MagickExport MagickBooleanType ClipImage(Image *image, ExceptionInfo *exception)
Definition: image.c:701
ImageType
Definition: image.h:51
MagickExport void GravityAdjustGeometry(const size_t width, const size_t height, const GravityType gravity, RectangleInfo *region)
Definition: geometry.c:514
MagickExport char * CloneString(char **destination, const char *source)
Definition: string.c:271
#define Swap(x, y)
Definition: studio.h:339
MagickExport BlobInfo * ReferenceBlob(BlobInfo *)
Definition: blob.c:3889
MagickExport MagickBooleanType CloneImageArtifacts(Image *image, const Image *clone_image)
Definition: artifact.c:102
CompositeOperator compose
Definition: image.h:237
CompositeOperator
Definition: composite.h:25
ResolutionType
Definition: image.h:92
#define MagickExport
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
Definition: cache-view.c:1100
OrientationType orientation
Definition: image.h:169
MagickProgressMonitor progress_monitor
Definition: image.h:452
double fuzz
Definition: image.h:219
ssize_t y
Definition: geometry.h:133
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:112
MagickExport void DestroyBlob(Image *image)
Definition: blob.c:625
ColorspaceType colorspace
Definition: pixel.h:173
static ssize_t SmushYGap(const Image *smush_image, const Image *images, const ssize_t offset, ExceptionInfo *exception)
Definition: image.c:3389
MagickBooleanType adjoin
Definition: image.h:375
PixelMask
Definition: pixel.h:125
char * page
Definition: image.h:381
MagickBooleanType ping
Definition: image.h:436
PixelTrait
Definition: pixel.h:132
MagickExport MagickBooleanType IsSceneGeometry(const char *geometry, const MagickBooleanType pedantic)
Definition: geometry.c:634
PixelInfo transparent_color
Definition: image.h:182
#define AppendImageTag
MagickBooleanType write_mask
Definition: image.h:279
MagickExport MagickRealType GetPixelIntensity(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
Definition: pixel.c:2357
PixelInfo background_color
Definition: image.h:182
MagickExport MagickBooleanType SetImageRegionMask(Image *image, const PixelMask type, const RectangleInfo *region, ExceptionInfo *exception)
Definition: image.c:3156
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:350
MagickSizeType QuantumAny
Definition: magick-type.h:131
void * client_data
Definition: image.h:309
MagickExport void LocaleUpper(char *string)
Definition: locale.c:1570
MagickExport Image * DestroyImage(Image *image)
Definition: image.c:1176
static void SetPixelReadMask(const Image *magick_restrict image, const Quantum mask, Quantum *magick_restrict pixel)
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
Definition: image.c:802
MagickExport void * CopyMagickMemory(void *destination, const void *source, const size_t size)
Definition: memory.c:680
MagickExport ssize_t GetImageReferenceCount(Image *image)
Definition: image.c:1535
double gamma
Definition: image.h:189
PixelInfo background_color
Definition: image.h:415
ColorspaceType colorspace
Definition: image.h:160
MagickExport StringInfo * CloneStringInfo(const StringInfo *string_info)
Definition: string.c:323
MagickExport void DisassociateImageStream(Image *image)
Definition: image.c:1309
#define QuantumRange
Definition: magick-type.h:71
MagickBooleanType temporary
Definition: image.h:375
PixelChannelMap * channel_map
Definition: image.h:294
MagickBooleanType debug
Definition: image.h:337
size_t depth
Definition: image.h:387
void * profile
Definition: image.h:446
MagickPrivate Cache AcquirePixelCache(const size_t)
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:420
size_t depth
Definition: image.h:175
ExceptionType severity
Definition: exception.h:104