MagickCore  7.1.0
constitute.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % CCCC OOO N N SSSSS TTTTT IIIII TTTTT U U TTTTT EEEEE %
7 % C O O NN N SS T I T U U T E %
8 % C O O N N N ESSS T I T U U T EEE %
9 % C O O N NN SS T I T U U T E %
10 % CCCC OOO N N SSSSS T IIIII T UUU T EEEEE %
11 % %
12 % %
13 % MagickCore Methods to Consitute an Image %
14 % %
15 % Software Design %
16 % Cristy %
17 % October 1998 %
18 % %
19 % %
20 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 
39 /*
40  Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/attribute.h"
44 #include "MagickCore/blob.h"
46 #include "MagickCore/exception.h"
48 #include "MagickCore/cache.h"
49 #include "MagickCore/client.h"
52 #include "MagickCore/constitute.h"
54 #include "MagickCore/delegate.h"
55 #include "MagickCore/geometry.h"
56 #include "MagickCore/identify.h"
58 #include "MagickCore/list.h"
59 #include "MagickCore/magick.h"
60 #include "MagickCore/memory_.h"
61 #include "MagickCore/monitor.h"
63 #include "MagickCore/option.h"
64 #include "MagickCore/pixel.h"
66 #include "MagickCore/policy.h"
67 #include "MagickCore/profile.h"
69 #include "MagickCore/property.h"
70 #include "MagickCore/quantum.h"
71 #include "MagickCore/resize.h"
72 #include "MagickCore/resource_.h"
73 #include "MagickCore/semaphore.h"
74 #include "MagickCore/statistic.h"
75 #include "MagickCore/stream.h"
76 #include "MagickCore/string_.h"
78 #include "MagickCore/timer.h"
79 #include "MagickCore/token.h"
80 #include "MagickCore/transform.h"
81 #include "MagickCore/utility.h"
83 
84 /*
85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % %
87 % %
88 % %
89 % C o n s t i t u t e I m a g e %
90 % %
91 % %
92 % %
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 %
95 % ConstituteImage() returns an image from the pixel data you supply.
96 % The pixel data must be in scanline order top-to-bottom. The data can be
97 % char, short int, int, float, or double. Float and double require the
98 % pixels to be normalized [0..1], otherwise [0..QuantumRange]. For example, to
99 % create a 640x480 image from unsigned red-green-blue character data, use:
100 %
101 % image = ConstituteImage(640,480,"RGB",CharPixel,pixels,&exception);
102 %
103 % The format of the ConstituteImage method is:
104 %
105 % Image *ConstituteImage(const size_t columns,const size_t rows,
106 % const char *map,const StorageType storage,const void *pixels,
107 % ExceptionInfo *exception)
108 %
109 % A description of each parameter follows:
110 %
111 % o columns: width in pixels of the image.
112 %
113 % o rows: height in pixels of the image.
114 %
115 % o map: This string reflects the expected ordering of the pixel array.
116 % It can be any combination or order of R = red, G = green, B = blue,
117 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
118 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
119 % P = pad.
120 %
121 % o storage: Define the data type of the pixels. Float and double types are
122 % expected to be normalized [0..1] otherwise [0..QuantumRange]. Choose
123 % from these types: CharPixel, DoublePixel, FloatPixel, IntegerPixel,
124 % LongPixel, QuantumPixel, or ShortPixel.
125 %
126 % o pixels: This array of values contain the pixel components as defined by
127 % map and type. You must preallocate this array where the expected
128 % length varies depending on the values of width, height, map, and type.
129 %
130 % o exception: return any errors or warnings in this structure.
131 %
132 */
133 MagickExport Image *ConstituteImage(const size_t columns,const size_t rows,
134  const char *map,const StorageType storage,const void *pixels,
135  ExceptionInfo *exception)
136 {
137  Image
138  *image;
139 
141  status;
142 
143  ssize_t
144  i;
145 
146  size_t
147  length;
148 
149  /*
150  Allocate image structure.
151  */
152  assert(map != (const char *) NULL);
153  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",map);
154  assert(pixels != (void *) NULL);
155  assert(exception != (ExceptionInfo *) NULL);
156  assert(exception->signature == MagickCoreSignature);
157  image=AcquireImage((ImageInfo *) NULL,exception);
158  if (image == (Image *) NULL)
159  return((Image *) NULL);
160  switch (storage)
161  {
162  case CharPixel: image->depth=8*sizeof(unsigned char); break;
163  case DoublePixel: image->depth=8*sizeof(double); break;
164  case FloatPixel: image->depth=8*sizeof(float); break;
165  case LongPixel: image->depth=8*sizeof(unsigned long); break;
166  case LongLongPixel: image->depth=8*sizeof(MagickSizeType); break;
167  case ShortPixel: image->depth=8*sizeof(unsigned short); break;
168  default: break;
169  }
170  length=strlen(map);
171  for (i=0; i < (ssize_t) length; i++)
172  {
173  switch (map[i])
174  {
175  case 'a':
176  case 'A':
177  case 'O':
178  case 'o':
179  {
181  break;
182  }
183  case 'C':
184  case 'c':
185  case 'm':
186  case 'M':
187  case 'Y':
188  case 'y':
189  case 'K':
190  case 'k':
191  {
192  image->colorspace=CMYKColorspace;
193  break;
194  }
195  case 'I':
196  case 'i':
197  {
198  image->colorspace=GRAYColorspace;
199  break;
200  }
201  default:
202  {
203  if (length == 1)
204  image->colorspace=GRAYColorspace;
205  break;
206  }
207  }
208  }
209  status=SetImageExtent(image,columns,rows,exception);
210  if (status == MagickFalse)
211  return(DestroyImageList(image));
212  status=ResetImagePixels(image,exception);
213  if (status == MagickFalse)
214  return(DestroyImageList(image));
215  status=ImportImagePixels(image,0,0,columns,rows,map,storage,pixels,exception);
216  if (status == MagickFalse)
217  image=DestroyImage(image);
218  return(image);
219 }
220 
221 /*
222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223 % %
224 % %
225 % %
226 % P i n g I m a g e %
227 % %
228 % %
229 % %
230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 %
232 % PingImage() returns all the properties of an image or image sequence
233 % except for the pixels. It is much faster and consumes far less memory
234 % than ReadImage(). On failure, a NULL image is returned and exception
235 % describes the reason for the failure.
236 %
237 % The format of the PingImage method is:
238 %
239 % Image *PingImage(const ImageInfo *image_info,ExceptionInfo *exception)
240 %
241 % A description of each parameter follows:
242 %
243 % o image_info: Ping the image defined by the file or filename members of
244 % this structure.
245 %
246 % o exception: return any errors or warnings in this structure.
247 %
248 */
249 
250 #if defined(__cplusplus) || defined(c_plusplus)
251 extern "C" {
252 #endif
253 
254 static size_t PingStream(const Image *magick_unused(image),
255  const void *magick_unused(pixels),const size_t columns)
256 {
257  magick_unreferenced(image);
258  magick_unreferenced(pixels);
259  return(columns);
260 }
261 
262 #if defined(__cplusplus) || defined(c_plusplus)
263 }
264 #endif
265 
267  ExceptionInfo *exception)
268 {
269  Image
270  *image;
271 
272  ImageInfo
273  *ping_info;
274 
275  assert(image_info != (ImageInfo *) NULL);
276  assert(image_info->signature == MagickCoreSignature);
277  if (image_info->debug != MagickFalse)
279  image_info->filename);
280  assert(exception != (ExceptionInfo *) NULL);
281  ping_info=CloneImageInfo(image_info);
282  ping_info->ping=MagickTrue;
283  image=ReadStream(ping_info,&PingStream,exception);
284  if (image != (Image *) NULL)
285  {
286  ResetTimer(&image->timer);
287  if (ping_info->verbose != MagickFalse)
288  (void) IdentifyImage(image,stdout,MagickFalse,exception);
289  }
290  ping_info=DestroyImageInfo(ping_info);
291  return(image);
292 }
293 
294 /*
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296 % %
297 % %
298 % %
299 % P i n g I m a g e s %
300 % %
301 % %
302 % %
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304 %
305 % PingImages() pings one or more images and returns them as an image list.
306 %
307 % The format of the PingImage method is:
308 %
309 % Image *PingImages(ImageInfo *image_info,const char *filename,
310 % ExceptionInfo *exception)
311 %
312 % A description of each parameter follows:
313 %
314 % o image_info: the image info.
315 %
316 % o filename: the image filename.
317 %
318 % o exception: return any errors or warnings in this structure.
319 %
320 */
321 MagickExport Image *PingImages(ImageInfo *image_info,const char *filename,
322  ExceptionInfo *exception)
323 {
324  char
325  ping_filename[MagickPathExtent];
326 
327  Image
328  *image,
329  *images;
330 
331  ImageInfo
332  *read_info;
333 
334  /*
335  Ping image list from a file.
336  */
337  assert(image_info != (ImageInfo *) NULL);
338  assert(image_info->signature == MagickCoreSignature);
339  if (image_info->debug != MagickFalse)
341  image_info->filename);
342  assert(exception != (ExceptionInfo *) NULL);
343  (void) SetImageOption(image_info,"filename",filename);
344  (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
345  (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename,
346  (int) image_info->scene,ping_filename,exception);
347  if (LocaleCompare(ping_filename,image_info->filename) != 0)
348  {
350  *sans;
351 
352  ssize_t
353  extent,
354  scene;
355 
356  /*
357  Images of the form image-%d.png[1-5].
358  */
359  read_info=CloneImageInfo(image_info);
360  sans=AcquireExceptionInfo();
361  (void) SetImageInfo(read_info,0,sans);
362  sans=DestroyExceptionInfo(sans);
363  if (read_info->number_scenes == 0)
364  {
365  read_info=DestroyImageInfo(read_info);
366  return(PingImage(image_info,exception));
367  }
368  (void) CopyMagickString(ping_filename,read_info->filename,
370  images=NewImageList();
371  extent=(ssize_t) (read_info->scene+read_info->number_scenes);
372  for (scene=(ssize_t) read_info->scene; scene < (ssize_t) extent; scene++)
373  {
374  (void) InterpretImageFilename(image_info,(Image *) NULL,ping_filename,
375  (int) scene,read_info->filename,exception);
376  image=PingImage(read_info,exception);
377  if (image == (Image *) NULL)
378  continue;
379  AppendImageToList(&images,image);
380  }
381  read_info=DestroyImageInfo(read_info);
382  return(images);
383  }
384  return(PingImage(image_info,exception));
385 }
386 
387 /*
388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 % %
390 % %
391 % %
392 % R e a d I m a g e %
393 % %
394 % %
395 % %
396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 %
398 % ReadImage() reads an image or image sequence from a file or file handle.
399 % The method returns a NULL if there is a memory shortage or if the image
400 % cannot be read. On failure, a NULL image is returned and exception
401 % describes the reason for the failure.
402 %
403 % The format of the ReadImage method is:
404 %
405 % Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception)
406 %
407 % A description of each parameter follows:
408 %
409 % o image_info: Read the image defined by the file or filename members of
410 % this structure.
411 %
412 % o exception: return any errors or warnings in this structure.
413 %
414 */
415 
416 static MagickBooleanType IsCoderAuthorized(const char *coder,
417  const PolicyRights rights,ExceptionInfo *exception)
418 {
419  if (IsRightsAuthorized(CoderPolicyDomain,rights,coder) == MagickFalse)
420  {
421  errno=EPERM;
423  "NotAuthorized","`%s'",coder);
424  return(MagickFalse);
425  }
426  return(MagickTrue);
427 }
428 
430  ExceptionInfo *exception)
431 {
432  char
433  filename[MagickPathExtent],
434  magick[MagickPathExtent],
435  magick_filename[MagickPathExtent];
436 
437  const char
438  *value;
439 
440  const DelegateInfo
441  *delegate_info;
442 
443  const MagickInfo
444  *magick_info;
445 
447  *decoder;
448 
450  *sans_exception;
451 
453  geometry_info;
454 
455  Image
456  *image,
457  *next;
458 
459  ImageInfo
460  *read_info;
461 
463  status;
464 
466  flags;
467 
468  /*
469  Determine image type from filename prefix or suffix (e.g. image.jpg).
470  */
471  assert(image_info != (ImageInfo *) NULL);
472  assert(image_info->signature == MagickCoreSignature);
473  assert(image_info->filename != (char *) NULL);
474  if (image_info->debug != MagickFalse)
476  image_info->filename);
477  assert(exception != (ExceptionInfo *) NULL);
478  read_info=CloneImageInfo(image_info);
479  (void) CopyMagickString(magick_filename,read_info->filename,MagickPathExtent);
480  (void) SetImageInfo(read_info,0,exception);
481  (void) CopyMagickString(filename,read_info->filename,MagickPathExtent);
482  (void) CopyMagickString(magick,read_info->magick,MagickPathExtent);
483  /*
484  Call appropriate image reader based on image type.
485  */
486  sans_exception=AcquireExceptionInfo();
487  magick_info=GetMagickInfo(read_info->magick,sans_exception);
488  if (sans_exception->severity == PolicyError)
489  magick_info=GetMagickInfo(read_info->magick,exception);
490  sans_exception=DestroyExceptionInfo(sans_exception);
491  if (magick_info != (const MagickInfo *) NULL)
492  {
493  if (GetMagickEndianSupport(magick_info) == MagickFalse)
494  read_info->endian=UndefinedEndian;
495  else
496  if ((image_info->endian == UndefinedEndian) &&
497  (GetMagickRawSupport(magick_info) != MagickFalse))
498  {
499  unsigned long
500  lsb_first;
501 
502  lsb_first=1;
503  read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian :
504  MSBEndian;
505  }
506  }
507  if ((magick_info != (const MagickInfo *) NULL) &&
509  {
510  image=AcquireImage(read_info,exception);
511  (void) CopyMagickString(image->filename,read_info->filename,
513  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
514  if (status == MagickFalse)
515  {
516  read_info=DestroyImageInfo(read_info);
517  image=DestroyImage(image);
518  return((Image *) NULL);
519  }
520  if (IsBlobSeekable(image) == MagickFalse)
521  {
522  /*
523  Coder requires a seekable stream.
524  */
525  *read_info->filename='\0';
526  status=ImageToFile(image,read_info->filename,exception);
527  if (status == MagickFalse)
528  {
529  (void) CloseBlob(image);
530  read_info=DestroyImageInfo(read_info);
531  image=DestroyImage(image);
532  return((Image *) NULL);
533  }
534  read_info->temporary=MagickTrue;
535  }
536  (void) CloseBlob(image);
537  image=DestroyImage(image);
538  }
539  image=NewImageList();
540  decoder=GetImageDecoder(magick_info);
541  if (decoder == (DecodeImageHandler *) NULL)
542  {
543  delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception);
544  if (delegate_info == (const DelegateInfo *) NULL)
545  {
546  (void) SetImageInfo(read_info,0,exception);
547  (void) CopyMagickString(read_info->filename,filename,
549  magick_info=GetMagickInfo(read_info->magick,exception);
550  decoder=GetImageDecoder(magick_info);
551  }
552  }
553  if (decoder != (DecodeImageHandler *) NULL)
554  {
555  /*
556  Call appropriate image reader based on image type.
557  */
558  if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
559  LockSemaphoreInfo(magick_info->semaphore);
560  status=IsCoderAuthorized(read_info->magick,ReadPolicyRights,exception);
561  image=(Image *) NULL;
562  if (status != MagickFalse)
563  image=decoder(read_info,exception);
564  if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
565  UnlockSemaphoreInfo(magick_info->semaphore);
566  }
567  else
568  {
569  delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception);
570  if (delegate_info == (const DelegateInfo *) NULL)
571  {
572  (void) ThrowMagickException(exception,GetMagickModule(),
573  MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
574  read_info->magick);
575  if (read_info->temporary != MagickFalse)
576  (void) RelinquishUniqueFileResource(read_info->filename);
577  read_info=DestroyImageInfo(read_info);
578  return((Image *) NULL);
579  }
580  /*
581  Let our decoding delegate process the image.
582  */
583  image=AcquireImage(read_info,exception);
584  if (image == (Image *) NULL)
585  {
586  read_info=DestroyImageInfo(read_info);
587  return((Image *) NULL);
588  }
589  (void) CopyMagickString(image->filename,read_info->filename,
591  *read_info->filename='\0';
592  if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
593  LockSemaphoreInfo(delegate_info->semaphore);
594  status=InvokeDelegate(read_info,image,read_info->magick,(char *) NULL,
595  exception);
596  if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
597  UnlockSemaphoreInfo(delegate_info->semaphore);
598  image=DestroyImageList(image);
599  read_info->temporary=MagickTrue;
600  if (status != MagickFalse)
601  (void) SetImageInfo(read_info,0,exception);
602  magick_info=GetMagickInfo(read_info->magick,exception);
603  decoder=GetImageDecoder(magick_info);
604  if (decoder == (DecodeImageHandler *) NULL)
605  {
606  if (IsPathAccessible(read_info->filename) != MagickFalse)
607  (void) ThrowMagickException(exception,GetMagickModule(),
608  MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
609  read_info->magick);
610  else
611  ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
612  read_info->filename);
613  read_info=DestroyImageInfo(read_info);
614  return((Image *) NULL);
615  }
616  /*
617  Call appropriate image reader based on image type.
618  */
619  if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
620  LockSemaphoreInfo(magick_info->semaphore);
621  status=IsCoderAuthorized(read_info->magick,ReadPolicyRights,exception);
622  image=(Image *) NULL;
623  if (status != MagickFalse)
624  image=(decoder)(read_info,exception);
625  if (GetMagickDecoderThreadSupport(magick_info) == MagickFalse)
626  UnlockSemaphoreInfo(magick_info->semaphore);
627  }
628  if (read_info->temporary != MagickFalse)
629  {
630  (void) RelinquishUniqueFileResource(read_info->filename);
631  read_info->temporary=MagickFalse;
632  if (image != (Image *) NULL)
633  (void) CopyMagickString(image->filename,filename,MagickPathExtent);
634  }
635  if (image == (Image *) NULL)
636  {
637  read_info=DestroyImageInfo(read_info);
638  return(image);
639  }
640  if (exception->severity >= ErrorException)
642  "Coder (%s) generated an image despite an error (%d), "
643  "notify the developers",image->magick,exception->severity);
644  if (IsBlobTemporary(image) != MagickFalse)
645  (void) RelinquishUniqueFileResource(read_info->filename);
646  if ((IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse) &&
647  (GetImageListLength(image) != 1))
648  {
649  Image
650  *clones;
651 
652  clones=CloneImages(image,read_info->scenes,exception);
653  if (clones != (Image *) NULL)
654  {
655  image=DestroyImageList(image);
656  image=GetFirstImageInList(clones);
657  }
658  }
659  for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
660  {
661  char
662  magick_path[MagickPathExtent],
663  *property,
664  timestamp[MagickTimeExtent];
665 
666  const char
667  *option;
668 
669  const StringInfo
670  *profile;
671 
672  ssize_t
673  option_type;
674 
675  static const char
676  *source_date_epoch = (const char *) NULL;
677 
678  static MagickBooleanType
679  epoch_initalized = MagickFalse;
680 
681  next->taint=MagickFalse;
682  GetPathComponent(magick_filename,MagickPath,magick_path);
683  if ((*magick_path == '\0') && (*next->magick == '\0'))
684  (void) CopyMagickString(next->magick,magick,MagickPathExtent);
685  (void) CopyMagickString(next->magick_filename,magick_filename,
687  if (IsBlobTemporary(image) != MagickFalse)
688  (void) CopyMagickString(next->filename,filename,MagickPathExtent);
689  if (next->magick_columns == 0)
690  next->magick_columns=next->columns;
691  if (next->magick_rows == 0)
692  next->magick_rows=next->rows;
693  (void) GetImageProperty(next,"exif:*",exception);
694  (void) GetImageProperty(next,"icc:*",exception);
695  (void) GetImageProperty(next,"iptc:*",exception);
696  (void) GetImageProperty(next,"xmp:*",exception);
697  value=GetImageProperty(next,"exif:Orientation",exception);
698  if (value == (char *) NULL)
699  value=GetImageProperty(next,"tiff:Orientation",exception);
700  if (value != (char *) NULL)
701  {
703  (void) DeleteImageProperty(next,"tiff:Orientation");
704  (void) DeleteImageProperty(next,"exif:Orientation");
705  }
706  value=GetImageProperty(next,"exif:XResolution",exception);
707  if (value != (char *) NULL)
708  {
709  geometry_info.rho=next->resolution.x;
710  geometry_info.sigma=1.0;
711  flags=ParseGeometry(value,&geometry_info);
712  if (geometry_info.sigma != 0)
713  next->resolution.x=geometry_info.rho/geometry_info.sigma;
714  if (strchr(value,',') != (char *) NULL)
715  next->resolution.x=geometry_info.rho+geometry_info.sigma/1000.0;
716  (void) DeleteImageProperty(next,"exif:XResolution");
717  }
718  value=GetImageProperty(next,"exif:YResolution",exception);
719  if (value != (char *) NULL)
720  {
721  geometry_info.rho=next->resolution.y;
722  geometry_info.sigma=1.0;
723  flags=ParseGeometry(value,&geometry_info);
724  if (geometry_info.sigma != 0)
725  next->resolution.y=geometry_info.rho/geometry_info.sigma;
726  if (strchr(value,',') != (char *) NULL)
727  next->resolution.y=geometry_info.rho+geometry_info.sigma/1000.0;
728  (void) DeleteImageProperty(next,"exif:YResolution");
729  }
730  value=GetImageProperty(next,"exif:ResolutionUnit",exception);
731  if (value == (char *) NULL)
732  value=GetImageProperty(next,"tiff:ResolutionUnit",exception);
733  if (value != (char *) NULL)
734  {
736  value);
737  if (option_type >= 0)
738  next->units=(ResolutionType) option_type;
739  (void) DeleteImageProperty(next,"exif:ResolutionUnit");
740  (void) DeleteImageProperty(next,"tiff:ResolutionUnit");
741  }
742  if (next->page.width == 0)
743  next->page.width=next->columns;
744  if (next->page.height == 0)
745  next->page.height=next->rows;
746  option=GetImageOption(read_info,"caption");
747  if (option != (const char *) NULL)
748  {
749  property=InterpretImageProperties(read_info,next,option,exception);
750  (void) SetImageProperty(next,"caption",property,exception);
751  property=DestroyString(property);
752  }
753  option=GetImageOption(read_info,"comment");
754  if (option != (const char *) NULL)
755  {
756  property=InterpretImageProperties(read_info,next,option,exception);
757  (void) SetImageProperty(next,"comment",property,exception);
758  property=DestroyString(property);
759  }
760  option=GetImageOption(read_info,"label");
761  if (option != (const char *) NULL)
762  {
763  property=InterpretImageProperties(read_info,next,option,exception);
764  (void) SetImageProperty(next,"label",property,exception);
765  property=DestroyString(property);
766  }
767  if (LocaleCompare(next->magick,"TEXT") == 0)
768  (void) ParseAbsoluteGeometry("0x0+0+0",&next->page);
769  if ((read_info->extract != (char *) NULL) &&
770  (read_info->stream == (StreamHandler) NULL))
771  {
773  geometry;
774 
775  SetGeometry(next,&geometry);
776  flags=ParseAbsoluteGeometry(read_info->extract,&geometry);
777  if ((next->columns != geometry.width) ||
778  (next->rows != geometry.height))
779  {
780  if (((flags & XValue) != 0) || ((flags & YValue) != 0))
781  {
782  Image
783  *crop_image;
784 
785  crop_image=CropImage(next,&geometry,exception);
786  if (crop_image != (Image *) NULL)
787  ReplaceImageInList(&next,crop_image);
788  }
789  else
790  if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0))
791  {
792  Image
793  *size_image;
794 
795  flags=ParseRegionGeometry(next,read_info->extract,&geometry,
796  exception);
797  size_image=ResizeImage(next,geometry.width,geometry.height,
798  next->filter,exception);
799  if (size_image != (Image *) NULL)
800  ReplaceImageInList(&next,size_image);
801  }
802  }
803  }
804  profile=GetImageProfile(next,"icc");
805  if (profile == (const StringInfo *) NULL)
806  profile=GetImageProfile(next,"icm");
807  profile=GetImageProfile(next,"iptc");
808  if (profile == (const StringInfo *) NULL)
809  profile=GetImageProfile(next,"8bim");
810  if (epoch_initalized == MagickFalse)
811  {
812  source_date_epoch=getenv("SOURCE_DATE_EPOCH");
813  epoch_initalized=MagickTrue;
814  }
815  if (source_date_epoch == (const char *) NULL)
816  {
817  (void) FormatMagickTime((time_t) GetBlobProperties(next)->st_mtime,
818  sizeof(timestamp),timestamp);
819  (void) SetImageProperty(next,"date:modify",timestamp,exception);
820  (void) FormatMagickTime((time_t) GetBlobProperties(next)->st_ctime,
821  sizeof(timestamp),timestamp);
822  (void) SetImageProperty(next,"date:create",timestamp,exception);
823  }
824  option=GetImageOption(image_info,"delay");
825  if (option != (const char *) NULL)
826  {
827  flags=ParseGeometry(option,&geometry_info);
828  if ((flags & GreaterValue) != 0)
829  {
830  if (next->delay > (size_t) floor(geometry_info.rho+0.5))
831  next->delay=(size_t) floor(geometry_info.rho+0.5);
832  }
833  else
834  if ((flags & LessValue) != 0)
835  {
836  if (next->delay < (size_t) floor(geometry_info.rho+0.5))
838  geometry_info.sigma+0.5));
839  }
840  else
841  next->delay=(size_t) floor(geometry_info.rho+0.5);
842  if ((flags & SigmaValue) != 0)
844  geometry_info.sigma+0.5));
845  }
846  option=GetImageOption(image_info,"dispose");
847  if (option != (const char *) NULL)
848  {
850  option);
851  if (option_type >= 0)
852  next->dispose=(DisposeType) option_type;
853  }
854  if (read_info->verbose != MagickFalse)
855  (void) IdentifyImage(next,stderr,MagickFalse,exception);
856  image=next;
857  }
858  read_info=DestroyImageInfo(read_info);
859  if (GetBlobError(image) != MagickFalse)
860  ThrowReaderException(CorruptImageError,"UnableToReadImageData");
861  return(GetFirstImageInList(image));
862 }
863 
864 /*
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 % %
867 % %
868 % %
869 % R e a d I m a g e s %
870 % %
871 % %
872 % %
873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 %
875 % ReadImages() reads one or more images and returns them as an image list.
876 %
877 % The format of the ReadImage method is:
878 %
879 % Image *ReadImages(ImageInfo *image_info,const char *filename,
880 % ExceptionInfo *exception)
881 %
882 % A description of each parameter follows:
883 %
884 % o image_info: the image info.
885 %
886 % o filename: the image filename.
887 %
888 % o exception: return any errors or warnings in this structure.
889 %
890 */
891 MagickExport Image *ReadImages(ImageInfo *image_info,const char *filename,
892  ExceptionInfo *exception)
893 {
894  char
895  read_filename[MagickPathExtent];
896 
897  Image
898  *image,
899  *images;
900 
901  ImageInfo
902  *read_info;
903 
904  /*
905  Read image list from a file.
906  */
907  assert(image_info != (ImageInfo *) NULL);
908  assert(image_info->signature == MagickCoreSignature);
909  if (image_info->debug != MagickFalse)
911  image_info->filename);
912  assert(exception != (ExceptionInfo *) NULL);
913  read_info=CloneImageInfo(image_info);
914  *read_info->magick='\0';
915  (void) SetImageOption(read_info,"filename",filename);
916  (void) CopyMagickString(read_info->filename,filename,MagickPathExtent);
917  (void) InterpretImageFilename(read_info,(Image *) NULL,filename,
918  (int) read_info->scene,read_filename,exception);
919  if (LocaleCompare(read_filename,read_info->filename) != 0)
920  {
922  *sans;
923 
924  ssize_t
925  extent,
926  scene;
927 
928  /*
929  Images of the form image-%d.png[1-5].
930  */
931  sans=AcquireExceptionInfo();
932  (void) SetImageInfo(read_info,0,sans);
933  sans=DestroyExceptionInfo(sans);
934  if (read_info->number_scenes != 0)
935  {
936  (void) CopyMagickString(read_filename,read_info->filename,
938  images=NewImageList();
939  extent=(ssize_t) (read_info->scene+read_info->number_scenes);
940  scene=(ssize_t) read_info->scene;
941  for ( ; scene < (ssize_t) extent; scene++)
942  {
943  (void) InterpretImageFilename(image_info,(Image *) NULL,
944  read_filename,(int) scene,read_info->filename,exception);
945  image=ReadImage(read_info,exception);
946  if (image == (Image *) NULL)
947  continue;
948  AppendImageToList(&images,image);
949  }
950  read_info=DestroyImageInfo(read_info);
951  return(images);
952  }
953  }
954  (void) CopyMagickString(read_info->filename,filename,MagickPathExtent);
955  image=ReadImage(read_info,exception);
956  read_info=DestroyImageInfo(read_info);
957  return(image);
958 }
959 
960 /*
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % %
963 % %
964 % %
965 + R e a d I n l i n e I m a g e %
966 % %
967 % %
968 % %
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970 %
971 % ReadInlineImage() reads a Base64-encoded inline image or image sequence.
972 % The method returns a NULL if there is a memory shortage or if the image
973 % cannot be read. On failure, a NULL image is returned and exception
974 % describes the reason for the failure.
975 %
976 % The format of the ReadInlineImage method is:
977 %
978 % Image *ReadInlineImage(const ImageInfo *image_info,const char *content,
979 % ExceptionInfo *exception)
980 %
981 % A description of each parameter follows:
982 %
983 % o image_info: the image info.
984 %
985 % o content: the image encoded in Base64.
986 %
987 % o exception: return any errors or warnings in this structure.
988 %
989 */
991  const char *content,ExceptionInfo *exception)
992 {
993  Image
994  *image;
995 
996  ImageInfo
997  *read_info;
998 
999  unsigned char
1000  *blob;
1001 
1002  size_t
1003  length;
1004 
1005  const char
1006  *p;
1007 
1008  /*
1009  Skip over header (e.g. data:image/gif;base64,).
1010  */
1011  image=NewImageList();
1012  for (p=content; (*p != ',') && (*p != '\0'); p++) ;
1013  if (*p == '\0')
1014  ThrowReaderException(CorruptImageError,"CorruptImage");
1015  blob=Base64Decode(++p,&length);
1016  if (length == 0)
1017  {
1018  blob=(unsigned char *) RelinquishMagickMemory(blob);
1019  ThrowReaderException(CorruptImageError,"CorruptImage");
1020  }
1021  read_info=CloneImageInfo(image_info);
1022  (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
1023  (void *) NULL);
1024  *read_info->filename='\0';
1025  *read_info->magick='\0';
1026  for (p=content; (*p != '/') && (*p != '\0'); p++) ;
1027  if (*p != '\0')
1028  {
1029  char
1030  *q;
1031 
1032  ssize_t
1033  i;
1034 
1035  /*
1036  Extract media type.
1037  */
1038  if (LocaleNCompare(++p,"x-",2) == 0)
1039  p+=2;
1040  (void) strcpy(read_info->filename,"data.");
1041  q=read_info->filename+5;
1042  for (i=0; (*p != ';') && (*p != '\0') && (i < (MagickPathExtent-6)); i++)
1043  *q++=(*p++);
1044  *q++='\0';
1045  }
1046  image=BlobToImage(read_info,blob,length,exception);
1047  blob=(unsigned char *) RelinquishMagickMemory(blob);
1048  read_info=DestroyImageInfo(read_info);
1049  return(image);
1050 }
1051 
1052 /*
1053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054 % %
1055 % %
1056 % %
1057 % W r i t e I m a g e %
1058 % %
1059 % %
1060 % %
1061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062 %
1063 % WriteImage() writes an image or an image sequence to a file or file handle.
1064 % If writing to a file is on disk, the name is defined by the filename member
1065 % of the image structure. WriteImage() returns MagickFalse is there is a
1066 % memory shortage or if the image cannot be written. Check the exception
1067 % member of image to determine the cause for any failure.
1068 %
1069 % The format of the WriteImage method is:
1070 %
1071 % MagickBooleanType WriteImage(const ImageInfo *image_info,Image *image,
1072 % ExceptionInfo *exception)
1073 %
1074 % A description of each parameter follows:
1075 %
1076 % o image_info: the image info.
1077 %
1078 % o image: the image.
1079 %
1080 % o exception: return any errors or warnings in this structure.
1081 %
1082 */
1084  Image *image,ExceptionInfo *exception)
1085 {
1086  char
1087  filename[MagickPathExtent];
1088 
1089  const char
1090  *option;
1091 
1092  const DelegateInfo
1093  *delegate_info;
1094 
1095  const MagickInfo
1096  *magick_info;
1097 
1099  *encoder;
1100 
1102  *sans_exception;
1103 
1104  ImageInfo
1105  *write_info;
1106 
1108  status,
1109  temporary;
1110 
1111  /*
1112  Determine image type from filename prefix or suffix (e.g. image.jpg).
1113  */
1114  assert(image_info != (ImageInfo *) NULL);
1115  assert(image_info->signature == MagickCoreSignature);
1116  assert(image != (Image *) NULL);
1117  if (image->debug != MagickFalse)
1119  image_info->filename);
1120  assert(image->signature == MagickCoreSignature);
1121  assert(exception != (ExceptionInfo *) NULL);
1122  sans_exception=AcquireExceptionInfo();
1123  write_info=CloneImageInfo(image_info);
1124  (void) CopyMagickString(write_info->filename,image->filename,
1126  (void) SetImageInfo(write_info,1,sans_exception);
1127  if (*write_info->magick == '\0')
1128  (void) CopyMagickString(write_info->magick,image->magick,MagickPathExtent);
1129  (void) CopyMagickString(filename,image->filename,MagickPathExtent);
1130  (void) CopyMagickString(image->filename,write_info->filename,
1132  /*
1133  Call appropriate image writer based on image type.
1134  */
1135  magick_info=GetMagickInfo(write_info->magick,sans_exception);
1136  if (sans_exception->severity == PolicyError)
1137  magick_info=GetMagickInfo(write_info->magick,exception);
1138  sans_exception=DestroyExceptionInfo(sans_exception);
1139  if (magick_info != (const MagickInfo *) NULL)
1140  {
1141  if (GetMagickEndianSupport(magick_info) == MagickFalse)
1142  image->endian=UndefinedEndian;
1143  else
1144  if ((image_info->endian == UndefinedEndian) &&
1145  (GetMagickRawSupport(magick_info) != MagickFalse))
1146  {
1147  unsigned long
1148  lsb_first;
1149 
1150  lsb_first=1;
1151  image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
1152  }
1153  }
1154  (void) SyncImageProfiles(image);
1155  DisassociateImageStream(image);
1156  option=GetImageOption(image_info,"delegate:bimodal");
1157  if ((IsStringTrue(option) != MagickFalse) &&
1158  (write_info->page == (char *) NULL) &&
1159  (GetPreviousImageInList(image) == (Image *) NULL) &&
1160  (GetNextImageInList(image) == (Image *) NULL) &&
1161  (IsTaintImage(image) == MagickFalse) )
1162  {
1163  delegate_info=GetDelegateInfo(image->magick,write_info->magick,exception);
1164  if ((delegate_info != (const DelegateInfo *) NULL) &&
1165  (GetDelegateMode(delegate_info) == 0) &&
1167  {
1168  /*
1169  Process image with bi-modal delegate.
1170  */
1171  (void) CopyMagickString(image->filename,image->magick_filename,
1173  status=InvokeDelegate(write_info,image,image->magick,
1174  write_info->magick,exception);
1175  write_info=DestroyImageInfo(write_info);
1176  (void) CopyMagickString(image->filename,filename,MagickPathExtent);
1177  return(status);
1178  }
1179  }
1180  status=MagickFalse;
1181  temporary=MagickFalse;
1182  if ((magick_info != (const MagickInfo *) NULL) &&
1183  (GetMagickEncoderSeekableStream(magick_info) != MagickFalse))
1184  {
1185  char
1186  image_filename[MagickPathExtent];
1187 
1188  (void) CopyMagickString(image_filename,image->filename,MagickPathExtent);
1189  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1190  (void) CopyMagickString(image->filename, image_filename,MagickPathExtent);
1191  if (status != MagickFalse)
1192  {
1193  if (IsBlobSeekable(image) == MagickFalse)
1194  {
1195  /*
1196  A seekable stream is required by the encoder.
1197  */
1198  write_info->adjoin=MagickTrue;
1199  (void) CopyMagickString(write_info->filename,image->filename,
1201  (void) AcquireUniqueFilename(image->filename);
1202  temporary=MagickTrue;
1203  }
1204  (void) CloseBlob(image);
1205  }
1206  }
1207  encoder=GetImageEncoder(magick_info);
1208  if (encoder != (EncodeImageHandler *) NULL)
1209  {
1210  /*
1211  Call appropriate image writer based on image type.
1212  */
1213  if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
1214  LockSemaphoreInfo(magick_info->semaphore);
1215  status=IsCoderAuthorized(write_info->magick,WritePolicyRights,exception);
1216  if (status != MagickFalse)
1217  status=encoder(write_info,image,exception);
1218  if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
1219  UnlockSemaphoreInfo(magick_info->semaphore);
1220  }
1221  else
1222  {
1223  delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,exception);
1224  if (delegate_info != (DelegateInfo *) NULL)
1225  {
1226  /*
1227  Process the image with delegate.
1228  */
1229  *write_info->filename='\0';
1230  if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
1231  LockSemaphoreInfo(delegate_info->semaphore);
1232  status=InvokeDelegate(write_info,image,(char *) NULL,
1233  write_info->magick,exception);
1234  if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
1235  UnlockSemaphoreInfo(delegate_info->semaphore);
1236  (void) CopyMagickString(image->filename,filename,MagickPathExtent);
1237  }
1238  else
1239  {
1240  sans_exception=AcquireExceptionInfo();
1241  magick_info=GetMagickInfo(write_info->magick,sans_exception);
1242  if (sans_exception->severity == PolicyError)
1243  magick_info=GetMagickInfo(write_info->magick,exception);
1244  sans_exception=DestroyExceptionInfo(sans_exception);
1245  if ((write_info->affirm == MagickFalse) &&
1246  (magick_info == (const MagickInfo *) NULL))
1247  {
1248  (void) CopyMagickString(write_info->magick,image->magick,
1250  magick_info=GetMagickInfo(write_info->magick,exception);
1251  }
1252  encoder=GetImageEncoder(magick_info);
1253  if (encoder == (EncodeImageHandler *) NULL)
1254  {
1255  char
1256  extension[MagickPathExtent];
1257 
1258  GetPathComponent(image->filename,ExtensionPath,extension);
1259  if (*extension != '\0')
1260  magick_info=GetMagickInfo(extension,exception);
1261  else
1262  magick_info=GetMagickInfo(image->magick,exception);
1263  (void) CopyMagickString(image->filename,filename,
1265  encoder=GetImageEncoder(magick_info);
1266  }
1267  if (encoder == (EncodeImageHandler *) NULL)
1268  {
1269  magick_info=GetMagickInfo(image->magick,exception);
1270  encoder=GetImageEncoder(magick_info);
1271  if (encoder == (EncodeImageHandler *) NULL)
1272  (void) ThrowMagickException(exception,GetMagickModule(),
1273  MissingDelegateError,"NoEncodeDelegateForThisImageFormat",
1274  "`%s'",write_info->magick);
1275  }
1276  if (encoder != (EncodeImageHandler *) NULL)
1277  {
1278  /*
1279  Call appropriate image writer based on image type.
1280  */
1281  if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
1282  LockSemaphoreInfo(magick_info->semaphore);
1283  status=IsCoderAuthorized(write_info->magick,WritePolicyRights,
1284  exception);
1285  if (status != MagickFalse)
1286  status=encoder(write_info,image,exception);
1287  if (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)
1288  UnlockSemaphoreInfo(magick_info->semaphore);
1289  }
1290  }
1291  }
1292  if (temporary != MagickFalse)
1293  {
1294  /*
1295  Copy temporary image file to permanent.
1296  */
1297  status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception);
1298  if (status != MagickFalse)
1299  {
1300  (void) RelinquishUniqueFileResource(write_info->filename);
1301  status=ImageToFile(image,write_info->filename,exception);
1302  }
1303  (void) CloseBlob(image);
1304  (void) RelinquishUniqueFileResource(image->filename);
1305  (void) CopyMagickString(image->filename,write_info->filename,
1307  }
1308  if ((LocaleCompare(write_info->magick,"info") != 0) &&
1309  (write_info->verbose != MagickFalse))
1310  (void) IdentifyImage(image,stdout,MagickFalse,exception);
1311  write_info=DestroyImageInfo(write_info);
1312  if (GetBlobError(image) != MagickFalse)
1313  ThrowWriterException(FileOpenError,"UnableToWriteFile");
1314  return(status);
1315 }
1316 
1317 /*
1318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319 % %
1320 % %
1321 % %
1322 % W r i t e I m a g e s %
1323 % %
1324 % %
1325 % %
1326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327 %
1328 % WriteImages() writes an image sequence into one or more files. While
1329 % WriteImage() can write an image sequence, it is limited to writing
1330 % the sequence into a single file using a format which supports multiple
1331 % frames. WriteImages(), however, does not have this limitation, instead it
1332 % generates multiple output files if necessary (or when requested). When
1333 % ImageInfo's adjoin flag is set to MagickFalse, the file name is expected
1334 % to include a printf-style formatting string for the frame number (e.g.
1335 % "image%02d.png").
1336 %
1337 % The format of the WriteImages method is:
1338 %
1339 % MagickBooleanType WriteImages(const ImageInfo *image_info,Image *images,
1340 % const char *filename,ExceptionInfo *exception)
1341 %
1342 % A description of each parameter follows:
1343 %
1344 % o image_info: the image info.
1345 %
1346 % o images: the image list.
1347 %
1348 % o filename: the image filename.
1349 %
1350 % o exception: return any errors or warnings in this structure.
1351 %
1352 */
1354  Image *images,const char *filename,ExceptionInfo *exception)
1355 {
1356 #define WriteImageTag "Write/Image"
1357 
1359  *sans_exception;
1360 
1361  ImageInfo
1362  *write_info;
1363 
1365  proceed;
1366 
1368  progress;
1369 
1371  progress_monitor;
1372 
1374  number_images;
1375 
1377  status;
1378 
1379  Image
1380  *p;
1381 
1382  assert(image_info != (const ImageInfo *) NULL);
1383  assert(image_info->signature == MagickCoreSignature);
1384  assert(images != (Image *) NULL);
1385  assert(images->signature == MagickCoreSignature);
1386  if (images->debug != MagickFalse)
1387  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
1388  assert(exception != (ExceptionInfo *) NULL);
1389  write_info=CloneImageInfo(image_info);
1390  *write_info->magick='\0';
1391  images=GetFirstImageInList(images);
1392  if (filename != (const char *) NULL)
1393  for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1394  (void) CopyMagickString(p->filename,filename,MagickPathExtent);
1395  (void) CopyMagickString(write_info->filename,images->filename,
1397  sans_exception=AcquireExceptionInfo();
1398  (void) SetImageInfo(write_info,(unsigned int) GetImageListLength(images),
1399  sans_exception);
1400  sans_exception=DestroyExceptionInfo(sans_exception);
1401  if (*write_info->magick == '\0')
1402  (void) CopyMagickString(write_info->magick,images->magick,MagickPathExtent);
1403  p=images;
1404  for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p))
1405  {
1406  Image
1407  *next;
1408 
1409  next=GetNextImageInList(p);
1410  if (next == (Image *) NULL)
1411  break;
1412  if (p->scene >= next->scene)
1413  {
1414  ssize_t
1415  i;
1416 
1417  /*
1418  Generate consistent scene numbers.
1419  */
1420  i=(ssize_t) images->scene;
1421  for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1422  p->scene=(size_t) i++;
1423  break;
1424  }
1425  }
1426  /*
1427  Write images.
1428  */
1429  status=MagickTrue;
1430  progress_monitor=(MagickProgressMonitor) NULL;
1431  progress=0;
1432  number_images=GetImageListLength(images);
1433  for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
1434  {
1435  if (number_images != 1)
1436  progress_monitor=SetImageProgressMonitor(p,(MagickProgressMonitor) NULL,
1437  p->client_data);
1438  status&=WriteImage(write_info,p,exception);
1439  if (number_images != 1)
1440  (void) SetImageProgressMonitor(p,progress_monitor,p->client_data);
1441  if (write_info->adjoin != MagickFalse)
1442  break;
1443  if (number_images != 1)
1444  {
1445 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1446  #pragma omp atomic
1447 #endif
1448  progress++;
1449  proceed=SetImageProgress(p,WriteImageTag,progress,number_images);
1450  if (proceed == MagickFalse)
1451  break;
1452  }
1453  }
1454  write_info=DestroyImageInfo(write_info);
1455  return(status != 0 ? MagickTrue : MagickFalse);
1456 }
size_t rows
Definition: image.h:172
MagickExport Image * ResizeImage(const Image *image, const size_t columns, const size_t rows, const FilterType filter, ExceptionInfo *exception)
Definition: resize.c:3717
MagickExport Image * CloneImages(const Image *images, const char *scenes, ExceptionInfo *exception)
Definition: list.c:206
EndianType endian
Definition: image.h:404
size_t signature
Definition: image.h:488
DisposeType dispose
Definition: image.h:237
char magick[MagickPathExtent]
Definition: image.h:480
MagickExport MagickBooleanType GetDelegateThreadSupport(const DelegateInfo *delegate_info)
Definition: delegate.c:1542
char * scenes
Definition: image.h:390
MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights, const char *pattern)
Definition: policy.c:620
ssize_t ticks_per_second
Definition: image.h:245
FilterType filter
Definition: image.h:219
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:449
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:3052
OrientationType
Definition: image.h:76
MagickExport MagickBooleanType GetBlobError(const Image *image)
Definition: blob.c:1714
char * extract
Definition: image.h:390
PolicyRights
Definition: policy.h:41
size_t signature
Definition: exception.h:123
size_t number_scenes
Definition: image.h:396
MagickExport Image * PingImage(const ImageInfo *image_info, ExceptionInfo *exception)
Definition: constitute.c:266
double rho
Definition: geometry.h:107
MagickExport MagickStatusType ParseAbsoluteGeometry(const char *geometry, RectangleInfo *region_info)
Definition: geometry.c:710
EndianType endian
Definition: image.h:228
MagickBooleanType taint
Definition: image.h:169
StorageType
Definition: pixel.h:145
MagickExport MagickBooleanType IdentifyImage(Image *image, FILE *file, const MagickBooleanType verbose, ExceptionInfo *exception)
Definition: identify.c:471
MagickBooleanType debug
Definition: image.h:485
MagickExport MagickBooleanType GetMagickEncoderThreadSupport(const MagickInfo *magick_info)
Definition: magick.c:543
MagickExport const DelegateInfo * GetDelegateInfo(const char *decode, const char *encode, ExceptionInfo *exception)
Definition: delegate.c:1227
MagickExport Image * ReadInlineImage(const ImageInfo *image_info, const char *content, ExceptionInfo *exception)
Definition: constitute.c:990
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:115
static MagickBooleanType IsCoderAuthorized(const char *coder, const PolicyRights rights, ExceptionInfo *exception)
Definition: constitute.c:416
MagickExport ssize_t GetDelegateMode(const DelegateInfo *delegate_info)
Definition: delegate.c:1509
MagickExport size_t CopyMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:731
MagickBooleanType EncodeImageHandler(const ImageInfo *, Image *, ExceptionInfo *)
Definition: magick.h:62
ResolutionType units
Definition: image.h:198
size_t delay
Definition: image.h:240
#define WriteImageTag
char magick[MagickPathExtent]
Definition: image.h:319
size_t magick_rows
Definition: image.h:324
MagickExport MagickBooleanType ImageToFile(Image *image, char *filename, ExceptionInfo *exception)
Definition: blob.c:2299
MagickBooleanType verbose
Definition: image.h:445
static long StringToLong(const char *magick_restrict value)
MagickExport const char * GetImageOption(const ImageInfo *image_info, const char *option)
Definition: option.c:2382
#define MagickTimeExtent
double sigma
Definition: geometry.h:107
size_t width
Definition: geometry.h:131
MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
Definition: utility.c:111
Definition: log.h:52
ssize_t MagickOffsetType
Definition: magick-type.h:133
MagickExport MagickBooleanType SetImageOption(ImageInfo *image_info, const char *option, const char *value)
Definition: option.c:3322
Definition: image.h:151
MagickExport Image * GetPreviousImageInList(const Image *images)
Definition: list.c:818
SemaphoreInfo * semaphore
Definition: delegate.h:45
StreamHandler stream
Definition: image.h:468
MagickExport MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
Definition: magick.c:970
MagickExport Image * CropImage(const Image *image, const RectangleInfo *geometry, ExceptionInfo *exception)
Definition: transform.c:537
MagickExport const struct stat * GetBlobProperties(const Image *)
Definition: blob.c:1812
double x
Definition: geometry.h:124
MagickExport Image * PingImages(ImageInfo *image_info, const char *filename, ExceptionInfo *exception)
Definition: constitute.c:321
#define MagickCoreSignature
MagickExport MagickBooleanType ImportImagePixels(Image *image, const ssize_t x, const ssize_t y, const size_t width, const size_t height, const char *map, const StorageType type, const void *pixels, ExceptionInfo *exception)
Definition: pixel.c:4138
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport MagickBooleanType GetMagickDecoderSeekableStream(const MagickInfo *magick_info)
Definition: magick.c:413
MagickExport Image * GetFirstImageInList(const Image *images)
Definition: list.c:576
SemaphoreInfo * semaphore
Definition: magick.h:96
MagickExport Image * BlobToImage(const ImageInfo *image_info, const void *blob, const size_t length, ExceptionInfo *exception)
Definition: blob.c:422
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1221
MagickBooleanType
Definition: magick-type.h:169
MagickExport Image * NewImageList(void)
Definition: list.c:953
size_t scene
Definition: image.h:240
unsigned int MagickStatusType
Definition: magick-type.h:125
MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info, Image *image, ExceptionInfo *exception)
Definition: constitute.c:1083
MagickExport unsigned char * Base64Decode(const char *source, size_t *length)
Definition: utility.c:346
char filename[MagickPathExtent]
Definition: image.h:480
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1527
double y
Definition: geometry.h:124
MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
Definition: resource.c:1098
MagickExport MagickBooleanType CloseBlob(Image *)
MagickExport MagickBooleanType SetImageProperty(Image *image, const char *property, const char *value, ExceptionInfo *exception)
Definition: property.c:4238
MagickExport const StringInfo * GetImageProfile(const Image *image, const char *name)
Definition: profile.c:259
size_t scene
Definition: image.h:396
#define magick_unused(x)
RectangleInfo page
Definition: image.h:212
size_t magick_columns
Definition: image.h:324
size_t MagickSizeType
Definition: magick-type.h:134
#define MagickPathExtent
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1390
MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
Definition: blob.c:2967
#define ThrowFileException(exception, severity, tag, context)
PixelTrait alpha_trait
Definition: image.h:280
static size_t PingStream(const Image *magick_unused(image), const void *magick_unused(pixels), const size_t columns)
Definition: constitute.c:254
MagickExport Image * ReadImage(const ImageInfo *image_info, ExceptionInfo *exception)
Definition: constitute.c:429
MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info, const unsigned int frames, ExceptionInfo *exception)
Definition: image.c:2782
#define ThrowReaderException(severity, tag)
char magick_filename[MagickPathExtent]
Definition: image.h:319
MagickExport DecodeImageHandler * GetImageDecoder(const MagickInfo *magick_info)
Definition: magick.c:223
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:1145
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
MagickExport MagickBooleanType IsPathAccessible(const char *path)
Definition: utility.c:1492
size_t signature
Definition: image.h:354
size_t columns
Definition: image.h:172
MagickExport const MagickInfo * GetMagickInfo(const char *name, ExceptionInfo *exception)
Definition: magick.c:610
MagickExport Image * AcquireImage(const ImageInfo *image_info, ExceptionInfo *exception)
Definition: image.c:134
MagickExport MagickBooleanType OpenBlob(const ImageInfo *, Image *, const BlobMode, ExceptionInfo *)
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
Definition: monitor.h:26
size_t height
Definition: geometry.h:131
MagickExport void ResetTimer(TimerInfo *time_info)
Definition: timer.c:442
MagickExport EncodeImageHandler * GetImageEncoder(const MagickInfo *magick_info)
Definition: magick.c:253
MagickExport Image * ReadStream(const ImageInfo *image_info, StreamHandler stream, ExceptionInfo *exception)
Definition: stream.c:1040
MagickExport MagickProgressMonitor SetImageProgressMonitor(Image *image, const MagickProgressMonitor progress_monitor, void *client_data)
Definition: monitor.c:194
MagickExport Image * DestroyImageList(Image *images)
Definition: list.c:477
MagickExport MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
Definition: magick.c:575
MagickExport size_t InterpretImageFilename(const ImageInfo *image_info, Image *image, const char *format, int value, char *filename, ExceptionInfo *exception)
Definition: image.c:1645
MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
Definition: blob.c:2888
MagickExport MagickBooleanType SetImageExtent(Image *image, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: image.c:2656
MagickExport Image * ReadImages(ImageInfo *image_info, const char *filename, ExceptionInfo *exception)
Definition: constitute.c:891
TimerInfo timer
Definition: image.h:300
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1403
MagickExport MagickBooleanType GetMagickDecoderThreadSupport(const MagickInfo *magick_info)
Definition: magick.c:447
static ssize_t CastDoubleToLong(const double value)
Definition: image-private.h:53
DisposeType
Definition: layer.h:27
char filename[MagickPathExtent]
Definition: image.h:319
#define GetMagickModule()
Definition: log.h:28
MagickBooleanType affirm
Definition: image.h:384
MagickExport Image * ConstituteImage(const size_t columns, const size_t rows, const char *map, const StorageType storage, const void *pixels, ExceptionInfo *exception)
Definition: constitute.c:133
MagickExport MagickBooleanType GetMagickEncoderSeekableStream(const MagickInfo *magick_info)
Definition: magick.c:509
MagickExport char * InterpretImageProperties(ImageInfo *image_info, Image *image, const char *embed_text, ExceptionInfo *exception)
Definition: property.c:3515
MagickExport MagickBooleanType ResetImagePixels(Image *image, ExceptionInfo *exception)
Definition: image.c:2239
MagickExport ImageInfo * DestroyImageInfo(ImageInfo *image_info)
Definition: image.c:1248
MagickExport MagickBooleanType IsTaintImage(const Image *image)
Definition: image.c:1938
MagickExport void ReplaceImageInList(Image **images, Image *replace)
Definition: list.c:1181
MagickExport Image * GetNextImageInList(const Image *images)
Definition: list.c:786
MagickExport char * DestroyString(char *string)
Definition: string.c:788
MagickExport MagickBooleanType DeleteImageProperty(Image *image, const char *property)
Definition: property.c:279
MagickExport const char * GetImageProperty(const Image *image, const char *property, ExceptionInfo *exception)
Definition: property.c:2216
MagickExport ImageInfo * CloneImageInfo(const ImageInfo *image_info)
Definition: image.c:936
MagickExport MagickStatusType ParseGeometry(const char *geometry, GeometryInfo *geometry_info)
Definition: geometry.c:860
MagickExport void AppendImageToList(Image **images, const Image *append)
Definition: list.c:80
MagickExport void SetGeometry(const Image *image, RectangleInfo *geometry)
Definition: geometry.c:1696
MagickPrivate MagickBooleanType SyncImageProfiles(Image *)
Definition: profile.c:2437
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
PointInfo resolution
Definition: image.h:209
#define magick_unreferenced(x)
MagickExport MagickProgressMonitor SetImageInfoProgressMonitor(ImageInfo *image_info, const MagickProgressMonitor progress_monitor, void *client_data)
Definition: monitor.c:243
MagickExport MagickBooleanType InvokeDelegate(ImageInfo *image_info, Image *image, const char *decode, const char *encode, ExceptionInfo *exception)
Definition: delegate.c:1692
ResolutionType
Definition: image.h:89
#define MagickExport
OrientationType orientation
Definition: image.h:166
MagickBooleanType adjoin
Definition: image.h:384
char * page
Definition: image.h:390
MagickExport ssize_t FormatMagickTime(const time_t time, const size_t length, char *timestamp)
Definition: timer.c:255
MagickBooleanType ping
Definition: image.h:445
MagickExport MagickBooleanType IsSceneGeometry(const char *geometry, const MagickBooleanType pedantic)
Definition: geometry.c:653
MagickExport size_t GetImageListLength(const Image *images)
Definition: list.c:711
#define ThrowWriterException(severity, tag)
void * client_data
Definition: image.h:306
MagickExport Image * DestroyImage(Image *image)
Definition: image.c:1177
ColorspaceType colorspace
Definition: image.h:157
MagickExport MagickStatusType ParseRegionGeometry(const Image *image, const char *geometry, RectangleInfo *region_info, ExceptionInfo *exception)
Definition: geometry.c:1657
MagickExport void DisassociateImageStream(Image *image)
Definition: image.c:1310
size_t(* StreamHandler)(const Image *, const void *, const size_t)
Definition: stream.h:31
MagickExport MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
Definition: monitor.c:136
MagickBooleanType temporary
Definition: image.h:384
MagickBooleanType debug
Definition: image.h:334
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:418
MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info, Image *images, const char *filename, ExceptionInfo *exception)
Definition: constitute.c:1353
size_t depth
Definition: image.h:172
ExceptionType severity
Definition: exception.h:104
Image * DecodeImageHandler(const ImageInfo *, ExceptionInfo *)
Definition: magick.h:59