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