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