00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "magick/studio.h"
00043 #include "magick/blob.h"
00044 #include "magick/blob-private.h"
00045 #include "magick/exception.h"
00046 #include "magick/exception-private.h"
00047 #include "magick/cache.h"
00048 #include "magick/client.h"
00049 #include "magick/constitute.h"
00050 #include "magick/delegate.h"
00051 #include "magick/geometry.h"
00052 #include "magick/identify.h"
00053 #include "magick/image-private.h"
00054 #include "magick/list.h"
00055 #include "magick/magick.h"
00056 #include "magick/memory_.h"
00057 #include "magick/monitor.h"
00058 #include "magick/option.h"
00059 #include "magick/pixel.h"
00060 #include "magick/policy.h"
00061 #include "magick/profile.h"
00062 #include "magick/property.h"
00063 #include "magick/quantum.h"
00064 #include "magick/resize.h"
00065 #include "magick/resource_.h"
00066 #include "magick/semaphore.h"
00067 #include "magick/statistic.h"
00068 #include "magick/stream.h"
00069 #include "magick/string_.h"
00070 #include "magick/timer.h"
00071 #include "magick/transform.h"
00072 #include "magick/utility.h"
00073
00074 static SemaphoreInfo
00075 *constitute_semaphore = (SemaphoreInfo *) NULL;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 MagickExport Image *ConstituteImage(const unsigned long columns,
00127 const unsigned long rows,const char *map,const StorageType storage,
00128 const void *pixels,ExceptionInfo *exception)
00129 {
00130 Image
00131 *image;
00132
00133 MagickBooleanType
00134 status;
00135
00136
00137
00138
00139 assert(map != (const char *) NULL);
00140 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",map);
00141 assert(pixels != (void *) NULL);
00142 assert(exception != (ExceptionInfo *) NULL);
00143 assert(exception->signature == MagickSignature);
00144 image=AcquireImage((ImageInfo *) NULL);
00145 if (image == (Image *) NULL)
00146 return((Image *) NULL);
00147 if ((columns == 0) || (rows == 0))
00148 ThrowImageException(OptionError,"NonZeroWidthAndHeightRequired");
00149 image->columns=columns;
00150 image->rows=rows;
00151 (void) SetImageBackgroundColor(image);
00152 status=ImportImagePixels(image,0,0,columns,rows,map,storage,pixels);
00153 if (status == MagickFalse)
00154 {
00155 InheritException(exception,&image->exception);
00156 image=DestroyImage(image);
00157 }
00158 return(image);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 MagickExport void DestroyConstitute(void)
00180 {
00181 if (constitute_semaphore != (SemaphoreInfo *) NULL)
00182 DestroySemaphoreInfo(&constitute_semaphore);
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 #if defined(__cplusplus) || defined(c_plusplus)
00215 extern "C" {
00216 #endif
00217
00218 static size_t PingStream(const Image *magick_unused(image),
00219 const void *magick_unused(pixels),const size_t columns)
00220 {
00221 return(columns);
00222 }
00223
00224 #if defined(__cplusplus) || defined(c_plusplus)
00225 }
00226 #endif
00227
00228 MagickExport Image *PingImage(const ImageInfo *image_info,
00229 ExceptionInfo *exception)
00230 {
00231 Image
00232 *image;
00233
00234 ImageInfo
00235 *ping_info;
00236
00237 assert(image_info != (ImageInfo *) NULL);
00238 assert(image_info->signature == MagickSignature);
00239 if (image_info->debug != MagickFalse)
00240 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00241 image_info->filename);
00242 assert(exception != (ExceptionInfo *) NULL);
00243 ping_info=CloneImageInfo(image_info);
00244 ping_info->ping=MagickTrue;
00245 image=ReadStream(ping_info,&PingStream,exception);
00246 if (image != (Image *) NULL)
00247 {
00248 ResetTimer(&image->timer);
00249 if (ping_info->verbose != MagickFalse)
00250 (void) IdentifyImage(image,stdout,MagickFalse);
00251 }
00252 ping_info=DestroyImageInfo(ping_info);
00253 return(image);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 MagickExport Image *PingImages(const ImageInfo *image_info,
00281 ExceptionInfo *exception)
00282 {
00283 char
00284 filename[MaxTextExtent];
00285
00286 Image
00287 *image,
00288 *images;
00289
00290 ImageInfo
00291 *read_info;
00292
00293
00294
00295
00296 assert(image_info != (ImageInfo *) NULL);
00297 assert(image_info->signature == MagickSignature);
00298 if (image_info->debug != MagickFalse)
00299 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00300 image_info->filename);
00301 assert(exception != (ExceptionInfo *) NULL);
00302 (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename,
00303 (int) image_info->scene,filename);
00304 if (LocaleCompare(filename,image_info->filename) != 0)
00305 {
00306 ExceptionInfo
00307 *sans;
00308
00309 long
00310 extent,
00311 scene;
00312
00313
00314
00315
00316 read_info=CloneImageInfo(image_info);
00317 sans=AcquireExceptionInfo();
00318 (void) SetImageInfo(read_info,MagickFalse,sans);
00319 sans=DestroyExceptionInfo(sans);
00320 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
00321 images=NewImageList();
00322 extent=(long) (read_info->scene+read_info->number_scenes);
00323 for (scene=(long) read_info->scene; scene < (long) extent; scene++)
00324 {
00325 (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(int)
00326 scene,read_info->filename);
00327 image=PingImage(read_info,exception);
00328 if (image == (Image *) NULL)
00329 continue;
00330 AppendImageToList(&images,image);
00331 }
00332 read_info=DestroyImageInfo(read_info);
00333 return(images);
00334 }
00335 return(PingImage(image_info,exception));
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 MagickExport Image *ReadImage(const ImageInfo *image_info,
00367 ExceptionInfo *exception)
00368 {
00369 char
00370 filename[MaxTextExtent],
00371 magick[MaxTextExtent],
00372 magick_filename[MaxTextExtent];
00373
00374 const char
00375 *value;
00376
00377 const DelegateInfo
00378 *delegate_info;
00379
00380 const MagickInfo
00381 *magick_info;
00382
00383 ExceptionInfo
00384 *sans_exception;
00385
00386 GeometryInfo
00387 geometry_info;
00388
00389 Image
00390 *image,
00391 *next;
00392
00393 ImageInfo
00394 *read_info;
00395
00396 MagickStatusType
00397 flags,
00398 thread_support;
00399
00400 PolicyDomain
00401 domain;
00402
00403 PolicyRights
00404 rights;
00405
00406
00407
00408
00409 assert(image_info != (ImageInfo *) NULL);
00410 assert(image_info->signature == MagickSignature);
00411 assert(image_info->filename != (char *) NULL);
00412 if (image_info->debug != MagickFalse)
00413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00414 image_info->filename);
00415 assert(exception != (ExceptionInfo *) NULL);
00416 read_info=CloneImageInfo(image_info);
00417 (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent);
00418 (void) SetImageInfo(read_info,MagickFalse,exception);
00419 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
00420 (void) CopyMagickString(magick,read_info->magick,MaxTextExtent);
00421 domain=CoderPolicyDomain;
00422 rights=ReadPolicyRights;
00423 if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse)
00424 {
00425 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
00426 "NotAuthorized","`%s'",read_info->filename);
00427 return((Image *) NULL);
00428 }
00429
00430
00431
00432 sans_exception=AcquireExceptionInfo();
00433 magick_info=GetMagickInfo(read_info->magick,sans_exception);
00434 sans_exception=DestroyExceptionInfo(sans_exception);
00435 if (magick_info != (const MagickInfo *) NULL)
00436 {
00437 if (GetMagickEndianSupport(magick_info) == MagickFalse)
00438 read_info->endian=UndefinedEndian;
00439 else
00440 if ((image_info->endian == UndefinedEndian) &&
00441 (GetMagickRawSupport(magick_info) != MagickFalse))
00442 {
00443 unsigned long
00444 lsb_first;
00445
00446 lsb_first=1;
00447 read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian :
00448 MSBEndian;
00449 }
00450 }
00451 if ((magick_info != (const MagickInfo *) NULL) &&
00452 (GetMagickSeekableStream(magick_info) != MagickFalse))
00453 {
00454 MagickBooleanType
00455 status;
00456
00457 image=AcquireImage(read_info);
00458 (void) CopyMagickString(image->filename,read_info->filename,
00459 MaxTextExtent);
00460 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
00461 if (status == MagickFalse)
00462 {
00463 read_info=DestroyImageInfo(read_info);
00464 image=DestroyImage(image);
00465 return((Image *) NULL);
00466 }
00467 if (IsBlobSeekable(image) == MagickFalse)
00468 {
00469
00470
00471
00472 *read_info->filename='\0';
00473 status=ImageToFile(image,read_info->filename,exception);
00474 if (status == MagickFalse)
00475 {
00476 (void) CloseBlob(image);
00477 read_info=DestroyImageInfo(read_info);
00478 image=DestroyImage(image);
00479 return((Image *) NULL);
00480 }
00481 read_info->temporary=MagickTrue;
00482 }
00483 (void) CloseBlob(image);
00484 image=DestroyImage(image);
00485 }
00486 image=NewImageList();
00487 if ((magick_info != (const MagickInfo *) NULL) &&
00488 (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL))
00489 {
00490 thread_support=GetMagickThreadSupport(magick_info);
00491 if ((thread_support & DecoderThreadSupport) == 0)
00492 AcquireSemaphoreInfo(&constitute_semaphore);
00493 image=GetImageDecoder(magick_info)(read_info,exception);
00494 if ((thread_support & DecoderThreadSupport) == 0)
00495 RelinquishSemaphoreInfo(constitute_semaphore);
00496 }
00497 else
00498 {
00499 delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception);
00500 if (delegate_info == (const DelegateInfo *) NULL)
00501 {
00502 if (IsPathAccessible(read_info->filename) != MagickFalse)
00503 (void) ThrowMagickException(exception,GetMagickModule(),
00504 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
00505 read_info->filename);
00506 if (read_info->temporary != MagickFalse)
00507 (void) RelinquishUniqueFileResource(read_info->filename);
00508 read_info=DestroyImageInfo(read_info);
00509 return((Image *) NULL);
00510 }
00511
00512
00513
00514 image=AcquireImage(read_info);
00515 if (image == (Image *) NULL)
00516 {
00517 read_info=DestroyImageInfo(read_info);
00518 return((Image *) NULL);
00519 }
00520 (void) CopyMagickString(image->filename,read_info->filename,
00521 MaxTextExtent);
00522 *read_info->filename='\0';
00523 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
00524 AcquireSemaphoreInfo(&constitute_semaphore);
00525 (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL,
00526 exception);
00527 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
00528 RelinquishSemaphoreInfo(constitute_semaphore);
00529 image=DestroyImageList(image);
00530 read_info->temporary=MagickTrue;
00531 (void) SetImageInfo(read_info,MagickFalse,exception);
00532 magick_info=GetMagickInfo(read_info->magick,exception);
00533 if ((magick_info == (const MagickInfo *) NULL) ||
00534 (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL))
00535 {
00536 if (IsPathAccessible(read_info->filename) != MagickFalse)
00537 (void) ThrowMagickException(exception,GetMagickModule(),
00538 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
00539 read_info->filename);
00540 else
00541 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
00542 read_info->filename);
00543 read_info=DestroyImageInfo(read_info);
00544 return((Image *) NULL);
00545 }
00546 thread_support=GetMagickThreadSupport(magick_info);
00547 if ((thread_support & DecoderThreadSupport) == 0)
00548 AcquireSemaphoreInfo(&constitute_semaphore);
00549 image=(Image *) (GetImageDecoder(magick_info))(read_info,exception);
00550 if ((thread_support & DecoderThreadSupport) == 0)
00551 RelinquishSemaphoreInfo(constitute_semaphore);
00552 }
00553 if (read_info->temporary != MagickFalse)
00554 {
00555 (void) RelinquishUniqueFileResource(read_info->filename);
00556 read_info->temporary=MagickFalse;
00557 if (image != (Image *) NULL)
00558 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
00559 }
00560 if (image == (Image *) NULL)
00561 {
00562 read_info=DestroyImageInfo(read_info);
00563 return(image);
00564 }
00565 if (exception->severity >= ErrorException)
00566 (void) LogMagickEvent(ExceptionEvent,GetMagickModule(),
00567 "Coder (%s) generated an image despite an error (%d), "
00568 "notify the developers",image->magick,exception->severity);
00569 if (IsBlobTemporary(image) != MagickFalse)
00570 (void) RelinquishUniqueFileResource(read_info->filename);
00571 if ((GetNextImageInList(image) != (Image *) NULL) &&
00572 (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse))
00573 {
00574 Image
00575 *clones;
00576
00577 clones=CloneImages(image,read_info->scenes,exception);
00578 if (clones == (Image *) NULL)
00579 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
00580 "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename);
00581 else
00582 {
00583 image=DestroyImageList(image);
00584 image=GetFirstImageInList(clones);
00585 }
00586 }
00587 if (GetBlobError(image) != MagickFalse)
00588 {
00589 ThrowFileException(exception,FileOpenError,
00590 "AnErrorHasOccurredReadingFromFile",read_info->filename);
00591 image=DestroyImageList(image);
00592 read_info=DestroyImageInfo(read_info);
00593 return((Image *) NULL);
00594 }
00595 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
00596 {
00597 char
00598 timestamp[MaxTextExtent];
00599
00600 const StringInfo
00601 *profile;
00602
00603 next->taint=MagickFalse;
00604 if (next->magick_columns == 0)
00605 next->magick_columns=next->columns;
00606 if (next->magick_rows == 0)
00607 next->magick_rows=next->rows;
00608 if ((LocaleCompare(magick,"HTTP") != 0) &&
00609 (LocaleCompare(magick,"FTP") != 0))
00610 (void) CopyMagickString(next->magick,magick,MaxTextExtent);
00611 (void) CopyMagickString(next->magick_filename,magick_filename,
00612 MaxTextExtent);
00613 if (IsBlobTemporary(image) != MagickFalse)
00614 (void) CopyMagickString(next->filename,filename,MaxTextExtent);
00615 value=GetImageProperty(next,"tiff:Orientation");
00616 if (value == (char *) NULL)
00617 value=GetImageProperty(next,"exif:Orientation");
00618 if (value != (char *) NULL)
00619 {
00620 next->orientation=(OrientationType) atol(value);
00621 (void) DeleteImageProperty(next,"tiff:Orientation");
00622 (void) DeleteImageProperty(next,"exif:Orientation");
00623 }
00624 value=GetImageProperty(next,"tiff:XResolution");
00625 if (value == (char *) NULL)
00626 value=GetImageProperty(next,"exif:XResolution");
00627 if (value != (char *) NULL)
00628 {
00629 geometry_info.rho=next->x_resolution;
00630 geometry_info.sigma=1.0;
00631 flags=ParseGeometry(value,&geometry_info);
00632 if (geometry_info.sigma != 0)
00633 next->x_resolution=geometry_info.rho/geometry_info.sigma;
00634 (void) DeleteImageProperty(next,"exif:XResolution");
00635 (void) DeleteImageProperty(next,"tiff:XResolution");
00636 }
00637 value=GetImageProperty(next,"tiff:YResolution");
00638 if (value == (char *) NULL)
00639 value=GetImageProperty(next,"exif:YResolution");
00640 if (value != (char *) NULL)
00641 {
00642 geometry_info.rho=next->y_resolution;
00643 geometry_info.sigma=1.0;
00644 flags=ParseGeometry(value,&geometry_info);
00645 if (geometry_info.sigma != 0)
00646 next->y_resolution=geometry_info.rho/geometry_info.sigma;
00647 (void) DeleteImageProperty(next,"exif:YResolution");
00648 (void) DeleteImageProperty(next,"tiff:YResolution");
00649 }
00650 value=GetImageProperty(next,"tiff:ResolutionUnit");
00651 if (value == (char *) NULL)
00652 value=GetImageProperty(next,"exif:ResolutionUnit");
00653 if (value != (char *) NULL)
00654 {
00655 next->units=(ResolutionType) (atoi(value)-1);
00656 (void) DeleteImageProperty(next,"exif:ResolutionUnit");
00657 (void) DeleteImageProperty(next,"tiff:ResolutionUnit");
00658 }
00659 if (next->page.width == 0)
00660 next->page.width=next->columns;
00661 if (next->page.height == 0)
00662 next->page.height=next->rows;
00663 if (*read_info->filename != '\0')
00664 {
00665 char
00666 *property;
00667
00668 const char
00669 *option;
00670
00671 option=GetImageOption(read_info,"caption");
00672 if (option != (const char *) NULL)
00673 {
00674 property=InterpretImageProperties(read_info,next,option);
00675 (void) SetImageProperty(next,"caption",property);
00676 property=DestroyString(property);
00677 }
00678 option=GetImageOption(read_info,"comment");
00679 if (option != (const char *) NULL)
00680 {
00681 property=InterpretImageProperties(read_info,next,option);
00682 (void) SetImageProperty(next,"comment",property);
00683 property=DestroyString(property);
00684 }
00685 option=GetImageOption(read_info,"label");
00686 if (option != (const char *) NULL)
00687 {
00688 property=InterpretImageProperties(read_info,next,option);
00689 (void) SetImageProperty(next,"label",property);
00690 property=DestroyString(property);
00691 }
00692 }
00693 if (LocaleCompare(next->magick,"TEXT") == 0)
00694 (void) ParseAbsoluteGeometry("0x0+0+0",&next->page);
00695 if ((read_info->extract != (char *) NULL) &&
00696 (read_info->stream == (StreamHandler) NULL))
00697 {
00698 RectangleInfo
00699 geometry;
00700
00701 flags=ParseAbsoluteGeometry(read_info->extract,&geometry);
00702 if ((next->columns != geometry.width) ||
00703 (next->rows != geometry.height))
00704 {
00705 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
00706 {
00707 Image
00708 *crop_image;
00709
00710 crop_image=CropImage(next,&geometry,exception);
00711 if (crop_image != (Image *) NULL)
00712 ReplaceImageInList(&next,crop_image);
00713 }
00714 else
00715 if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0))
00716 {
00717 Image
00718 *size_image;
00719
00720 flags=ParseRegionGeometry(next,read_info->extract,&geometry,
00721 exception);
00722 size_image=ResizeImage(next,geometry.width,geometry.height,
00723 next->filter,next->blur,exception);
00724 if (size_image != (Image *) NULL)
00725 ReplaceImageInList(&next,size_image);
00726 }
00727 }
00728 }
00729 profile=GetImageProfile(next,"icc");
00730 if (profile == (const StringInfo *) NULL)
00731 profile=GetImageProfile(next,"icm");
00732 if (profile != (const StringInfo *) NULL)
00733 {
00734 next->color_profile.length=GetStringInfoLength(profile);
00735 next->color_profile.info=GetStringInfoDatum(profile);
00736 }
00737 profile=GetImageProfile(next,"iptc");
00738 if (profile == (const StringInfo *) NULL)
00739 profile=GetImageProfile(next,"8bim");
00740 if (profile != (const StringInfo *) NULL)
00741 {
00742 next->iptc_profile.length=GetStringInfoLength(profile);
00743 next->iptc_profile.info=GetStringInfoDatum(profile);
00744 }
00745 (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent,
00746 timestamp);
00747 (void) SetImageProperty(next,"modify-date",timestamp);
00748 (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent,
00749 timestamp);
00750 (void) SetImageProperty(next,"create-date",timestamp);
00751 if (read_info->verbose != MagickFalse)
00752 (void) IdentifyImage(next,stdout,MagickFalse);
00753 image=next;
00754 }
00755 read_info=DestroyImageInfo(read_info);
00756 return(GetFirstImageInList(image));
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 MagickExport Image *ReadImages(const ImageInfo *image_info,
00784 ExceptionInfo *exception)
00785 {
00786 char
00787 filename[MaxTextExtent];
00788
00789 Image
00790 *image,
00791 *images;
00792
00793 ImageInfo
00794 *read_info;
00795
00796
00797
00798
00799 assert(image_info != (ImageInfo *) NULL);
00800 assert(image_info->signature == MagickSignature);
00801 if (image_info->debug != MagickFalse)
00802 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00803 image_info->filename);
00804 assert(exception != (ExceptionInfo *) NULL);
00805 (void) InterpretImageFilename(image_info,(Image *) NULL,image_info->filename,
00806 (int) image_info->scene,filename);
00807 if (LocaleCompare(filename,image_info->filename) != 0)
00808 {
00809 ExceptionInfo
00810 *sans;
00811
00812 long
00813 extent,
00814 scene;
00815
00816
00817
00818
00819 read_info=CloneImageInfo(image_info);
00820 sans=AcquireExceptionInfo();
00821 (void) SetImageInfo(read_info,MagickFalse,sans);
00822 sans=DestroyExceptionInfo(sans);
00823 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
00824 images=NewImageList();
00825 extent=(long) (read_info->scene+read_info->number_scenes);
00826 for (scene=(long) read_info->scene; scene < (long) extent; scene++)
00827 {
00828 (void) InterpretImageFilename(image_info,(Image *) NULL,filename,(int)
00829 scene,read_info->filename);
00830 image=ReadImage(read_info,exception);
00831 if (image == (Image *) NULL)
00832 continue;
00833 AppendImageToList(&images,image);
00834 }
00835 read_info=DestroyImageInfo(read_info);
00836 return(images);
00837 }
00838 return(ReadImage(image_info,exception));
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 MagickExport Image *ReadInlineImage(const ImageInfo *image_info,
00872 const char *content,ExceptionInfo *exception)
00873 {
00874 Image
00875 *image;
00876
00877 ImageInfo
00878 *read_info;
00879
00880 unsigned char
00881 *blob;
00882
00883 size_t
00884 length;
00885
00886 register const char
00887 *p;
00888
00889 image=NewImageList();
00890 for (p=content; (*p != ',') && (*p != '\0'); p++) ;
00891 if (*p == '\0')
00892 ThrowReaderException(CorruptImageError,"CorruptImage");
00893 p++;
00894 length=0;
00895 blob=Base64Decode(p,&length);
00896 if (length == 0)
00897 ThrowReaderException(CorruptImageError,"CorruptImage");
00898 read_info=CloneImageInfo(image_info);
00899 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
00900 (void *) NULL);
00901 image=BlobToImage(read_info,blob,length,exception);
00902 blob=(unsigned char *) RelinquishMagickMemory(blob);
00903 read_info=DestroyImageInfo(read_info);
00904 return(image);
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info,
00936 Image *image)
00937 {
00938 char
00939 filename[MaxTextExtent];
00940
00941 const DelegateInfo
00942 *delegate_info;
00943
00944 const MagickInfo
00945 *magick_info;
00946
00947 ExceptionInfo
00948 *sans_exception;
00949
00950 ImageInfo
00951 *write_info;
00952
00953 MagickBooleanType
00954 status,
00955 temporary;
00956
00957 MagickStatusType
00958 thread_support;
00959
00960 PolicyDomain
00961 domain;
00962
00963 PolicyRights
00964 rights;
00965
00966
00967
00968
00969 assert(image_info != (ImageInfo *) NULL);
00970 assert(image_info->signature == MagickSignature);
00971 if (image->debug != MagickFalse)
00972 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00973 image_info->filename);
00974 assert(image != (Image *) NULL);
00975 assert(image->signature == MagickSignature);
00976 sans_exception=AcquireExceptionInfo();
00977 write_info=CloneImageInfo(image_info);
00978 (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent);
00979 if (*write_info->magick == '\0')
00980 (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent);
00981 (void) SetImageInfo(write_info,MagickTrue,sans_exception);
00982 if (LocaleCompare(write_info->magick,"clipmask") == 0)
00983 {
00984 if (image->clip_mask == (Image *) NULL)
00985 {
00986 (void) ThrowMagickException(&image->exception,GetMagickModule(),
00987 OptionError,"NoClipPathDefined","`%s'",image->filename);
00988 return(MagickFalse);
00989 }
00990 image=image->clip_mask;
00991 (void) SetImageInfo(write_info,MagickTrue,sans_exception);
00992 }
00993 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
00994 (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent);
00995 domain=CoderPolicyDomain;
00996 rights=WritePolicyRights;
00997 if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse)
00998 {
00999 sans_exception=DestroyExceptionInfo(sans_exception);
01000 ThrowBinaryException(PolicyError,"NotAuthorized",filename);
01001 }
01002 magick_info=GetMagickInfo(write_info->magick,sans_exception);
01003 sans_exception=DestroyExceptionInfo(sans_exception);
01004 if (magick_info != (const MagickInfo *) NULL)
01005 {
01006 if (GetMagickEndianSupport(magick_info) == MagickFalse)
01007 image->endian=UndefinedEndian;
01008 else
01009 if ((image_info->endian == UndefinedEndian) &&
01010 (GetMagickRawSupport(magick_info) != MagickFalse))
01011 {
01012 unsigned long
01013 lsb_first;
01014
01015 lsb_first=1;
01016 image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
01017 }
01018 }
01019 (void) SyncImageProfiles(image);
01020 if ((write_info->page == (char *) NULL) &&
01021 (GetPreviousImageInList(image) == (Image *) NULL) &&
01022 (GetNextImageInList(image) == (Image *) NULL) &&
01023 (IsTaintImage(image) == MagickFalse))
01024 {
01025 delegate_info=GetDelegateInfo(image->magick,write_info->magick,
01026 &image->exception);
01027 if ((delegate_info != (const DelegateInfo *) NULL) &&
01028 (GetDelegateMode(delegate_info) == 0) &&
01029 (IsPathAccessible(image->magick_filename) != MagickFalse))
01030 {
01031
01032
01033
01034 (void) CopyMagickString(image->filename,image->magick_filename,
01035 MaxTextExtent);
01036 status=InvokeDelegate(write_info,image,image->magick,
01037 write_info->magick,&image->exception);
01038 write_info=DestroyImageInfo(write_info);
01039 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
01040 return(status);
01041 }
01042 }
01043 status=MagickFalse;
01044 temporary=MagickFalse;
01045 if ((magick_info != (const MagickInfo *) NULL) &&
01046 (GetMagickSeekableStream(magick_info) != MagickFalse))
01047 {
01048 char
01049 filename[MaxTextExtent];
01050
01051 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
01052 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
01053 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
01054 if (status != MagickFalse)
01055 {
01056 if (IsBlobSeekable(image) == MagickFalse)
01057 {
01058
01059
01060
01061 (void) CopyMagickString(write_info->filename,image->filename,
01062 MaxTextExtent);
01063 (void) AcquireUniqueFilename(image->filename);
01064 temporary=MagickTrue;
01065 }
01066 (void) CloseBlob(image);
01067 }
01068 }
01069 if ((magick_info != (const MagickInfo *) NULL) &&
01070 (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL))
01071 {
01072
01073
01074
01075 thread_support=GetMagickThreadSupport(magick_info);
01076 if ((thread_support & EncoderThreadSupport) == 0)
01077 AcquireSemaphoreInfo(&constitute_semaphore);
01078 status=GetImageEncoder(magick_info)(write_info,image);
01079 if ((thread_support & EncoderThreadSupport) == 0)
01080 RelinquishSemaphoreInfo(constitute_semaphore);
01081 }
01082 else
01083 {
01084 delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,
01085 &image->exception);
01086 if (delegate_info != (DelegateInfo *) NULL)
01087 {
01088
01089
01090
01091 *write_info->filename='\0';
01092 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
01093 AcquireSemaphoreInfo(&constitute_semaphore);
01094 status=InvokeDelegate(write_info,image,(char *) NULL,
01095 write_info->magick,&image->exception);
01096 if (GetDelegateThreadSupport(delegate_info) == MagickFalse)
01097 RelinquishSemaphoreInfo(constitute_semaphore);
01098 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
01099 }
01100 else
01101 {
01102 sans_exception=AcquireExceptionInfo();
01103 magick_info=GetMagickInfo(write_info->magick,sans_exception);
01104 sans_exception=DestroyExceptionInfo(sans_exception);
01105 if ((write_info->affirm == MagickFalse) &&
01106 (magick_info == (const MagickInfo *) NULL))
01107 {
01108 (void) CopyMagickString(write_info->magick,image->magick,
01109 MaxTextExtent);
01110 magick_info=GetMagickInfo(write_info->magick,&image->exception);
01111 }
01112 if ((magick_info == (const MagickInfo *) NULL) ||
01113 (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL))
01114 (void) ThrowMagickException(&image->exception,GetMagickModule(),
01115 MissingDelegateError,"NoEncodeDelegateForThisImageFormat","`%s'",
01116 image->filename);
01117 else
01118 {
01119
01120
01121
01122 thread_support=GetMagickThreadSupport(magick_info);
01123 if ((thread_support & EncoderThreadSupport) == 0)
01124 AcquireSemaphoreInfo(&constitute_semaphore);
01125 status=GetImageEncoder(magick_info)(write_info,image);
01126 if ((thread_support & EncoderThreadSupport) == 0)
01127 RelinquishSemaphoreInfo(constitute_semaphore);
01128 }
01129 }
01130 }
01131 if (GetBlobError(image) != MagickFalse)
01132 ThrowFileException(&image->exception,FileOpenError,
01133 "AnErrorHasOccurredWritingToFile",image->filename);
01134 if (temporary == MagickTrue)
01135 {
01136
01137
01138
01139 status=OpenBlob(write_info,image,ReadBinaryBlobMode,&image->exception);
01140 if (status != MagickFalse)
01141 status=ImageToFile(image,write_info->filename,&image->exception);
01142 (void) RelinquishUniqueFileResource(image->filename);
01143 (void) CopyMagickString(image->filename,write_info->filename,
01144 MaxTextExtent);
01145 (void) CloseBlob(image);
01146 }
01147 if ((LocaleCompare(write_info->magick,"info") != 0) &&
01148 (write_info->verbose != MagickFalse))
01149 (void) IdentifyImage(image,stdout,MagickFalse);
01150 write_info=DestroyImageInfo(write_info);
01151 return(status);
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info,
01184 Image *images,const char *filename,ExceptionInfo *exception)
01185 {
01186 BlobInfo
01187 *blob;
01188
01189 ExceptionInfo
01190 *sans_exception;
01191
01192 ImageInfo
01193 *write_info;
01194
01195 MagickStatusType
01196 status;
01197
01198 register Image
01199 *p;
01200
01201 assert(image_info != (const ImageInfo *) NULL);
01202 assert(image_info->signature == MagickSignature);
01203 assert(images != (Image *) NULL);
01204 assert(images->signature == MagickSignature);
01205 if (images->debug != MagickFalse)
01206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
01207 assert(exception != (ExceptionInfo *) NULL);
01208 write_info=CloneImageInfo(image_info);
01209 images=GetFirstImageInList(images);
01210 blob=CloneBlobInfo(images->blob);
01211 DestroyBlob(images);
01212 images->blob=blob;
01213 if (filename != (const char *) NULL)
01214 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
01215 (void) CopyMagickString(p->filename,filename,MaxTextExtent);
01216 (void) CopyMagickString(write_info->filename,images->filename,MaxTextExtent);
01217 if (*write_info->magick == '\0')
01218 (void) CopyMagickString(write_info->magick,images->magick,MaxTextExtent);
01219 sans_exception=AcquireExceptionInfo();
01220 (void) SetImageInfo(write_info,MagickTrue,sans_exception);
01221 sans_exception=DestroyExceptionInfo(sans_exception);
01222 p=images;
01223 for ( ; GetNextImageInList(p) != (Image *) NULL; p=GetNextImageInList(p))
01224 if (p->scene >= GetNextImageInList(p)->scene)
01225 {
01226 register long
01227 i;
01228
01229
01230
01231
01232 i=(long) images->scene;
01233 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
01234 p->scene=(unsigned long) i++;
01235 break;
01236 }
01237
01238
01239
01240 status=MagickTrue;
01241 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
01242 {
01243 status&=WriteImage(write_info,p);
01244 GetImageException(p,exception);
01245 if (write_info->adjoin != MagickFalse)
01246 break;
01247 }
01248 write_info=DestroyImageInfo(write_info);
01249 return(status != 0 ? MagickTrue : MagickFalse);
01250 }