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
00043 #include "magick/studio.h"
00044 #include "magick/animate.h"
00045 #include "magick/artifact.h"
00046 #include "magick/blob.h"
00047 #include "magick/blob-private.h"
00048 #include "magick/cache.h"
00049 #include "magick/cache-private.h"
00050 #include "magick/cache-view.h"
00051 #include "magick/client.h"
00052 #include "magick/color.h"
00053 #include "magick/color-private.h"
00054 #include "magick/colorspace.h"
00055 #include "magick/colorspace-private.h"
00056 #include "magick/composite.h"
00057 #include "magick/composite-private.h"
00058 #include "magick/compress.h"
00059 #include "magick/constitute.h"
00060 #include "magick/deprecate.h"
00061 #include "magick/display.h"
00062 #include "magick/draw.h"
00063 #include "magick/enhance.h"
00064 #include "magick/exception.h"
00065 #include "magick/exception-private.h"
00066 #include "magick/gem.h"
00067 #include "magick/geometry.h"
00068 #include "magick/list.h"
00069 #include "magick/image-private.h"
00070 #include "magick/magic.h"
00071 #include "magick/magick.h"
00072 #include "magick/memory_.h"
00073 #include "magick/module.h"
00074 #include "magick/monitor.h"
00075 #include "magick/monitor-private.h"
00076 #include "magick/option.h"
00077 #include "magick/paint.h"
00078 #include "magick/pixel-private.h"
00079 #include "magick/profile.h"
00080 #include "magick/property.h"
00081 #include "magick/quantize.h"
00082 #include "magick/random_.h"
00083 #include "magick/segment.h"
00084 #include "magick/semaphore.h"
00085 #include "magick/signature-private.h"
00086 #include "magick/statistic.h"
00087 #include "magick/string_.h"
00088 #include "magick/thread-private.h"
00089 #include "magick/threshold.h"
00090 #include "magick/timer.h"
00091 #include "magick/utility.h"
00092 #include "magick/version.h"
00093 #include "magick/xwindow-private.h"
00094
00095
00096
00097
00098 const char
00099 *BackgroundColor = "#ffffff",
00100 *BorderColor = "#dfdfdf",
00101 *DefaultTileFrame = "15x15+3+3",
00102 *DefaultTileGeometry = "120x120+4+3>",
00103 *DefaultTileLabel = "%f\n%wx%h\n%b",
00104 *ForegroundColor = "#000",
00105 *LoadImageTag = "Load/Image",
00106 *LoadImagesTag = "Load/Images",
00107 *MatteColor = "#bdbdbd",
00108 *PSDensityGeometry = "72.0x72.0",
00109 *PSPageGeometry = "612x792",
00110 *SaveImageTag = "Save/Image",
00111 *SaveImagesTag = "Save/Images",
00112 *TransparentColor = "#00000000";
00113
00114 const double
00115 DefaultResolution = 72.0;
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 MagickExport Image *AcquireImage(const ImageInfo *image_info)
00143 {
00144 Image
00145 *image;
00146
00147 MagickStatusType
00148 flags;
00149
00150
00151
00152
00153 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00154 image=(Image *) AcquireMagickMemory(sizeof(*image));
00155 if (image == (Image *) NULL)
00156 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00157 (void) ResetMagickMemory(image,0,sizeof(*image));
00158
00159
00160
00161 (void) CopyMagickString(image->magick,"MIFF",MaxTextExtent);
00162 image->storage_class=DirectClass;
00163 image->depth=MAGICKCORE_QUANTUM_DEPTH;
00164 image->colorspace=RGBColorspace;
00165 image->interlace=NoInterlace;
00166 image->ticks_per_second=UndefinedTicksPerSecond;
00167 image->compose=OverCompositeOp;
00168 image->blur=1.0;
00169 GetExceptionInfo(&image->exception);
00170 (void) QueryColorDatabase(BackgroundColor,&image->background_color,
00171 &image->exception);
00172 (void) QueryColorDatabase(BorderColor,&image->border_color,&image->exception);
00173 (void) QueryColorDatabase(MatteColor,&image->matte_color,&image->exception);
00174 (void) QueryColorDatabase(TransparentColor,&image->transparent_color,
00175 &image->exception);
00176 image->x_resolution=DefaultResolution;
00177 image->y_resolution=DefaultResolution;
00178 image->units=PixelsPerInchResolution;
00179 GetTimerInfo(&image->timer);
00180 image->cache=AcquirePixelCacheInfo(0);
00181 image->blob=CloneBlobInfo((BlobInfo *) NULL);
00182 image->debug=IsEventLogging();
00183 image->reference_count=1;
00184 image->semaphore=AllocateSemaphoreInfo();
00185 image->signature=MagickSignature;
00186 if (image_info == (ImageInfo *) NULL)
00187 return(image);
00188
00189
00190
00191 (void) SyncImageSettings(image_info,image);
00192 SetBlobExempt(image,image_info->file != (FILE *) NULL ? MagickTrue :
00193 MagickFalse);
00194 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
00195 (void) CopyMagickString(image->magick_filename,image_info->filename,
00196 MaxTextExtent);
00197 (void) CopyMagickString(image->magick,image_info->magick,MaxTextExtent);
00198 if (image_info->size != (char *) NULL)
00199 {
00200 (void) ParseAbsoluteGeometry(image_info->size,&image->extract_info);
00201 image->columns=image->extract_info.width;
00202 image->rows=image->extract_info.height;
00203 image->offset=image->extract_info.x;
00204 image->extract_info.x=0;
00205 image->extract_info.y=0;
00206 }
00207 if (image_info->extract != (char *) NULL)
00208 {
00209 RectangleInfo
00210 geometry;
00211
00212 flags=ParseAbsoluteGeometry(image_info->extract,&geometry);
00213 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
00214 {
00215 image->extract_info=geometry;
00216 Swap(image->columns,image->extract_info.width);
00217 Swap(image->rows,image->extract_info.height);
00218 }
00219 }
00220 image->compression=image_info->compression;
00221 image->quality=image_info->quality;
00222 image->endian=image_info->endian;
00223 image->interlace=image_info->interlace;
00224 image->units=image_info->units;
00225 if (image_info->density != (char *) NULL)
00226 {
00227 GeometryInfo
00228 geometry_info;
00229
00230 flags=ParseGeometry(image_info->density,&geometry_info);
00231 image->x_resolution=geometry_info.rho;
00232 image->y_resolution=geometry_info.sigma;
00233 if ((flags & SigmaValue) == 0)
00234 image->y_resolution=image->x_resolution;
00235 }
00236 if (image_info->page != (char *) NULL)
00237 {
00238 char
00239 *geometry;
00240
00241 image->page=image->extract_info;
00242 geometry=GetPageGeometry(image_info->page);
00243 (void) ParseAbsoluteGeometry(geometry,&image->page);
00244 geometry=DestroyString(geometry);
00245 }
00246 if (image_info->depth != 0)
00247 image->depth=image_info->depth;
00248 image->dither=image_info->dither;
00249 image->background_color=image_info->background_color;
00250 image->border_color=image_info->border_color;
00251 image->matte_color=image_info->matte_color;
00252 image->transparent_color=image_info->transparent_color;
00253 image->progress_monitor=image_info->progress_monitor;
00254 image->client_data=image_info->client_data;
00255 if (image_info->cache != (void *) NULL)
00256 ClonePixelCacheMethods(image->cache,image_info->cache);
00257 (void) SetImageVirtualPixelMethod(image,image_info->virtual_pixel_method);
00258 return(image);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 static inline unsigned long MagickMax(const unsigned long x,
00291 const unsigned long y)
00292 {
00293 if (x > y)
00294 return(x);
00295 return(y);
00296 }
00297
00298 static inline unsigned long MagickMin(const unsigned long x,
00299 const unsigned long y)
00300 {
00301 if (x < y)
00302 return(x);
00303 return(y);
00304 }
00305
00306 MagickExport MagickBooleanType AcquireImageColormap(Image *image,
00307 const unsigned long colors)
00308 {
00309 register long
00310 i;
00311
00312 size_t
00313 length;
00314
00315
00316
00317
00318 assert(image != (Image *) NULL);
00319 assert(image->signature == MagickSignature);
00320 if (image->debug != MagickFalse)
00321 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00322 image->colors=MagickMin(colors,MaxColormapSize);
00323 length=(size_t) colors;
00324 if (image->colormap == (PixelPacket *) NULL)
00325 image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
00326 sizeof(*image->colormap));
00327 else
00328 image->colormap=(PixelPacket *) ResizeQuantumMemory(image->colormap,length,
00329 sizeof(*image->colormap));
00330 if (image->colormap == (PixelPacket *) NULL)
00331 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
00332 image->filename);
00333 for (i=0; i < (long) image->colors; i++)
00334 {
00335 unsigned long
00336 pixel;
00337
00338 pixel=(unsigned long) (i*(QuantumRange/MagickMax(colors-1,1)));
00339 image->colormap[i].red=(Quantum) pixel;
00340 image->colormap[i].green=(Quantum) pixel;
00341 image->colormap[i].blue=(Quantum) pixel;
00342 image->colormap[i].opacity=OpaqueOpacity;
00343 }
00344 return(SetImageStorageClass(image,PseudoClass));
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 MagickExport ImageInfo *AcquireImageInfo(void)
00366 {
00367 ImageInfo
00368 *image_info;
00369
00370 image_info=(ImageInfo *) AcquireMagickMemory(sizeof(*image_info));
00371 if (image_info == (ImageInfo *) NULL)
00372 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00373 GetImageInfo(image_info);
00374 return(image_info);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 MagickExport void AcquireNextImage(const ImageInfo *image_info,Image *image)
00406 {
00407
00408
00409
00410 assert(image != (Image *) NULL);
00411 assert(image->signature == MagickSignature);
00412 if (image->debug != MagickFalse)
00413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00414 image->next=AcquireImage(image_info);
00415 if (GetNextImageInList(image) == (Image *) NULL)
00416 return;
00417 (void) CopyMagickString(GetNextImageInList(image)->filename,image->filename,
00418 MaxTextExtent);
00419 if (image_info != (ImageInfo *) NULL)
00420 (void) CopyMagickString(GetNextImageInList(image)->filename,
00421 image_info->filename,MaxTextExtent);
00422 DestroyBlob(GetNextImageInList(image));
00423 image->next->blob=ReferenceBlob(image->blob);
00424 image->next->endian=image->endian;
00425 image->next->scene=image->scene+1;
00426 image->next->previous=image;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 MagickExport Image *AppendImages(const Image *image,
00462 const MagickBooleanType stack,ExceptionInfo *exception)
00463 {
00464 #define AppendImageTag "Append/Image"
00465
00466 Image
00467 *append_image;
00468
00469 long
00470 n,
00471 x_offset,
00472 y,
00473 y_offset;
00474
00475 MagickBooleanType
00476 matte,
00477 proceed,
00478 status;
00479
00480 RectangleInfo
00481 geometry;
00482
00483 register const Image
00484 *next;
00485
00486 unsigned long
00487 height,
00488 number_images,
00489 width;
00490
00491 ViewInfo
00492 *append_view,
00493 *image_view;
00494
00495
00496
00497
00498 assert(image != (Image *) NULL);
00499 assert(image->signature == MagickSignature);
00500 if (image->debug != MagickFalse)
00501 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00502 assert(exception != (ExceptionInfo *) NULL);
00503 assert(exception->signature == MagickSignature);
00504 matte=image->matte;
00505 number_images=1;
00506 width=image->columns;
00507 height=image->rows;
00508 next=GetNextImageInList(image);
00509 for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
00510 {
00511 if (next->matte != MagickFalse)
00512 matte=MagickTrue;
00513 number_images++;
00514 if (stack != MagickFalse)
00515 {
00516 if (next->columns > width)
00517 width=next->columns;
00518 height+=next->rows;
00519 continue;
00520 }
00521 width+=next->columns;
00522 if (next->rows > height)
00523 height=next->rows;
00524 }
00525
00526
00527
00528 append_image=CloneImage(image,width,height,MagickTrue,exception);
00529 if (append_image == (Image *) NULL)
00530 return((Image *) NULL);
00531 if (SetImageStorageClass(append_image,DirectClass) == MagickFalse)
00532 {
00533 InheritException(exception,&append_image->exception);
00534 append_image=DestroyImage(append_image);
00535 return((Image *) NULL);
00536 }
00537 append_image->matte=matte;
00538 (void) SetImageBackgroundColor(append_image);
00539 status=MagickTrue;
00540 x_offset=0;
00541 y_offset=0;
00542 append_view=AcquireCacheView(append_image);
00543 for (n=0; n < (long) number_images; n++)
00544 {
00545 SetGeometry(append_image,&geometry);
00546 GravityAdjustGeometry(image->columns,image->rows,image->gravity,&geometry);
00547 if (stack != MagickFalse)
00548 x_offset-=geometry.x;
00549 else
00550 y_offset-=geometry.y;
00551 image_view=AcquireCacheView(image);
00552 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00553 #pragma omp parallel for schedule(dynamic,4) shared(status)
00554 #endif
00555 for (y=0; y < (long) image->rows; y++)
00556 {
00557 MagickBooleanType
00558 sync;
00559
00560 register const IndexPacket
00561 *__restrict indexes;
00562
00563 register const PixelPacket
00564 *__restrict p;
00565
00566 register IndexPacket
00567 *__restrict append_indexes;
00568
00569 register long
00570 x;
00571
00572 register PixelPacket
00573 *__restrict q;
00574
00575 if (status == MagickFalse)
00576 continue;
00577 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
00578 q=QueueCacheViewAuthenticPixels(append_view,x_offset,y+y_offset,
00579 image->columns,1,exception);
00580 if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
00581 {
00582 status=MagickFalse;
00583 continue;
00584 }
00585 indexes=GetCacheViewVirtualIndexQueue(image_view);
00586 append_indexes=GetCacheViewAuthenticIndexQueue(append_view);
00587 for (x=0; x < (long) image->columns; x++)
00588 {
00589 q->red=p->red;
00590 q->green=p->green;
00591 q->blue=p->blue;
00592 q->opacity=OpaqueOpacity;
00593 if (image->matte != MagickFalse)
00594 q->opacity=p->opacity;
00595 if (image->colorspace == CMYKColorspace)
00596 append_indexes[x]=indexes[x];
00597 p++;
00598 q++;
00599 }
00600 sync=SyncCacheViewAuthenticPixels(append_view,exception);
00601 if (sync == MagickFalse)
00602 continue;
00603 }
00604 image_view=DestroyCacheView(image_view);
00605 proceed=SetImageProgress(image,AppendImageTag,n,number_images);
00606 if (proceed == MagickFalse)
00607 break;
00608 if (stack == MagickFalse)
00609 {
00610 x_offset+=image->columns;
00611 y_offset=0;
00612 }
00613 else
00614 {
00615 x_offset=0;
00616 y_offset+=image->rows;
00617 }
00618 image=GetNextImageInList(image);
00619 }
00620 append_view=DestroyCacheView(append_view);
00621 if (status == MagickFalse)
00622 append_image=DestroyImage(append_image);
00623 return(append_image);
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 static MagickPixelPacket **DestroyPixelThreadSet(MagickPixelPacket **pixels)
00656 {
00657 register long
00658 i;
00659
00660 assert(pixels != (MagickPixelPacket **) NULL);
00661 for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
00662 if (pixels[i] != (MagickPixelPacket *) NULL)
00663 pixels[i]=(MagickPixelPacket *) RelinquishMagickMemory(pixels[i]);
00664 return((MagickPixelPacket **) RelinquishMagickMemory(pixels));
00665 }
00666
00667 static MagickPixelPacket **AcquirePixelThreadSet(const Image *image)
00668 {
00669 register long
00670 i,
00671 j;
00672
00673 MagickPixelPacket
00674 **pixels;
00675
00676 unsigned long
00677 number_threads;
00678
00679 number_threads=GetOpenMPMaximumThreads();
00680 pixels=(MagickPixelPacket **) AcquireCachelineMemory(number_threads*
00681 sizeof(*pixels));
00682 if (pixels == (MagickPixelPacket **) NULL)
00683 return((MagickPixelPacket **) NULL);
00684 (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
00685 for (i=0; i < (long) number_threads; i++)
00686 {
00687 pixels[i]=(MagickPixelPacket *) AcquireQuantumMemory(image->columns,
00688 sizeof(**pixels));
00689 if (pixels[i] == (MagickPixelPacket *) NULL)
00690 return(DestroyPixelThreadSet(pixels));
00691 for (j=0; j < (long) image->columns; j++)
00692 GetMagickPixelPacket(image,&pixels[i][j]);
00693 }
00694 return(pixels);
00695 }
00696
00697 MagickExport Image *AverageImages(const Image *image,ExceptionInfo *exception)
00698 {
00699 #define AverageImageTag "Average/Image"
00700
00701 const Image
00702 *next;
00703
00704 Image
00705 *average_image;
00706
00707 long
00708 progress,
00709 y;
00710
00711 MagickBooleanType
00712 status;
00713
00714 MagickPixelPacket
00715 **average_pixels,
00716 zero;
00717
00718 unsigned long
00719 number_images;
00720
00721 ViewInfo
00722 *average_view;
00723
00724
00725
00726
00727 assert(image != (Image *) NULL);
00728 assert(image->signature == MagickSignature);
00729 if (image->debug != MagickFalse)
00730 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00731 assert(exception != (ExceptionInfo *) NULL);
00732 assert(exception->signature == MagickSignature);
00733 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
00734 if ((next->columns != image->columns) || (next->rows != image->rows))
00735 ThrowImageException(OptionError,"ImageWidthsOrHeightsDiffer");
00736
00737
00738
00739 average_image=CloneImage(image,image->columns,image->rows,MagickTrue,
00740 exception);
00741 if (average_image == (Image *) NULL)
00742 return((Image *) NULL);
00743 if (SetImageStorageClass(average_image,DirectClass) == MagickFalse)
00744 {
00745 InheritException(exception,&average_image->exception);
00746 average_image=DestroyImage(average_image);
00747 return((Image *) NULL);
00748 }
00749 average_pixels=AcquirePixelThreadSet(image);
00750 if (average_pixels == (MagickPixelPacket **) NULL)
00751 {
00752 average_image=DestroyImage(average_image);
00753 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
00754 }
00755
00756
00757
00758 status=MagickTrue;
00759 progress=0;
00760 GetMagickPixelPacket(image,&zero);
00761 number_images=GetImageListLength(image);
00762 average_view=AcquireCacheView(average_image);
00763 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00764 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
00765 #endif
00766 for (y=0; y < (long) average_image->rows; y++)
00767 {
00768 const Image
00769 *next;
00770
00771 MagickPixelPacket
00772 pixel;
00773
00774 register IndexPacket
00775 *__restrict average_indexes;
00776
00777 register long
00778 i,
00779 x;
00780
00781 register MagickPixelPacket
00782 *average_pixel;
00783
00784 register PixelPacket
00785 *__restrict q;
00786
00787 ViewInfo
00788 *image_view;
00789
00790 if (status == MagickFalse)
00791 continue;
00792 q=QueueCacheViewAuthenticPixels(average_view,0,y,average_image->columns,1,
00793 exception);
00794 if (q == (PixelPacket *) NULL)
00795 {
00796 status=MagickFalse;
00797 continue;
00798 }
00799 average_indexes=GetCacheViewAuthenticIndexQueue(average_view);
00800 pixel=zero;
00801 average_pixel=average_pixels[GetOpenMPThreadId()];
00802 for (x=0; x < (long) average_image->columns; x++)
00803 average_pixel[x]=zero;
00804 next=image;
00805 for (i=0; i < (long) number_images; i++)
00806 {
00807 register const IndexPacket
00808 *indexes;
00809
00810 register const PixelPacket
00811 *p;
00812
00813 image_view=AcquireCacheView(next);
00814 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
00815 if (p == (const PixelPacket *) NULL)
00816 {
00817 image_view=DestroyCacheView(image_view);
00818 break;
00819 }
00820 indexes=GetCacheViewVirtualIndexQueue(image_view);
00821 for (x=0; x < (long) next->columns; x++)
00822 {
00823 SetMagickPixelPacket(next,p,indexes+x,&pixel);
00824 average_pixel[x].red+=QuantumScale*pixel.red;
00825 average_pixel[x].green+=QuantumScale*pixel.green;
00826 average_pixel[x].blue+=QuantumScale*pixel.blue;
00827 average_pixel[x].opacity+=QuantumScale*pixel.opacity;
00828 if (average_image->colorspace == CMYKColorspace)
00829 average_pixel[x].index+=QuantumScale*pixel.index;
00830 p++;
00831 }
00832 image_view=DestroyCacheView(image_view);
00833 next=GetNextImageInList(next);
00834 }
00835 for (x=0; x < (long) average_image->columns; x++)
00836 {
00837 average_pixel[x].red=(MagickRealType) (QuantumRange*
00838 average_pixel[x].red/number_images);
00839 average_pixel[x].green=(MagickRealType) (QuantumRange*
00840 average_pixel[x].green/number_images);
00841 average_pixel[x].blue=(MagickRealType) (QuantumRange*
00842 average_pixel[x].blue/number_images);
00843 average_pixel[x].opacity=(MagickRealType) (QuantumRange*
00844 average_pixel[x].opacity/number_images);
00845 if (average_image->colorspace == CMYKColorspace)
00846 average_pixel[x].index=(MagickRealType) (QuantumRange*
00847 average_pixel[x].index/number_images);
00848 SetPixelPacket(average_image,&average_pixel[x],q,average_indexes+x);
00849 q++;
00850 }
00851 if (SyncCacheViewAuthenticPixels(average_view,exception) == MagickFalse)
00852 status=MagickFalse;
00853 if (image->progress_monitor != (MagickProgressMonitor) NULL)
00854 {
00855 MagickBooleanType
00856 proceed;
00857
00858 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00859 #pragma omp critical (MagickCore_AverageImages)
00860 #endif
00861 proceed=SetImageProgress(image,AverageImageTag,progress++,
00862 average_image->rows);
00863 if (proceed == MagickFalse)
00864 status=MagickFalse;
00865 }
00866 }
00867 average_view=DestroyCacheView(average_view);
00868 average_pixels=DestroyPixelThreadSet(average_pixels);
00869 if (status == MagickFalse)
00870 average_image=DestroyImage(average_image);
00871 return(average_image);
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 ExceptionType CatchImageException(Image *image)
00899 {
00900 ExceptionInfo
00901 *exception;
00902
00903 ExceptionType
00904 severity;
00905
00906 assert(image != (const Image *) NULL);
00907 assert(image->signature == MagickSignature);
00908 if (image->debug != MagickFalse)
00909 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00910 exception=AcquireExceptionInfo();
00911 GetImageException(image,exception);
00912 CatchException(exception);
00913 severity=exception->severity;
00914 exception=DestroyExceptionInfo(exception);
00915 return(severity);
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 MagickExport MagickBooleanType ClipImage(Image *image)
00950 {
00951 return(ClipImagePath(image,"#1",MagickTrue));
00952 }
00953
00954 MagickExport MagickBooleanType ClipImagePath(Image *image,const char *pathname,
00955 const MagickBooleanType inside)
00956 {
00957 #define ClipImagePathTag "ClipPath/Image"
00958
00959 char
00960 *property;
00961
00962 const char
00963 *value;
00964
00965 Image
00966 *clip_mask;
00967
00968 ImageInfo
00969 *image_info;
00970
00971 assert(image != (const Image *) NULL);
00972 assert(image->signature == MagickSignature);
00973 if (image->debug != MagickFalse)
00974 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00975 assert(pathname != NULL);
00976 property=AcquireString(pathname);
00977 (void) FormatMagickString(property,MaxTextExtent,"8BIM:1999,2998:%s",
00978 pathname);
00979 value=GetImageProperty(image,property);
00980 property=DestroyString(property);
00981 if (value == (const char *) NULL)
00982 {
00983 ThrowFileException(&image->exception,OptionError,"NoClipPathDefined",
00984 image->filename);
00985 return(MagickFalse);
00986 }
00987 image_info=AcquireImageInfo();
00988 (void) CopyMagickString(image_info->filename,image->filename,MaxTextExtent);
00989 (void) ConcatenateMagickString(image_info->filename,pathname,MaxTextExtent);
00990 clip_mask=BlobToImage(image_info,value,strlen(value),&image->exception);
00991 image_info=DestroyImageInfo(image_info);
00992 if (clip_mask == (Image *) NULL)
00993 return(MagickFalse);
00994 if (clip_mask->storage_class == PseudoClass)
00995 {
00996 (void) SyncImage(clip_mask);
00997 if (SetImageStorageClass(clip_mask,DirectClass) == MagickFalse)
00998 return(MagickFalse);
00999 }
01000 if (inside == MagickFalse)
01001 (void) NegateImage(clip_mask,MagickFalse);
01002 (void) FormatMagickString(clip_mask->magick_filename,MaxTextExtent,
01003 "8BIM:1999,2998:%s\nPS",pathname);
01004 (void) SetImageClipMask(image,clip_mask);
01005 clip_mask=DestroyImage(clip_mask);
01006 return(MagickTrue);
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 MagickExport Image *CloneImage(const Image *image,const unsigned long columns,
01048 const unsigned long rows,const MagickBooleanType detach,
01049 ExceptionInfo *exception)
01050 {
01051 Image
01052 *clone_image;
01053
01054 MagickRealType
01055 scale;
01056
01057 size_t
01058 length;
01059
01060
01061
01062
01063 assert(image != (const Image *) NULL);
01064 assert(image->signature == MagickSignature);
01065 if (image->debug != MagickFalse)
01066 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01067 assert(exception != (ExceptionInfo *) NULL);
01068 assert(exception->signature == MagickSignature);
01069 clone_image=(Image *) AcquireMagickMemory(sizeof(*clone_image));
01070 if (clone_image == (Image *) NULL)
01071 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
01072 (void) ResetMagickMemory(clone_image,0,sizeof(*clone_image));
01073 clone_image->signature=MagickSignature;
01074 clone_image->storage_class=image->storage_class;
01075 clone_image->colorspace=image->colorspace;
01076 clone_image->matte=image->matte;
01077 clone_image->columns=image->columns;
01078 clone_image->rows=image->rows;
01079 clone_image->dither=image->dither;
01080 if (image->colormap != (PixelPacket *) NULL)
01081 {
01082
01083
01084
01085 clone_image->colors=image->colors;
01086 length=(size_t) image->colors;
01087 clone_image->colormap=(PixelPacket *) AcquireQuantumMemory(length,
01088 sizeof(*clone_image->colormap));
01089 if (clone_image->colormap == (PixelPacket *) NULL)
01090 ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
01091 (void) CopyMagickMemory(clone_image->colormap,image->colormap,length*
01092 sizeof(*clone_image->colormap));
01093 }
01094 (void) CloneImageProfiles(clone_image,image);
01095 (void) CloneImageProperties(clone_image,image);
01096 (void) CloneImageArtifacts(clone_image,image);
01097 GetTimerInfo(&clone_image->timer);
01098 GetExceptionInfo(&clone_image->exception);
01099 InheritException(&clone_image->exception,&image->exception);
01100 if (image->ascii85 != (void *) NULL)
01101 Ascii85Initialize(clone_image);
01102 clone_image->magick_columns=image->magick_columns;
01103 clone_image->magick_rows=image->magick_rows;
01104 clone_image->type=image->type;
01105 (void) CopyMagickString(clone_image->magick_filename,image->magick_filename,
01106 MaxTextExtent);
01107 (void) CopyMagickString(clone_image->magick,image->magick,MaxTextExtent);
01108 (void) CopyMagickString(clone_image->filename,image->filename,MaxTextExtent);
01109 clone_image->progress_monitor=image->progress_monitor;
01110 clone_image->client_data=image->client_data;
01111 clone_image->reference_count=1;
01112 clone_image->next=NewImageList();
01113 clone_image->previous=NewImageList();
01114 clone_image->list=NewImageList();
01115 clone_image->clip_mask=NewImageList();
01116 clone_image->mask=NewImageList();
01117 clone_image->cache=ReferencePixelCache(image->cache);
01118 if (detach == MagickFalse)
01119 clone_image->blob=ReferenceBlob(image->blob);
01120 else
01121 clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
01122 clone_image->debug=IsEventLogging();
01123 clone_image->semaphore=AllocateSemaphoreInfo();
01124 if ((columns == 0) && (rows == 0))
01125 {
01126 if (image->montage != (char *) NULL)
01127 (void) CloneString(&clone_image->montage,image->montage);
01128 if (image->directory != (char *) NULL)
01129 (void) CloneString(&clone_image->directory,image->directory);
01130 if (image->clip_mask != (Image *) NULL)
01131 clone_image->clip_mask=CloneImage(image->clip_mask,0,0,MagickTrue,
01132 exception);
01133 if (image->mask != (Image *) NULL)
01134 clone_image->mask=CloneImage(image->mask,0,0,MagickTrue,exception);
01135 if (SetImageExtent(clone_image,columns,rows) == MagickFalse)
01136 clone_image=DestroyImage(clone_image);
01137 return(clone_image);
01138 }
01139 scale=(MagickRealType) columns/(MagickRealType) image->columns;
01140 clone_image->page.width=(unsigned long) (scale*image->page.width+0.5);
01141 clone_image->page.x=(long) (scale*image->page.x+0.5);
01142 clone_image->tile_offset.x=(long) (scale*image->tile_offset.x+0.5);
01143 scale=(MagickRealType) rows/(MagickRealType) image->rows;
01144 clone_image->page.height=(unsigned long) (scale*image->page.height+0.5);
01145 clone_image->page.y=(long) (image->page.y*scale+0.5);
01146 clone_image->tile_offset.y=(long) (scale*image->tile_offset.y+0.5);
01147 if (SetImageExtent(clone_image,columns,rows) == MagickFalse)
01148 clone_image=DestroyImage(clone_image);
01149 return(clone_image);
01150 }
01151
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 MagickExport ImageInfo *CloneImageInfo(const ImageInfo *image_info)
01177 {
01178 ImageInfo
01179 *clone_info;
01180
01181 clone_info=AcquireImageInfo();
01182 if (image_info == (ImageInfo *) NULL)
01183 return(clone_info);
01184 clone_info->compression=image_info->compression;
01185 clone_info->temporary=image_info->temporary;
01186 clone_info->adjoin=image_info->adjoin;
01187 clone_info->antialias=image_info->antialias;
01188 clone_info->scene=image_info->subimage;
01189 clone_info->number_scenes=image_info->subrange;
01190 clone_info->depth=image_info->depth;
01191 if (image_info->size != (char *) NULL)
01192 (void) CloneString(&clone_info->size,image_info->size);
01193 if (image_info->extract != (char *) NULL)
01194 (void) CloneString(&clone_info->extract,image_info->extract);
01195 if (image_info->scenes != (char *) NULL)
01196 (void) CloneString(&clone_info->scenes,image_info->scenes);
01197 if (image_info->page != (char *) NULL)
01198 (void) CloneString(&clone_info->page,image_info->page);
01199 clone_info->interlace=image_info->interlace;
01200 clone_info->endian=image_info->endian;
01201 clone_info->units=image_info->units;
01202 clone_info->quality=image_info->quality;
01203 if (image_info->sampling_factor != (char *) NULL)
01204 (void) CloneString(&clone_info->sampling_factor,
01205 image_info->sampling_factor);
01206 if (image_info->server_name != (char *) NULL)
01207 (void) CloneString(&clone_info->server_name,image_info->server_name);
01208 if (image_info->font != (char *) NULL)
01209 (void) CloneString(&clone_info->font,image_info->font);
01210 if (image_info->texture != (char *) NULL)
01211 (void) CloneString(&clone_info->texture,image_info->texture);
01212 if (image_info->density != (char *) NULL)
01213 (void) CloneString(&clone_info->density,image_info->density);
01214 clone_info->pointsize=image_info->pointsize;
01215 clone_info->fuzz=image_info->fuzz;
01216 clone_info->pen=image_info->pen;
01217 clone_info->background_color=image_info->background_color;
01218 clone_info->border_color=image_info->border_color;
01219 clone_info->matte_color=image_info->matte_color;
01220 clone_info->transparent_color=image_info->transparent_color;
01221 clone_info->dither=image_info->dither;
01222 clone_info->monochrome=image_info->monochrome;
01223 clone_info->colors=image_info->colors;
01224 clone_info->colorspace=image_info->colorspace;
01225 clone_info->type=image_info->type;
01226 clone_info->orientation=image_info->orientation;
01227 clone_info->preview_type=image_info->preview_type;
01228 clone_info->group=image_info->group;
01229 clone_info->ping=image_info->ping;
01230 clone_info->verbose=image_info->verbose;
01231 if (image_info->view != (char *) NULL)
01232 (void) CloneString(&clone_info->view,image_info->view);
01233 if (image_info->authenticate != (char *) NULL)
01234 (void) CloneString(&clone_info->authenticate,image_info->authenticate);
01235 (void) CloneImageOptions(clone_info,image_info);
01236 clone_info->progress_monitor=image_info->progress_monitor;
01237 clone_info->client_data=image_info->client_data;
01238 clone_info->cache=image_info->cache;
01239 if (image_info->cache != (void *) NULL)
01240 clone_info->cache=ReferencePixelCache(image_info->cache);
01241 if (image_info->profile != (void *) NULL)
01242 clone_info->profile=(void *) CloneStringInfo((StringInfo *)
01243 image_info->profile);
01244 SetImageInfoFile(clone_info,image_info->file);
01245 SetImageInfoBlob(clone_info,image_info->blob,image_info->length);
01246 clone_info->stream=image_info->stream;
01247 clone_info->virtual_pixel_method=image_info->virtual_pixel_method;
01248 (void) CopyMagickString(clone_info->magick,image_info->magick,MaxTextExtent);
01249 (void) CopyMagickString(clone_info->unique,image_info->unique,MaxTextExtent);
01250 (void) CopyMagickString(clone_info->zero,image_info->zero,MaxTextExtent);
01251 (void) CopyMagickString(clone_info->filename,image_info->filename,
01252 MaxTextExtent);
01253 clone_info->subimage=image_info->subimage;
01254 clone_info->subrange=image_info->subrange;
01255 clone_info->channel=image_info->channel;
01256 clone_info->debug=IsEventLogging();
01257 clone_info->signature=image_info->signature;
01258 return(clone_info);
01259 }
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 MagickExport Image *CombineImages(const Image *image,const ChannelType channel,
01290 ExceptionInfo *exception)
01291 {
01292 #define CombineImageTag "Combine/Image"
01293
01294 const Image
01295 *next;
01296
01297 Image
01298 *combine_image;
01299
01300 long
01301 progress,
01302 y;
01303
01304 MagickBooleanType
01305 status;
01306
01307 ViewInfo
01308 *combine_view;
01309
01310
01311
01312
01313 assert(image != (const Image *) NULL);
01314 assert(image->signature == MagickSignature);
01315 if (image->debug != MagickFalse)
01316 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01317 assert(exception != (ExceptionInfo *) NULL);
01318 assert(exception->signature == MagickSignature);
01319 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
01320 {
01321 if ((next->columns != image->columns) || (next->rows != image->rows))
01322 ThrowImageException(OptionError,"ImagesAreNotTheSameSize");
01323 }
01324 combine_image=CloneImage(image,0,0,MagickTrue,exception);
01325 if (combine_image == (Image *) NULL)
01326 return((Image *) NULL);
01327 if (SetImageStorageClass(combine_image,DirectClass) == MagickFalse)
01328 {
01329 InheritException(exception,&combine_image->exception);
01330 combine_image=DestroyImage(combine_image);
01331 return((Image *) NULL);
01332 }
01333 if ((channel & OpacityChannel) != 0)
01334 combine_image->matte=MagickTrue;
01335 (void) SetImageBackgroundColor(combine_image);
01336
01337
01338
01339 status=MagickTrue;
01340 progress=0;
01341 combine_view=AcquireCacheView(combine_image);
01342 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01343 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
01344 #endif
01345 for (y=0; y < (long) combine_image->rows; y++)
01346 {
01347 const Image
01348 *next;
01349
01350 PixelPacket
01351 *pixels;
01352
01353 register const PixelPacket
01354 *__restrict p;
01355
01356 register long
01357 x;
01358
01359 register PixelPacket
01360 *__restrict q;
01361
01362 ViewInfo
01363 *image_view;
01364
01365 if (status == MagickFalse)
01366 continue;
01367 pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns,
01368 1,exception);
01369 if (pixels == (PixelPacket *) NULL)
01370 {
01371 status=MagickFalse;
01372 continue;
01373 }
01374 next=image;
01375 if (((channel & RedChannel) != 0) && (next != (Image *) NULL))
01376 {
01377 image_view=AcquireCacheView(next);
01378 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01379 if (p == (const PixelPacket *) NULL)
01380 continue;
01381 q=pixels;
01382 for (x=0; x < (long) combine_image->columns; x++)
01383 {
01384 q->red=PixelIntensityToQuantum(p);
01385 p++;
01386 q++;
01387 }
01388 image_view=DestroyCacheView(image_view);
01389 next=GetNextImageInList(next);
01390 }
01391 if (((channel & GreenChannel) != 0) && (next != (Image *) NULL))
01392 {
01393 image_view=AcquireCacheView(next);
01394 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01395 if (p == (const PixelPacket *) NULL)
01396 continue;
01397 q=pixels;
01398 for (x=0; x < (long) combine_image->columns; x++)
01399 {
01400 q->green=PixelIntensityToQuantum(p);
01401 p++;
01402 q++;
01403 }
01404 image_view=DestroyCacheView(image_view);
01405 next=GetNextImageInList(next);
01406 }
01407 if (((channel & BlueChannel) != 0) && (next != (Image *) NULL))
01408 {
01409 image_view=AcquireCacheView(next);
01410 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01411 if (p == (const PixelPacket *) NULL)
01412 continue;
01413 q=pixels;
01414 for (x=0; x < (long) combine_image->columns; x++)
01415 {
01416 q->blue=PixelIntensityToQuantum(p);
01417 p++;
01418 q++;
01419 }
01420 image_view=DestroyCacheView(image_view);
01421 next=GetNextImageInList(next);
01422 }
01423 if (((channel & OpacityChannel) != 0) && (next != (Image *) NULL))
01424 {
01425 image_view=AcquireCacheView(next);
01426 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01427 if (p == (const PixelPacket *) NULL)
01428 continue;
01429 q=pixels;
01430 for (x=0; x < (long) combine_image->columns; x++)
01431 {
01432 q->opacity=PixelIntensityToQuantum(p);
01433 p++;
01434 q++;
01435 }
01436 image_view=DestroyCacheView(image_view);
01437 next=GetNextImageInList(next);
01438 }
01439 if (((channel & IndexChannel) != 0) &&
01440 (image->colorspace == CMYKColorspace) && (next != (Image *) NULL))
01441 {
01442 IndexPacket
01443 *indexes;
01444
01445 image_view=AcquireCacheView(next);
01446 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
01447 if (p == (const PixelPacket *) NULL)
01448 continue;
01449 indexes=GetCacheViewAuthenticIndexQueue(combine_view);
01450 for (x=0; x < (long) combine_image->columns; x++)
01451 {
01452 indexes[x]=PixelIntensityToQuantum(p);
01453 p++;
01454 }
01455 image_view=DestroyCacheView(image_view);
01456 next=GetNextImageInList(next);
01457 }
01458 if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse)
01459 status=MagickFalse;
01460 if (image->progress_monitor != (MagickProgressMonitor) NULL)
01461 {
01462 MagickBooleanType
01463 proceed;
01464
01465 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01466 #pragma omp critical (MagickCore_CombineImages)
01467 #endif
01468 proceed=SetImageProgress(image,CombineImageTag,progress++,
01469 combine_image->rows);
01470 if (proceed == MagickFalse)
01471 status=MagickFalse;
01472 }
01473 }
01474 combine_view=DestroyCacheView(combine_view);
01475 if (status == MagickFalse)
01476 combine_image=DestroyImage(combine_image);
01477 return(combine_image);
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506 MagickExport MagickBooleanType CycleColormapImage(Image *image,
01507 const long displace)
01508 {
01509 ExceptionInfo
01510 *exception;
01511
01512 long
01513 y;
01514
01515 MagickBooleanType
01516 status;
01517
01518 ViewInfo
01519 *image_view;
01520
01521 assert(image != (Image *) NULL);
01522 assert(image->signature == MagickSignature);
01523 if (image->debug != MagickFalse)
01524 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01525 if (image->storage_class == DirectClass)
01526 (void) SetImageType(image,PaletteType);
01527 status=MagickTrue;
01528 exception=(&image->exception);
01529 image_view=AcquireCacheView(image);
01530 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01531 #pragma omp parallel for schedule(dynamic,4) shared(status)
01532 #endif
01533 for (y=0; y < (long) image->rows; y++)
01534 {
01535 long
01536 index;
01537
01538 register IndexPacket
01539 *__restrict indexes;
01540
01541 register long
01542 x;
01543
01544 register PixelPacket
01545 *__restrict q;
01546
01547 if (status == MagickFalse)
01548 continue;
01549 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
01550 if (q == (PixelPacket *) NULL)
01551 {
01552 status=MagickFalse;
01553 continue;
01554 }
01555 indexes=GetCacheViewAuthenticIndexQueue(image_view);
01556 for (x=0; x < (long) image->columns; x++)
01557 {
01558 index=(long) (indexes[x]+displace) % image->colors;
01559 if (index < 0)
01560 index+=image->colors;
01561 indexes[x]=(IndexPacket) index;
01562 q->red=image->colormap[index].red;
01563 q->green=image->colormap[index].green;
01564 q->blue=image->colormap[index].blue;
01565 q++;
01566 }
01567 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
01568 status=MagickFalse;
01569 }
01570 image_view=DestroyCacheView(image_view);
01571 return(status);
01572 }
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597 MagickExport Image *DestroyImage(Image *image)
01598 {
01599 MagickBooleanType
01600 destroy;
01601
01602
01603
01604
01605 assert(image != (Image *) NULL);
01606 assert(image->signature == MagickSignature);
01607 if (image->debug != MagickFalse)
01608 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01609 destroy=MagickFalse;
01610 (void) LockSemaphoreInfo(image->semaphore);
01611 image->reference_count--;
01612 if (image->reference_count == 0)
01613 destroy=MagickTrue;
01614 (void) UnlockSemaphoreInfo(image->semaphore);
01615 if (destroy == MagickFalse)
01616 return((Image *) NULL);
01617
01618
01619
01620 DestroyImagePixels(image);
01621 if (image->clip_mask != (Image *) NULL)
01622 image->clip_mask=DestroyImage(image->clip_mask);
01623 if (image->mask != (Image *) NULL)
01624 image->mask=DestroyImage(image->mask);
01625 if (image->montage != (char *) NULL)
01626 image->montage=DestroyString(image->montage);
01627 if (image->directory != (char *) NULL)
01628 image->directory=DestroyString(image->directory);
01629 if (image->colormap != (PixelPacket *) NULL)
01630 image->colormap=(PixelPacket *) RelinquishMagickMemory(image->colormap);
01631 if (image->geometry != (char *) NULL)
01632 image->geometry=DestroyString(image->geometry);
01633 #if !defined(MAGICKCORE_EXCLUDE_DEPRECATED)
01634 DestroyImageAttributes(image);
01635 #endif
01636 DestroyImageProfiles(image);
01637 DestroyImageProperties(image);
01638 DestroyImageArtifacts(image);
01639 if (image->ascii85 != (Ascii85Info*) NULL)
01640 image->ascii85=(Ascii85Info *) RelinquishMagickMemory(image->ascii85);
01641 DestroyBlob(image);
01642 (void) DestroyExceptionInfo(&image->exception);
01643 if (image->semaphore != (SemaphoreInfo *) NULL)
01644 DestroySemaphoreInfo(&image->semaphore);
01645 image->signature=(~MagickSignature);
01646 image=(Image *) RelinquishMagickMemory(image);
01647 return(image);
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673 MagickExport ImageInfo *DestroyImageInfo(ImageInfo *image_info)
01674 {
01675 assert(image_info != (ImageInfo *) NULL);
01676 assert(image_info->signature == MagickSignature);
01677 if (image_info->debug != MagickFalse)
01678 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
01679 image_info->filename);
01680 if (image_info->size != (char *) NULL)
01681 image_info->size=DestroyString(image_info->size);
01682 if (image_info->extract != (char *) NULL)
01683 image_info->extract=DestroyString(image_info->extract);
01684 if (image_info->scenes != (char *) NULL)
01685 image_info->scenes=DestroyString(image_info->scenes);
01686 if (image_info->page != (char *) NULL)
01687 image_info->page=DestroyString(image_info->page);
01688 if (image_info->sampling_factor != (char *) NULL)
01689 image_info->sampling_factor=DestroyString(
01690 image_info->sampling_factor);
01691 if (image_info->server_name != (char *) NULL)
01692 image_info->server_name=DestroyString(
01693 image_info->server_name);
01694 if (image_info->font != (char *) NULL)
01695 image_info->font=DestroyString(image_info->font);
01696 if (image_info->texture != (char *) NULL)
01697 image_info->texture=DestroyString(image_info->texture);
01698 if (image_info->density != (char *) NULL)
01699 image_info->density=DestroyString(image_info->density);
01700 if (image_info->view != (char *) NULL)
01701 image_info->view=DestroyString(image_info->view);
01702 if (image_info->authenticate != (char *) NULL)
01703 image_info->authenticate=DestroyString(
01704 image_info->authenticate);
01705 DestroyImageOptions(image_info);
01706 if (image_info->cache != (void *) NULL)
01707 image_info->cache=DestroyPixelCacheInfo(image_info->cache);
01708 if (image_info->profile != (StringInfo *) NULL)
01709 image_info->profile=(void *) DestroyStringInfo((StringInfo *)
01710 image_info->profile);
01711 image_info->signature=(~MagickSignature);
01712 image_info=(ImageInfo *) RelinquishMagickMemory(image_info);
01713 return(image_info);
01714 }
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738 MagickExport void DisassociateImageStream(Image *image)
01739 {
01740 assert(image != (const Image *) NULL);
01741 assert(image->signature == MagickSignature);
01742 if (image->debug != MagickFalse)
01743 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01744 (void) DetachBlob(image->blob);
01745 }
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
01772 {
01773 assert(image != (const Image *) NULL);
01774 if (image->debug != MagickFalse)
01775 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01776 assert(image->signature == MagickSignature);
01777 return(image->matte);
01778 }
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802 MagickExport Image *GetImageClipMask(const Image *image,
01803 ExceptionInfo *exception)
01804 {
01805 assert(image != (const Image *) NULL);
01806 if (image->debug != MagickFalse)
01807 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01808 assert(image->signature == MagickSignature);
01809 if (image->clip_mask == (Image *) NULL)
01810 return((Image *) NULL);
01811 return(CloneImage(image->clip_mask,0,0,MagickTrue,exception));
01812 }
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 MagickExport void GetImageException(Image *image,ExceptionInfo *exception)
01840 {
01841 register Image
01842 *next;
01843
01844 assert(image != (Image *) NULL);
01845 assert(image->signature == MagickSignature);
01846 if (image->debug != MagickFalse)
01847 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01848 assert(exception != (ExceptionInfo *) NULL);
01849 assert(exception->signature == MagickSignature);
01850 for (next=image; next != (Image *) NULL; next=GetNextImageInList(next))
01851 {
01852 if (next->exception.severity == UndefinedException)
01853 continue;
01854 if (next->exception.severity > exception->severity)
01855 InheritException(exception,&next->exception);
01856 next->exception.severity=UndefinedException;
01857 }
01858 }
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882 MagickExport void GetImageInfo(ImageInfo *image_info)
01883 {
01884 ExceptionInfo
01885 *exception;
01886
01887
01888
01889
01890 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01891 assert(image_info != (ImageInfo *) NULL);
01892 (void) ResetMagickMemory(image_info,0,sizeof(*image_info));
01893 image_info->adjoin=MagickTrue;
01894 image_info->interlace=NoInterlace;
01895 image_info->channel=DefaultChannels;
01896 image_info->quality=UndefinedCompressionQuality;
01897 image_info->antialias=MagickTrue;
01898 image_info->dither=MagickTrue;
01899 exception=AcquireExceptionInfo();
01900 (void) QueryColorDatabase(BackgroundColor,&image_info->background_color,
01901 exception);
01902 (void) QueryColorDatabase(BorderColor,&image_info->border_color,exception);
01903 (void) QueryColorDatabase(MatteColor,&image_info->matte_color,exception);
01904 (void) QueryColorDatabase(TransparentColor,&image_info->transparent_color,
01905 exception);
01906 exception=DestroyExceptionInfo(exception);
01907 image_info->debug=IsEventLogging();
01908 image_info->signature=MagickSignature;
01909 }
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933 MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
01934 {
01935 assert(image != (const Image *) NULL);
01936 if (image->debug != MagickFalse)
01937 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01938 assert(image->signature == MagickSignature);
01939 if (image->mask == (Image *) NULL)
01940 return((Image *) NULL);
01941 return(CloneImage(image->mask,0,0,MagickTrue,exception));
01942 }
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
01977 {
01978 assert(image != (Image *) NULL);
01979 assert(image->signature == MagickSignature);
01980 if (image->debug != MagickFalse)
01981 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01982 if (image->colorspace == CMYKColorspace)
01983 {
01984 if (image->matte == MagickFalse)
01985 return(ColorSeparationType);
01986 return(ColorSeparationMatteType);
01987 }
01988 if (IsMonochromeImage(image,exception) != MagickFalse)
01989 return(BilevelType);
01990 if (IsGrayImage(image,exception) != MagickFalse)
01991 {
01992 if (image->matte != MagickFalse)
01993 return(GrayscaleMatteType);
01994 return(GrayscaleType);
01995 }
01996 if (IsPaletteImage(image,exception) != MagickFalse)
01997 {
01998 if (image->matte != MagickFalse)
01999 return(PaletteMatteType);
02000 return(PaletteType);
02001 }
02002 if (image->matte != MagickFalse)
02003 return(TrueColorMatteType);
02004 return(TrueColorType);
02005 }
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
02032 {
02033 assert(image != (Image *) NULL);
02034 assert(image->signature == MagickSignature);
02035 if (image->debug != MagickFalse)
02036 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02037 return(GetPixelCacheVirtualMethod(image));
02038 }
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073 MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
02074 Image *image,const char *format,int value,char *filename)
02075 {
02076 char
02077 *q;
02078
02079 int
02080 c;
02081
02082 MagickBooleanType
02083 canonical;
02084
02085 register const char
02086 *p;
02087
02088 canonical=MagickFalse;
02089 (void) CopyMagickString(filename,format,MaxTextExtent);
02090 for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
02091 {
02092 q=(char *) p+1;
02093 if (*q == '%')
02094 {
02095 p=q+1;
02096 continue;
02097 }
02098 if (*q == '0')
02099 {
02100 long
02101 value;
02102
02103 value=strtol(q,&q,10);
02104 }
02105 switch (*q)
02106 {
02107 case 'd':
02108 case 'o':
02109 case 'x':
02110 {
02111 q++;
02112 c=(*q);
02113 *q='\0';
02114 (void) FormatMagickString(filename+(p-format),(size_t) (MaxTextExtent-
02115 (p-format)),p,value);
02116 *q=c;
02117 (void) ConcatenateMagickString(filename,q,MaxTextExtent);
02118 canonical=MagickTrue;
02119 if (*(q-1) != '%')
02120 break;
02121 p++;
02122 break;
02123 }
02124 case '[':
02125 {
02126 char
02127 pattern[MaxTextExtent];
02128
02129 const char
02130 *value;
02131
02132 long
02133 depth;
02134
02135 register char
02136 *r;
02137
02138 register long
02139 i;
02140
02141
02142
02143
02144 if (strchr(p,']') == (char *) NULL)
02145 break;
02146 depth=1;
02147 r=q+1;
02148 for (i=0; (i < (MaxTextExtent-1L)) && (*r != '\0'); i++)
02149 {
02150 if (*r == '[')
02151 depth++;
02152 if (*r == ']')
02153 depth--;
02154 if (depth <= 0)
02155 break;
02156 pattern[i]=(*r++);
02157 }
02158 pattern[i]='\0';
02159 if (LocaleNCompare(pattern,"filename:",9) != 0)
02160 break;
02161 value=(const char *) NULL;
02162 if ((image_info != (const ImageInfo *) NULL) &&
02163 (image != (const Image *) NULL))
02164 value=GetMagickProperty(image_info,image,pattern);
02165 else
02166 if (image != (Image *) NULL)
02167 value=GetImageProperty(image,pattern);
02168 else
02169 if (image_info != (ImageInfo *) NULL)
02170 value=GetImageOption(image_info,pattern);
02171 if (value == (const char *) NULL)
02172 break;
02173 q--;
02174 c=(*q);
02175 *q='\0';
02176 (void) CopyMagickString(filename+(p-format),value,(size_t)
02177 (MaxTextExtent-(p-format)));
02178 *q=c;
02179 (void) ConcatenateMagickString(filename,r+1,MaxTextExtent);
02180 canonical=MagickTrue;
02181 if (*(q-1) != '%')
02182 break;
02183 p++;
02184 break;
02185 }
02186 default:
02187 break;
02188 }
02189 }
02190 for (q=filename; *q != '\0'; q++)
02191 if ((*q == '%') && (*(q+1) == '%'))
02192 (void) CopyMagickString(q,q+1,(size_t) (MaxTextExtent-(q-filename)));
02193 if (canonical == MagickFalse)
02194 (void) CopyMagickString(filename,format,MaxTextExtent);
02195 return(strlen(filename));
02196 }
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225 MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
02226 ExceptionInfo *exception)
02227 {
02228 #if !defined(MAGICKCORE_HDRI_SUPPORT)
02229 (void) image;
02230 (void) exception;
02231 return(MagickFalse);
02232 #else
02233 long
02234 y;
02235
02236 MagickBooleanType
02237 status;
02238
02239 MagickPixelPacket
02240 zero;
02241
02242 ViewInfo
02243 *image_view;
02244
02245 assert(image != (Image *) NULL);
02246 assert(image->signature == MagickSignature);
02247 if (image->debug != MagickFalse)
02248 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02249 status=MagickFalse;
02250 GetMagickPixelPacket(image,&zero);
02251 image_view=AcquireCacheView(image);
02252 for (y=0; y < (long) image->rows; y++)
02253 {
02254 MagickPixelPacket
02255 pixel;
02256
02257 register const IndexPacket
02258 *indexes;
02259
02260 register const PixelPacket
02261 *p;
02262
02263 register long
02264 x;
02265
02266 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
02267 if (p == (const PixelPacket *) NULL)
02268 break;
02269 indexes=GetCacheViewVirtualIndexQueue(image_view);
02270 pixel=zero;
02271 for (x=0; x < (long) image->columns; x++)
02272 {
02273 SetMagickPixelPacket(image,p,indexes+x,&pixel);
02274 if ((pixel.red < 0.0) || (pixel.red > QuantumRange) ||
02275 (pixel.red != (QuantumAny) pixel.red))
02276 break;
02277 if ((pixel.green < 0.0) || (pixel.green > QuantumRange) ||
02278 (pixel.green != (QuantumAny) pixel.green))
02279 break;
02280 if ((pixel.blue < 0.0) || (pixel.blue > QuantumRange) ||
02281 (pixel.blue != (QuantumAny) pixel.blue))
02282 break;
02283 if (pixel.matte != MagickFalse)
02284 {
02285 if ((pixel.opacity < 0.0) || (pixel.opacity > QuantumRange) ||
02286 (pixel.opacity != (QuantumAny) pixel.opacity))
02287 break;
02288 }
02289 if (pixel.colorspace == CMYKColorspace)
02290 {
02291 if ((pixel.index < 0.0) || (pixel.index > QuantumRange) ||
02292 (pixel.index != (QuantumAny) pixel.index))
02293 break;
02294 }
02295 p++;
02296 }
02297 if (x < (long) image->columns)
02298 {
02299 status=MagickTrue;
02300 continue;
02301 }
02302 }
02303 image_view=DestroyCacheView(image_view);
02304 return(status);
02305 #endif
02306 }
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331 MagickExport MagickBooleanType IsImageObject(const Image *image)
02332 {
02333 register const Image
02334 *p;
02335
02336 assert(image != (Image *) NULL);
02337 if (image->debug != MagickFalse)
02338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02339 for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
02340 if (p->signature != MagickSignature)
02341 return(MagickFalse);
02342 return(MagickTrue);
02343 }
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368 MagickExport MagickBooleanType IsTaintImage(const Image *image)
02369 {
02370 char
02371 magick[MaxTextExtent],
02372 filename[MaxTextExtent];
02373
02374 register const Image
02375 *p;
02376
02377 assert(image != (Image *) NULL);
02378 if (image->debug != MagickFalse)
02379 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02380 assert(image->signature == MagickSignature);
02381 (void) CopyMagickString(magick,image->magick,MaxTextExtent);
02382 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
02383 for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
02384 {
02385 if (p->taint != MagickFalse)
02386 return(MagickTrue);
02387 if (LocaleCompare(p->magick,magick) != 0)
02388 return(MagickTrue);
02389 if (LocaleCompare(p->filename,filename) != 0)
02390 return(MagickTrue);
02391 }
02392 return(MagickFalse);
02393 }
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421 MagickExport MagickBooleanType ModifyImage(Image **image,
02422 ExceptionInfo *exception)
02423 {
02424 Image
02425 *clone_image;
02426
02427 assert(image != (Image **) NULL);
02428 assert(*image != (Image *) NULL);
02429 assert((*image)->signature == MagickSignature);
02430 if ((*image)->debug != MagickFalse)
02431 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
02432 if ((*image)->reference_count <= 1)
02433 return(MagickTrue);
02434 clone_image=CloneImage(*image,0,0,MagickTrue,exception);
02435 AcquireSemaphoreInfo(&(*image)->semaphore);
02436 (*image)->reference_count--;
02437 RelinquishSemaphoreInfo((*image)->semaphore);
02438 *image=clone_image;
02439 return(MagickTrue);
02440 }
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473 MagickExport Image *NewMagickImage(const ImageInfo *image_info,
02474 const unsigned long width,const unsigned long height,
02475 const MagickPixelPacket *background)
02476 {
02477 ExceptionInfo
02478 *exception;
02479
02480 Image
02481 *image;
02482
02483 long
02484 y;
02485
02486 MagickBooleanType
02487 status;
02488
02489 ViewInfo
02490 *image_view;
02491
02492 assert(image_info != (const ImageInfo *) NULL);
02493 if (image_info->debug != MagickFalse)
02494 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02495 assert(image_info->signature == MagickSignature);
02496 assert(background != (const MagickPixelPacket *) NULL);
02497 image=AcquireImage(image_info);
02498 image->columns=width;
02499 image->rows=height;
02500 image->colorspace=background->colorspace;
02501 image->matte=background->matte;
02502 image->fuzz=background->fuzz;
02503 image->depth=background->depth;
02504 status=MagickTrue;
02505 exception=(&image->exception);
02506 image_view=AcquireCacheView(image);
02507 for (y=0; y < (long) image->rows; y++)
02508 {
02509 register IndexPacket
02510 *__restrict indexes;
02511
02512 register long
02513 x;
02514
02515 register PixelPacket
02516 *__restrict q;
02517
02518 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
02519 if (q == (PixelPacket *) NULL)
02520 {
02521 status=MagickFalse;
02522 continue;
02523 }
02524 indexes=GetCacheViewAuthenticIndexQueue(image_view);
02525 for (x=0; x < (long) image->columns; x++)
02526 {
02527 SetPixelPacket(image,background,q,indexes+x);
02528 q++;
02529 }
02530 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02531 status=MagickFalse;
02532 if (status == MagickFalse)
02533 break;
02534 }
02535 image_view=DestroyCacheView(image_view);
02536 if (status == MagickFalse)
02537 image=DestroyImage(image);
02538 return(image);
02539 }
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564 MagickExport Image *ReferenceImage(Image *image)
02565 {
02566 assert(image != (Image *) NULL);
02567 if (image->debug != MagickFalse)
02568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02569 assert(image->signature == MagickSignature);
02570 (void) LockSemaphoreInfo(image->semaphore);
02571 image->reference_count++;
02572 (void) UnlockSemaphoreInfo(image->semaphore);
02573 return(image);
02574 }
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 MagickExport MagickBooleanType ResetImagePage(Image *image,const char *page)
02601 {
02602 MagickStatusType
02603 flags;
02604
02605 RectangleInfo
02606 geometry;
02607
02608 assert(image != (Image *) NULL);
02609 assert(image->signature == MagickSignature);
02610 if (image->debug != MagickFalse)
02611 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02612 flags=ParseAbsoluteGeometry(page,&geometry);
02613 if ((flags & WidthValue) != 0)
02614 {
02615 if ((flags & HeightValue) == 0)
02616 geometry.height=geometry.width;
02617 image->page.width=geometry.width;
02618 image->page.height=geometry.height;
02619 }
02620 if ((flags & AspectValue) != 0)
02621 {
02622 if ((flags & XValue) != 0)
02623 image->page.x+=geometry.x;
02624 if ((flags & YValue) != 0)
02625 image->page.y+=geometry.y;
02626 }
02627 else
02628 {
02629 if ((flags & XValue) != 0)
02630 {
02631 image->page.x=geometry.x;
02632 if ((image->page.width == 0) && (geometry.x > 0))
02633 image->page.width=image->columns+geometry.x;
02634 }
02635 if ((flags & YValue) != 0)
02636 {
02637 image->page.y=geometry.y;
02638 if ((image->page.height == 0) && (geometry.y > 0))
02639 image->page.height=image->rows+geometry.y;
02640 }
02641 }
02642 return(MagickTrue);
02643 }
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674 MagickExport MagickBooleanType SeparateImageChannel(Image *image,
02675 const ChannelType channel)
02676 {
02677 #define SeparateImageTag "Separate/Image"
02678
02679 ExceptionInfo
02680 *exception;
02681
02682 long
02683 progress,
02684 y;
02685
02686 MagickBooleanType
02687 status;
02688
02689 ViewInfo
02690 *image_view;
02691
02692 assert(image != (Image *) NULL);
02693 assert(image->signature == MagickSignature);
02694 if (image->debug != MagickFalse)
02695 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02696 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02697 return(MagickFalse);
02698
02699
02700
02701 status=MagickTrue;
02702 if ( channel == RGBChannels )
02703 image->matte=MagickTrue;
02704 progress=0;
02705 exception=(&image->exception);
02706 image_view=AcquireCacheView(image);
02707 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02708 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
02709 #endif
02710 for (y=0; y < (long) image->rows; y++)
02711 {
02712 register IndexPacket
02713 *__restrict indexes;
02714
02715 register long
02716 x;
02717
02718 register PixelPacket
02719 *__restrict q;
02720
02721 if (status == MagickFalse)
02722 continue;
02723 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
02724 if (q == (PixelPacket *) NULL)
02725 {
02726 status=MagickFalse;
02727 continue;
02728 }
02729 indexes=GetCacheViewAuthenticIndexQueue(image_view);
02730 switch (channel)
02731 {
02732 case RedChannel:
02733 {
02734 for (x=0; x < (long) image->columns; x++)
02735 {
02736 q->green=q->red;
02737 q->blue=q->red;
02738 q++;
02739 }
02740 break;
02741 }
02742 case GreenChannel:
02743 {
02744 for (x=0; x < (long) image->columns; x++)
02745 {
02746 q->red=q->green;
02747 q->blue=q->green;
02748 q++;
02749 }
02750 break;
02751 }
02752 case BlueChannel:
02753 {
02754 for (x=0; x < (long) image->columns; x++)
02755 {
02756 q->red=q->blue;
02757 q->green=q->blue;
02758 q++;
02759 }
02760 break;
02761 }
02762 case OpacityChannel:
02763 {
02764 for (x=0; x < (long) image->columns; x++)
02765 {
02766 q->red=q->opacity;
02767 q->green=q->opacity;
02768 q->blue=q->opacity;
02769 q++;
02770 }
02771 break;
02772 }
02773 case BlackChannel:
02774 {
02775 if ((image->storage_class != PseudoClass) &&
02776 (image->colorspace != CMYKColorspace))
02777 break;
02778 for (x=0; x < (long) image->columns; x++)
02779 {
02780 q->red=indexes[x];
02781 q->green=indexes[x];
02782 q->blue=indexes[x];
02783 q++;
02784 }
02785 break;
02786 }
02787 case TrueAlphaChannel:
02788 {
02789 for (x=0; x < (long) image->columns; x++)
02790 {
02791 q->red=(Quantum) (QuantumRange-q->opacity);
02792 q->green=(Quantum) (QuantumRange-q->opacity);
02793 q->blue=(Quantum) (QuantumRange-q->opacity);
02794 q++;
02795 }
02796 break;
02797 }
02798 case RGBChannels:
02799 {
02800 for (x=0; x < (long) image->columns; x++)
02801 {
02802 q->opacity=(Quantum) (QuantumRange-PixelIntensityToQuantum(q));
02803 q++;
02804 }
02805 break;
02806 }
02807 default:
02808 break;
02809 }
02810 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
02811 status=MagickFalse;
02812 if (image->progress_monitor != (MagickProgressMonitor) NULL)
02813 {
02814 MagickBooleanType
02815 proceed;
02816
02817 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02818 #pragma omp critical (MagickCore_SeparateImageChannel)
02819 #endif
02820 proceed=SetImageProgress(image,SeparateImageTag,progress++,image->rows);
02821 if (proceed == MagickFalse)
02822 status=MagickFalse;
02823 }
02824 }
02825 image_view=DestroyCacheView(image_view);
02826 if ( channel != RGBChannels )
02827 image->matte=MagickFalse;
02828 (void) SetImageColorspace(image,RGBColorspace);
02829 return(status);
02830 }
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862 MagickExport Image *SeparateImages(const Image *image,const ChannelType channel,
02863 ExceptionInfo *exception)
02864 {
02865 Image
02866 *images,
02867 *separate_image;
02868
02869 assert(image != (Image *) NULL);
02870 assert(image->signature == MagickSignature);
02871 if (image->debug != MagickFalse)
02872 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
02873 images=NewImageList();
02874 if ((channel & RedChannel) != 0)
02875 {
02876 separate_image=CloneImage(image,0,0,MagickTrue,exception);
02877 (void) SeparateImageChannel(separate_image,RedChannel);
02878 AppendImageToList(&images,separate_image);
02879 }
02880 if ((channel & GreenChannel) != 0)
02881 {
02882 separate_image=CloneImage(image,0,0,MagickTrue,exception);
02883 (void) SeparateImageChannel(separate_image,GreenChannel);
02884 AppendImageToList(&images,separate_image);
02885 }
02886 if ((channel & BlueChannel) != 0)
02887 {
02888 separate_image=CloneImage(image,0,0,MagickTrue,exception);
02889 (void) SeparateImageChannel(separate_image,BlueChannel);
02890 AppendImageToList(&images,separate_image);
02891 }
02892 if (((channel & BlackChannel) != 0) && (image->colorspace == CMYKColorspace))
02893 {
02894 separate_image=CloneImage(image,0,0,MagickTrue,exception);
02895 (void) SeparateImageChannel(separate_image,BlackChannel);
02896 AppendImageToList(&images,separate_image);
02897 }
02898 if ((channel & OpacityChannel) != 0)
02899 {
02900 separate_image=CloneImage(image,0,0,MagickTrue,exception);
02901 (void) SeparateImageChannel(separate_image,OpacityChannel);
02902 AppendImageToList(&images,separate_image);
02903 }
02904 return(images);
02905 }
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
02937 const AlphaChannelType alpha_type)
02938 {
02939 MagickBooleanType
02940 status;
02941
02942 assert(image != (Image *) NULL);
02943 if (image->debug != MagickFalse)
02944 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02945 assert(image->signature == MagickSignature);
02946 status=MagickFalse;
02947 switch (alpha_type)
02948 {
02949 case ActivateAlphaChannel:
02950 {
02951 image->matte=MagickTrue;
02952 break;
02953 }
02954 case BackgroundAlphaChannel:
02955 {
02956 ExceptionInfo
02957 *exception;
02958
02959 IndexPacket
02960 index;
02961
02962 long
02963 y;
02964
02965 MagickBooleanType
02966 status;
02967
02968 MagickPixelPacket
02969 background;
02970
02971 PixelPacket
02972 pixel;
02973
02974 ViewInfo
02975 *image_view;
02976
02977
02978
02979
02980 if (image->matte == MagickFalse)
02981 break;
02982 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
02983 break;
02984 GetMagickPixelPacket(image,&background);
02985 SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
02986 NULL,&background);
02987 if (image->colorspace == CMYKColorspace)
02988 ConvertRGBToCMYK(&background);
02989 index=0;
02990 SetPixelPacket(image,&background,&pixel,&index);
02991 status=MagickTrue;
02992 exception=(&image->exception);
02993 image_view=AcquireCacheView(image);
02994 #if defined(MAGICKCORE_OPENMP_SUPPORT)
02995 #pragma omp parallel for schedule(dynamic,4) shared(status)
02996 #endif
02997 for (y=0; y < (long) image->rows; y++)
02998 {
02999 register IndexPacket
03000 *__restrict indexes;
03001
03002 register long
03003 x;
03004
03005 register PixelPacket
03006 *__restrict q;
03007
03008 if (status == MagickFalse)
03009 continue;
03010 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
03011 exception);
03012 if (q == (PixelPacket *) NULL)
03013 {
03014 status=MagickFalse;
03015 continue;
03016 }
03017 for (x=0; x < (long) image->columns; x++)
03018 {
03019 if (q->opacity == TransparentOpacity)
03020 {
03021 q->red=pixel.red;
03022 q->green=pixel.green;
03023 q->blue=pixel.blue;
03024 }
03025 q++;
03026 }
03027 if (image->colorspace == CMYKColorspace)
03028 {
03029 indexes=GetCacheViewAuthenticIndexQueue(image_view);
03030 for (x=0; x < (long) image->columns; x++)
03031 indexes[x]=index;
03032 }
03033 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
03034 status=MagickFalse;
03035 }
03036 image_view=DestroyCacheView(image_view);
03037 return(status);
03038 }
03039 case DeactivateAlphaChannel:
03040 {
03041 image->matte=MagickFalse;
03042 break;
03043 }
03044 case ShapeAlphaChannel:
03045 case CopyAlphaChannel:
03046 {
03047
03048
03049
03050
03051 status=SeparateImageChannel(image,RGBChannels);
03052 image->matte=MagickTrue;
03053 if (alpha_type == ShapeAlphaChannel)
03054 {
03055 MagickPixelPacket
03056 background;
03057
03058
03059
03060
03061 GetMagickPixelPacket(image,&background);
03062 SetMagickPixelPacket(image,&(image->background_color),(IndexPacket *)
03063 NULL,&background);
03064 (void) LevelImageColors(image,DefaultChannels,&background,&background,
03065 MagickTrue);
03066 }
03067 break;
03068 }
03069 case ExtractAlphaChannel:
03070 {
03071 status=SeparateImageChannel(image,TrueAlphaChannel);
03072 image->matte=MagickFalse;
03073 break;
03074 }
03075 case ResetAlphaChannel:
03076 case OpaqueAlphaChannel:
03077 {
03078 status=SetImageOpacity(image,OpaqueOpacity);
03079 image->matte=MagickTrue;
03080 break;
03081 }
03082 case TransparentAlphaChannel:
03083 {
03084 status=SetImageOpacity(image,TransparentOpacity);
03085 image->matte=MagickTrue;
03086 break;
03087 }
03088 case SetAlphaChannel:
03089 {
03090 if (image->matte == MagickFalse)
03091 {
03092 status=SetImageOpacity(image,OpaqueOpacity);
03093 image->matte=MagickTrue;
03094 }
03095 break;
03096 }
03097 case UndefinedAlphaChannel:
03098 break;
03099 }
03100 return(status);
03101 }
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127 MagickExport MagickBooleanType SetImageBackgroundColor(Image *image)
03128 {
03129 ExceptionInfo
03130 *exception;
03131
03132 IndexPacket
03133 index;
03134
03135 long
03136 y;
03137
03138 MagickBooleanType
03139 status;
03140
03141 MagickPixelPacket
03142 background;
03143
03144 PixelPacket
03145 pixel;
03146
03147 ViewInfo
03148 *image_view;
03149
03150 assert(image != (Image *) NULL);
03151 if (image->debug != MagickFalse)
03152 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03153 assert(image->signature == MagickSignature);
03154 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
03155 return(MagickFalse);
03156 if (image->background_color.opacity != OpaqueOpacity)
03157 image->matte=MagickTrue;
03158 GetMagickPixelPacket(image,&background);
03159 SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *)
03160 NULL,&background);
03161 if (image->colorspace == CMYKColorspace)
03162 ConvertRGBToCMYK(&background);
03163 index=0;
03164 SetPixelPacket(image,&background,&pixel,&index);
03165
03166
03167
03168 status=MagickTrue;
03169 exception=(&image->exception);
03170 image_view=AcquireCacheView(image);
03171 #if defined(MAGICKCORE_OPENMP_SUPPORT)
03172 #pragma omp parallel for schedule(dynamic,4) shared(status)
03173 #endif
03174 for (y=0; y < (long) image->rows; y++)
03175 {
03176 register IndexPacket
03177 *__restrict indexes;
03178
03179 register long
03180 x;
03181
03182 register PixelPacket
03183 *__restrict q;
03184
03185 if (status == MagickFalse)
03186 continue;
03187 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
03188 if (q == (PixelPacket *) NULL)
03189 {
03190 status=MagickFalse;
03191 continue;
03192 }
03193 for (x=0; x < (long) image->columns; x++)
03194 *q++=pixel;
03195 if (image->colorspace == CMYKColorspace)
03196 {
03197 indexes=GetCacheViewAuthenticIndexQueue(image_view);
03198 for (x=0; x < (long) image->columns; x++)
03199 indexes[x]=index;
03200 }
03201 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
03202 status=MagickFalse;
03203 }
03204 image_view=DestroyCacheView(image_view);
03205 return(status);
03206 }
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234 MagickExport MagickBooleanType SetImageStorageClass(Image *image,
03235 const ClassType storage_class)
03236 {
03237 Cache
03238 cache;
03239
03240 if (image->storage_class == storage_class)
03241 return(MagickTrue);
03242 image->storage_class=storage_class;
03243 cache=GetImagePixelCache(image,MagickTrue,&image->exception);
03244 return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
03245 }
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274 MagickExport MagickBooleanType SetImageClipMask(Image *image,
03275 const Image *clip_mask)
03276 {
03277 assert(image != (Image *) NULL);
03278 if (image->debug != MagickFalse)
03279 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03280 assert(image->signature == MagickSignature);
03281 if (clip_mask != (const Image *) NULL)
03282 if ((clip_mask->columns != image->columns) ||
03283 (clip_mask->rows != image->rows))
03284 ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
03285 if (image->clip_mask != (Image *) NULL)
03286 image->clip_mask=DestroyImage(image->clip_mask);
03287 image->clip_mask=NewImageList();
03288 if (clip_mask == (Image *) NULL)
03289 return(MagickTrue);
03290 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
03291 return(MagickFalse);
03292 image->clip_mask=CloneImage(clip_mask,0,0,MagickTrue,&image->exception);
03293 if (image->clip_mask == (Image *) NULL)
03294 return(MagickFalse);
03295 return(MagickTrue);
03296 }
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325 MagickExport MagickBooleanType SetImageExtent(Image *image,
03326 const unsigned long columns,const unsigned long rows)
03327 {
03328 Cache
03329 cache;
03330
03331 if ((columns != 0) && (rows != 0))
03332 {
03333 image->columns=columns;
03334 image->rows=rows;
03335 }
03336 cache=GetImagePixelCache(image,MagickTrue,&image->exception);
03337 return(cache == (Cache) NULL ? MagickFalse : MagickTrue);
03338 }
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376 MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info,
03377 const MagickBooleanType rectify,ExceptionInfo *exception)
03378 {
03379 char
03380 extension[MaxTextExtent],
03381 filename[MaxTextExtent],
03382 magic[MaxTextExtent],
03383 *q,
03384 subimage[MaxTextExtent];
03385
03386 const MagicInfo
03387 *magic_info;
03388
03389 const MagickInfo
03390 *magick_info;
03391
03392 ExceptionInfo
03393 *sans_exception;
03394
03395 Image
03396 *image;
03397
03398 MagickBooleanType
03399 status;
03400
03401 register const char
03402 *p;
03403
03404 ssize_t
03405 count;
03406
03407 unsigned char
03408 magick[2*MaxTextExtent];
03409
03410
03411
03412
03413 assert(image_info != (ImageInfo *) NULL);
03414 assert(image_info->signature == MagickSignature);
03415 if (image_info->debug != MagickFalse)
03416 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03417 image_info->filename);
03418 *subimage='\0';
03419 GetPathComponent(image_info->filename,SubimagePath,subimage);
03420 if (*subimage != '\0')
03421 {
03422
03423
03424
03425 if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse)
03426 {
03427 if (IsGeometry(subimage) != MagickFalse)
03428 (void) CloneString(&image_info->extract,subimage);
03429 }
03430 else
03431 {
03432 unsigned long
03433 first,
03434 last;
03435
03436 (void) CloneString(&image_info->scenes,subimage);
03437 image_info->scene=(unsigned long) atol(image_info->scenes);
03438 image_info->number_scenes=image_info->scene;
03439 p=image_info->scenes;
03440 for (q=(char *) image_info->scenes; *q != '\0'; p++)
03441 {
03442 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
03443 p++;
03444 first=(unsigned long) strtol(p,&q,10);
03445 last=first;
03446 while (isspace((int) ((unsigned char) *q)) != 0)
03447 q++;
03448 if (*q == '-')
03449 last=(unsigned long) strtol(q+1,&q,10);
03450 if (first > last)
03451 Swap(first,last);
03452 if (first < image_info->scene)
03453 image_info->scene=first;
03454 if (last > image_info->number_scenes)
03455 image_info->number_scenes=last;
03456 p=q;
03457 }
03458 image_info->number_scenes-=image_info->scene-1;
03459 image_info->subimage=image_info->scene;
03460 image_info->subrange=image_info->number_scenes;
03461 }
03462 }
03463 *extension='\0';
03464 GetPathComponent(image_info->filename,ExtensionPath,extension);
03465 #if defined(MAGICKCORE_ZLIB_DELEGATE)
03466 if (*extension != '\0')
03467 if ((LocaleCompare(extension,"gz") == 0) ||
03468 (LocaleCompare(extension,"Z") == 0) ||
03469 (LocaleCompare(extension,"wmz") == 0))
03470 {
03471 char
03472 path[MaxTextExtent];
03473
03474 (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
03475 path[strlen(path)-strlen(extension)-1]='\0';
03476 GetPathComponent(path,ExtensionPath,extension);
03477 }
03478 #endif
03479 #if defined(MAGICKCORE_BZLIB_DELEGATE)
03480 if (*extension != '\0')
03481 if (LocaleCompare(extension,"bz2") == 0)
03482 {
03483 char
03484 path[MaxTextExtent];
03485
03486 (void) CopyMagickString(path,image_info->filename,MaxTextExtent);
03487 path[strlen(path)-strlen(extension)-1]='\0';
03488 GetPathComponent(path,ExtensionPath,extension);
03489 }
03490 #endif
03491 image_info->affirm=MagickFalse;
03492 sans_exception=AcquireExceptionInfo();
03493 if (*extension != '\0')
03494 {
03495 MagickFormatType
03496 format_type;
03497
03498 register long
03499 i;
03500
03501 static const char
03502 *format_type_formats[] =
03503 {
03504 "AUTOTRACE",
03505 "BROWSE",
03506 "DCRAW",
03507 "EDIT",
03508 "LAUNCH",
03509 "MPEG:DECODE",
03510 "MPEG:ENCODE",
03511 "PRINT",
03512 "PS:ALPHA",
03513 "PS:CMYK",
03514 "PS:COLOR",
03515 "PS:GRAY",
03516 "PS:MONO",
03517 "SCAN",
03518 "SHOW",
03519 "TMP",
03520 "WIN",
03521 (char *) NULL
03522 };
03523
03524
03525
03526
03527 (void) CopyMagickString(magic,extension,MaxTextExtent);
03528 LocaleUpper(magic);
03529
03530
03531
03532 format_type=UndefinedFormatType;
03533 i=0;
03534 while ((format_type != UndefinedFormatType) &&
03535 (format_type_formats[i] != (char *) NULL))
03536 {
03537 if ((*magic == *format_type_formats[i]) &&
03538 (LocaleCompare(magic,format_type_formats[i]) == 0))
03539 format_type=ExplicitFormatType;
03540 i++;
03541 }
03542 magick_info=GetMagickInfo(magic,sans_exception);
03543 if ((magick_info != (const MagickInfo *) NULL) &&
03544 (magick_info->format_type != UndefinedFormatType))
03545 format_type=magick_info->format_type;
03546 if (format_type == UndefinedFormatType)
03547 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03548 else
03549 if (format_type == ExplicitFormatType)
03550 {
03551 image_info->affirm=MagickTrue;
03552 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03553 }
03554 if (LocaleCompare(magic,"RGB") == 0)
03555 image_info->affirm=MagickFalse;
03556 }
03557
03558
03559
03560 *magic='\0';
03561 GetPathComponent(image_info->filename,MagickPath,magic);
03562 if (*magic == '\0')
03563 (void) CopyMagickString(magic,image_info->magick,MaxTextExtent);
03564 else
03565 {
03566
03567
03568
03569 LocaleUpper(magic);
03570 if (IsMagickConflict(magic) == MagickFalse)
03571 {
03572 (void) CopyMagickString(image_info->magick,magic,MaxTextExtent);
03573 if (LocaleCompare(magic,"TMP") != 0)
03574 image_info->affirm=MagickTrue;
03575 else
03576 image_info->temporary=MagickTrue;
03577 }
03578 }
03579 magick_info=GetMagickInfo(magic,sans_exception);
03580 sans_exception=DestroyExceptionInfo(sans_exception);
03581 if ((magick_info == (const MagickInfo *) NULL) ||
03582 (GetMagickEndianSupport(magick_info) == MagickFalse))
03583 image_info->endian=UndefinedEndian;
03584 GetPathComponent(image_info->filename,CanonicalPath,filename);
03585 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
03586 if (rectify != MagickFalse)
03587 {
03588
03589
03590
03591 (void) InterpretImageFilename(image_info,(Image *) NULL,
03592 image_info->filename,(int) image_info->scene,filename);
03593 if ((LocaleCompare(filename,image_info->filename) != 0) &&
03594 (strchr(filename,'%') == (char *) NULL))
03595 image_info->adjoin=MagickFalse;
03596 magick_info=GetMagickInfo(magic,exception);
03597 if (magick_info != (const MagickInfo *) NULL)
03598 if (GetMagickAdjoin(magick_info) == MagickFalse)
03599 image_info->adjoin=MagickFalse;
03600 return(MagickTrue);
03601 }
03602 if (image_info->affirm != MagickFalse)
03603 return(MagickTrue);
03604
03605
03606
03607 image=AcquireImage(image_info);
03608 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
03609 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
03610 if (status == MagickFalse)
03611 {
03612 image=DestroyImage(image);
03613 return(MagickFalse);
03614 }
03615 if ((IsBlobSeekable(image) == MagickFalse) ||
03616 (IsBlobExempt(image) != MagickFalse))
03617 {
03618
03619
03620
03621 *filename='\0';
03622 status=ImageToFile(image,filename,exception);
03623 (void) CloseBlob(image);
03624 if (status == MagickFalse)
03625 {
03626 image=DestroyImage(image);
03627 return(MagickFalse);
03628 }
03629 SetImageInfoFile(image_info,(FILE *) NULL);
03630 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
03631 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
03632 if (status == MagickFalse)
03633 {
03634 image=DestroyImage(image);
03635 return(MagickFalse);
03636 }
03637 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
03638 image_info->temporary=MagickTrue;
03639 }
03640 (void) ResetMagickMemory(magick,0,sizeof(magick));
03641 count=ReadBlob(image,2*MaxTextExtent,magick);
03642 (void) CloseBlob(image);
03643 image=DestroyImage(image);
03644
03645
03646
03647 sans_exception=AcquireExceptionInfo();
03648 magic_info=GetMagicInfo(magick,(size_t) count,sans_exception);
03649 if ((magic_info != (const MagicInfo *) NULL) &&
03650 (GetMagicName(magic_info) != (char *) NULL))
03651 {
03652 (void) CopyMagickString(image_info->magick,GetMagicName(magic_info),
03653 MaxTextExtent);
03654 magick_info=GetMagickInfo(image_info->magick,sans_exception);
03655 if ((magick_info == (const MagickInfo *) NULL) ||
03656 (GetMagickEndianSupport(magick_info) == MagickFalse))
03657 image_info->endian=UndefinedEndian;
03658 sans_exception=DestroyExceptionInfo(sans_exception);
03659 return(MagickTrue);
03660 }
03661 magick_info=GetMagickInfo(image_info->magick,sans_exception);
03662 if ((magick_info == (const MagickInfo *) NULL) ||
03663 (GetMagickEndianSupport(magick_info) == MagickFalse))
03664 image_info->endian=UndefinedEndian;
03665 sans_exception=DestroyExceptionInfo(sans_exception);
03666 return(MagickTrue);
03667 }
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696 MagickExport void SetImageInfoBlob(ImageInfo *image_info,const void *blob,
03697 const size_t length)
03698 {
03699 assert(image_info != (ImageInfo *) NULL);
03700 assert(image_info->signature == MagickSignature);
03701 if (image_info->debug != MagickFalse)
03702 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03703 image_info->filename);
03704 image_info->blob=(void *) blob;
03705 image_info->length=length;
03706 }
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732 MagickExport void SetImageInfoFile(ImageInfo *image_info,FILE *file)
03733 {
03734 assert(image_info != (ImageInfo *) NULL);
03735 assert(image_info->signature == MagickSignature);
03736 if (image_info->debug != MagickFalse)
03737 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
03738 image_info->filename);
03739 image_info->file=file;
03740 }
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767 MagickExport MagickBooleanType SetImageMask(Image *image,
03768 const Image *mask)
03769 {
03770 assert(image != (Image *) NULL);
03771 if (image->debug != MagickFalse)
03772 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03773 assert(image->signature == MagickSignature);
03774 if (mask != (const Image *) NULL)
03775 if ((mask->columns != image->columns) || (mask->rows != image->rows))
03776 ThrowBinaryException(ImageError,"ImageSizeDiffers",image->filename);
03777 if (image->mask != (Image *) NULL)
03778 image->mask=DestroyImage(image->mask);
03779 image->mask=NewImageList();
03780 if (mask == (Image *) NULL)
03781 return(MagickTrue);
03782 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
03783 return(MagickFalse);
03784 image->mask=CloneImage(mask,0,0,MagickTrue,&image->exception);
03785 if (image->mask == (Image *) NULL)
03786 return(MagickFalse);
03787 return(MagickTrue);
03788 }
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815 MagickExport MagickBooleanType SetImageOpacity(Image *image,
03816 const Quantum opacity)
03817 {
03818 ExceptionInfo
03819 *exception;
03820
03821 long
03822 y;
03823
03824 MagickBooleanType
03825 status;
03826
03827 ViewInfo
03828 *image_view;
03829
03830 assert(image != (Image *) NULL);
03831 if (image->debug != MagickFalse)
03832 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03833 assert(image->signature == MagickSignature);
03834 image->matte=opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
03835 status=MagickTrue;
03836 exception=(&image->exception);
03837 image_view=AcquireCacheView(image);
03838 #if defined(MAGICKCORE_OPENMP_SUPPORT)
03839 #pragma omp parallel for schedule(dynamic,4) shared(status)
03840 #endif
03841 for (y=0; y < (long) image->rows; y++)
03842 {
03843 register long
03844 x;
03845
03846 register PixelPacket
03847 *__restrict q;
03848
03849 if (status == MagickFalse)
03850 continue;
03851 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
03852 if (q == (PixelPacket *) NULL)
03853 {
03854 status=MagickFalse;
03855 continue;
03856 }
03857 for (x=0; x < (long) image->columns; x++)
03858 {
03859 q->opacity=opacity;
03860 q++;
03861 }
03862 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
03863 status=MagickFalse;
03864 }
03865 image_view=DestroyCacheView(image_view);
03866 return(status);
03867 }
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898 MagickExport MagickBooleanType SetImageType(Image *image,const ImageType type)
03899 {
03900 const char
03901 *artifact;
03902
03903 ImageInfo
03904 *image_info;
03905
03906 MagickBooleanType
03907 status;
03908
03909 QuantizeInfo
03910 *quantize_info;
03911
03912 assert(image != (Image *) NULL);
03913 if (image->debug != MagickFalse)
03914 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
03915 assert(image->signature == MagickSignature);
03916 status=MagickTrue;
03917 image_info=AcquireImageInfo();
03918 image_info->dither=image->dither;
03919 artifact=GetImageArtifact(image,"dither");
03920 if (artifact != (const char *) NULL)
03921 (void) SetImageOption(image_info,"dither",artifact);
03922 switch (type)
03923 {
03924 case BilevelType:
03925 {
03926 if (IsGrayImage(image,&image->exception) == MagickFalse)
03927 status=TransformImageColorspace(image,GRAYColorspace);
03928 if (IsMonochromeImage(image,&image->exception) == MagickFalse)
03929 {
03930 quantize_info=AcquireQuantizeInfo(image_info);
03931 quantize_info->number_colors=2;
03932 quantize_info->colorspace=GRAYColorspace;
03933 status=QuantizeImage(quantize_info,image);
03934 quantize_info=DestroyQuantizeInfo(quantize_info);
03935 }
03936 image->matte=MagickFalse;
03937 break;
03938 }
03939 case GrayscaleType:
03940 {
03941 if (IsGrayImage(image,&image->exception) == MagickFalse)
03942 status=TransformImageColorspace(image,GRAYColorspace);
03943 image->matte=MagickFalse;
03944 break;
03945 }
03946 case GrayscaleMatteType:
03947 {
03948 if (IsGrayImage(image,&image->exception) == MagickFalse)
03949 status=TransformImageColorspace(image,GRAYColorspace);
03950 if (image->matte == MagickFalse)
03951 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03952 break;
03953 }
03954 case PaletteType:
03955 {
03956 if (image->colorspace != RGBColorspace)
03957 status=TransformImageColorspace(image,RGBColorspace);
03958 if ((image->storage_class == DirectClass) || (image->colors > 256))
03959 {
03960 quantize_info=AcquireQuantizeInfo(image_info);
03961 quantize_info->number_colors=256;
03962 status=QuantizeImage(quantize_info,image);
03963 quantize_info=DestroyQuantizeInfo(quantize_info);
03964 }
03965 image->matte=MagickFalse;
03966 break;
03967 }
03968 case PaletteBilevelMatteType:
03969 {
03970 if (image->colorspace != RGBColorspace)
03971 status=TransformImageColorspace(image,RGBColorspace);
03972 if (image->matte == MagickFalse)
03973 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03974 (void) BilevelImageChannel(image,AlphaChannel,(double) QuantumRange/2.0);
03975 quantize_info=AcquireQuantizeInfo(image_info);
03976 status=QuantizeImage(quantize_info,image);
03977 quantize_info=DestroyQuantizeInfo(quantize_info);
03978 break;
03979 }
03980 case PaletteMatteType:
03981 {
03982 if (image->colorspace != RGBColorspace)
03983 status=TransformImageColorspace(image,RGBColorspace);
03984 if (image->matte == MagickFalse)
03985 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
03986 quantize_info=AcquireQuantizeInfo(image_info);
03987 quantize_info->colorspace=TransparentColorspace;
03988 status=QuantizeImage(quantize_info,image);
03989 quantize_info=DestroyQuantizeInfo(quantize_info);
03990 break;
03991 }
03992 case TrueColorType:
03993 {
03994 if (image->colorspace != RGBColorspace)
03995 status=TransformImageColorspace(image,RGBColorspace);
03996 if (image->storage_class != DirectClass)
03997 status=SetImageStorageClass(image,DirectClass);
03998 image->matte=MagickFalse;
03999 break;
04000 }
04001 case TrueColorMatteType:
04002 {
04003 if (image->colorspace != RGBColorspace)
04004 status=TransformImageColorspace(image,RGBColorspace);
04005 if (image->storage_class != DirectClass)
04006 status=SetImageStorageClass(image,DirectClass);
04007 if (image->matte == MagickFalse)
04008 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
04009 break;
04010 }
04011 case ColorSeparationType:
04012 {
04013 if (image->colorspace != CMYKColorspace)
04014 {
04015 if (image->colorspace != RGBColorspace)
04016 status=TransformImageColorspace(image,RGBColorspace);
04017 status=TransformImageColorspace(image,CMYKColorspace);
04018 }
04019 if (image->storage_class != DirectClass)
04020 status=SetImageStorageClass(image,DirectClass);
04021 image->matte=MagickFalse;
04022 break;
04023 }
04024 case ColorSeparationMatteType:
04025 {
04026 if (image->colorspace != CMYKColorspace)
04027 {
04028 if (image->colorspace != RGBColorspace)
04029 status=TransformImageColorspace(image,RGBColorspace);
04030 status=TransformImageColorspace(image,CMYKColorspace);
04031 }
04032 if (image->storage_class != DirectClass)
04033 status=SetImageStorageClass(image,DirectClass);
04034 if (image->matte == MagickFalse)
04035 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
04036 break;
04037 }
04038 case OptimizeType:
04039 case UndefinedType:
04040 break;
04041 }
04042 image->type=type;
04043 image_info=DestroyImageInfo(image_info);
04044 return(status);
04045 }
04046
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074 MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
04075 const VirtualPixelMethod virtual_pixel_method)
04076 {
04077 assert(image != (const Image *) NULL);
04078 assert(image->signature == MagickSignature);
04079 if (image->debug != MagickFalse)
04080 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
04081 return(SetPixelCacheVirtualMethod(image,virtual_pixel_method));
04082 }
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108 #if defined(__cplusplus) || defined(c_plusplus)
04109 extern "C" {
04110 #endif
04111
04112 static int IntensityCompare(const void *x,const void *y)
04113 {
04114 const PixelPacket
04115 *color_1,
04116 *color_2;
04117
04118 int
04119 intensity;
04120
04121 color_1=(const PixelPacket *) x;
04122 color_2=(const PixelPacket *) y;
04123 intensity=(int) PixelIntensityToQuantum(color_2)-
04124 (int) PixelIntensityToQuantum(color_1);
04125 return(intensity);
04126 }
04127
04128 #if defined(__cplusplus) || defined(c_plusplus)
04129 }
04130 #endif
04131
04132 MagickExport MagickBooleanType SortColormapByIntensity(Image *image)
04133 {
04134 ExceptionInfo
04135 *exception;
04136
04137 long
04138 y;
04139
04140 MagickBooleanType
04141 status;
04142
04143 register long
04144 i;
04145
04146 unsigned short
04147 *pixels;
04148
04149 ViewInfo
04150 *image_view;
04151
04152 assert(image != (Image *) NULL);
04153 if (image->debug != MagickFalse)
04154 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
04155 assert(image->signature == MagickSignature);
04156 if (image->storage_class != PseudoClass)
04157 return(MagickTrue);
04158
04159
04160
04161 pixels=(unsigned short *) AcquireQuantumMemory((size_t) image->colors,
04162 sizeof(*pixels));
04163 if (pixels == (unsigned short *) NULL)
04164 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
04165 image->filename);
04166
04167
04168
04169 #if defined(MAGICKCORE_OPENMP_SUPPORT)
04170 #pragma omp parallel for schedule(dynamic,4) shared(status)
04171 #endif
04172 for (i=0; i < (long) image->colors; i++)
04173 image->colormap[i].opacity=(IndexPacket) i;
04174
04175
04176
04177 qsort((void *) image->colormap,(size_t) image->colors,
04178 sizeof(*image->colormap),IntensityCompare);
04179
04180
04181
04182 #if defined(MAGICKCORE_OPENMP_SUPPORT)
04183 #pragma omp parallel for schedule(dynamic,4) shared(status)
04184 #endif
04185 for (i=0; i < (long) image->colors; i++)
04186 pixels[(long) image->colormap[i].opacity]=(unsigned short) i;
04187 status=MagickTrue;
04188 exception=(&image->exception);
04189 image_view=AcquireCacheView(image);
04190 for (y=0; y < (long) image->rows; y++)
04191 {
04192 IndexPacket
04193 index;
04194
04195 register long
04196 x;
04197
04198 register IndexPacket
04199 *__restrict indexes;
04200
04201 register PixelPacket
04202 *__restrict q;
04203
04204 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
04205 if (q == (PixelPacket *) NULL)
04206 {
04207 status=MagickFalse;
04208 continue;
04209 }
04210 indexes=GetCacheViewAuthenticIndexQueue(image_view);
04211 for (x=0; x < (long) image->columns; x++)
04212 {
04213 index=(IndexPacket) pixels[(long) indexes[x]];
04214 indexes[x]=index;
04215 *q++=image->colormap[(long) index];
04216 }
04217 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
04218 status=MagickFalse;
04219 if (status == MagickFalse)
04220 break;
04221 }
04222 image_view=DestroyCacheView(image_view);
04223 pixels=(unsigned short *) RelinquishMagickMemory(pixels);
04224 return(status);
04225 }
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249 MagickExport MagickBooleanType StripImage(Image *image)
04250 {
04251 assert(image != (Image *) NULL);
04252 if (image->debug != MagickFalse)
04253 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
04254 DestroyImageProfiles(image);
04255 (void) DeleteImageProperty(image,"comment");
04256 return(MagickTrue);
04257 }
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283 static inline IndexPacket PushColormapIndex(Image *image,
04284 const unsigned long index,MagickBooleanType *range_exception)
04285 {
04286 if (index < image->colors)
04287 return((IndexPacket) index);
04288 *range_exception=MagickTrue;
04289 return((IndexPacket) 0);
04290 }
04291
04292 MagickExport MagickBooleanType SyncImage(Image *image)
04293 {
04294 ExceptionInfo
04295 *exception;
04296
04297 long
04298 y;
04299
04300 MagickBooleanType
04301 range_exception,
04302 status;
04303
04304 ViewInfo
04305 *image_view;
04306
04307 assert(image != (Image *) NULL);
04308 if (image->debug != MagickFalse)
04309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
04310 assert(image->signature == MagickSignature);
04311 if (image->storage_class == DirectClass)
04312 return(MagickFalse);
04313 range_exception=MagickFalse;
04314 status=MagickTrue;
04315 exception=(&image->exception);
04316 image_view=AcquireCacheView(image);
04317 for (y=0; y < (long) image->rows; y++)
04318 {
04319 IndexPacket
04320 index;
04321
04322 PixelPacket
04323 pixel;
04324
04325 register IndexPacket
04326 *__restrict indexes;
04327
04328 register long
04329 x;
04330
04331 register PixelPacket
04332 *__restrict q;
04333
04334 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
04335 if (q == (PixelPacket *) NULL)
04336 {
04337 status=MagickFalse;
04338 continue;
04339 }
04340 indexes=GetCacheViewAuthenticIndexQueue(image_view);
04341 for (x=0; x < (long) image->columns; x++)
04342 {
04343 index=PushColormapIndex(image,(unsigned long) indexes[x],
04344 &range_exception);
04345 pixel=image->colormap[(long) index];
04346 q->red=pixel.red;
04347 q->green=pixel.green;
04348 q->blue=pixel.blue;
04349 q++;
04350 }
04351 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
04352 status=MagickFalse;
04353 if (status == MagickFalse)
04354 break;
04355 }
04356 image_view=DestroyCacheView(image_view);
04357 if (range_exception != MagickFalse)
04358 (void) ThrowMagickException(&image->exception,GetMagickModule(),
04359 CorruptImageError,"InvalidColormapIndex","`%s'",image->filename);
04360 return(status);
04361 }
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391 MagickExport MagickBooleanType SyncImagesSettings(ImageInfo *image_info,
04392 Image *images)
04393 {
04394 Image
04395 *image;
04396
04397 assert(image_info != (const ImageInfo *) NULL);
04398 assert(image_info->signature == MagickSignature);
04399 assert(images != (Image *) NULL);
04400 assert(images->signature == MagickSignature);
04401 if (images->debug != MagickFalse)
04402 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
04403 image=images;
04404 for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
04405 (void) SyncImageSettings(image_info,image);
04406 (void) DeleteImageOption(image_info,"page");
04407 return(MagickTrue);
04408 }
04409
04410 MagickExport MagickBooleanType SyncImageSettings(const ImageInfo *image_info,
04411 Image *image)
04412 {
04413 char
04414 property[MaxTextExtent];
04415
04416 const char
04417 *value,
04418 *option;
04419
04420 GeometryInfo
04421 geometry_info;
04422
04423 MagickStatusType
04424 flags;
04425
04426
04427
04428
04429 assert(image_info != (const ImageInfo *) NULL);
04430 assert(image_info->signature == MagickSignature);
04431 assert(image != (Image *) NULL);
04432 assert(image->signature == MagickSignature);
04433 if (image->debug != MagickFalse)
04434 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
04435 option=GetImageOption(image_info,"background");
04436 if (option != (const char *) NULL)
04437 (void) QueryColorDatabase(option,&image->background_color,
04438 &image->exception);
04439 option=GetImageOption(image_info,"bias");
04440 if (option != (const char *) NULL)
04441 image->bias=StringToDouble(option,QuantumRange);
04442 option=GetImageOption(image_info,"black-point-compensation");
04443 if (option != (const char *) NULL)
04444 image->black_point_compensation=(MagickBooleanType) ParseMagickOption(
04445 MagickBooleanOptions,MagickFalse,option);
04446 option=GetImageOption(image_info,"blue-primary");
04447 if (option != (const char *) NULL)
04448 {
04449 flags=ParseGeometry(option,&geometry_info);
04450 image->chromaticity.blue_primary.x=geometry_info.rho;
04451 image->chromaticity.blue_primary.y=geometry_info.sigma;
04452 if ((flags & SigmaValue) == 0)
04453 image->chromaticity.blue_primary.y=image->chromaticity.blue_primary.x;
04454 }
04455 option=GetImageOption(image_info,"bordercolor");
04456 if (option != (const char *) NULL)
04457 (void) QueryColorDatabase(option,&image->border_color,&image->exception);
04458 option=GetImageOption(image_info,"colors");
04459 if (option != (const char *) NULL)
04460 image->colors=(unsigned long) atol(option);
04461 option=GetImageOption(image_info,"compose");
04462 if (option != (const char *) NULL)
04463 image->compose=(CompositeOperator) ParseMagickOption(MagickComposeOptions,
04464 MagickFalse,option);
04465 option=GetImageOption(image_info,"compress");
04466 if (option != (const char *) NULL)
04467 image->compression=(CompressionType) ParseMagickOption(
04468 MagickCompressOptions,MagickFalse,option);
04469 option=GetImageOption(image_info,"debug");
04470 if (option != (const char *) NULL)
04471 image->debug=(MagickBooleanType) ParseMagickOption(MagickBooleanOptions,
04472 MagickFalse,option);
04473 option=GetImageOption(image_info,"delay");
04474 if (option != (const char *) NULL)
04475 {
04476 GeometryInfo
04477 geometry_info;
04478
04479 flags=ParseGeometry(option,&geometry_info);
04480 if ((flags & GreaterValue) != 0)
04481 {
04482 if (image->delay > (unsigned long) (geometry_info.rho+0.5))
04483 image->delay=(unsigned long) (geometry_info.rho+0.5);
04484 }
04485 else
04486 if ((flags & LessValue) != 0)
04487 {
04488 if (image->delay < (unsigned long) (geometry_info.rho+0.5))
04489 image->ticks_per_second=(long) (geometry_info.sigma+0.5);
04490 }
04491 else
04492 image->delay=(unsigned long) (geometry_info.rho+0.5);
04493 if ((flags & SigmaValue) != 0)
04494 image->ticks_per_second=(long) (geometry_info.sigma+0.5);
04495 }
04496 option=GetImageOption(image_info,"density");
04497 if (option != (const char *) NULL)
04498 {
04499 GeometryInfo
04500 geometry_info;
04501
04502
04503
04504
04505 flags=ParseGeometry(option,&geometry_info);
04506 image->x_resolution=geometry_info.rho;
04507 image->y_resolution=geometry_info.sigma;
04508 if ((flags & SigmaValue) == 0)
04509 image->y_resolution=image->x_resolution;
04510 }
04511 option=GetImageOption(image_info,"depth");
04512 if (option != (const char *) NULL)
04513 image->depth=(unsigned long) atol(option);
04514 option=GetImageOption(image_info,"dispose");
04515 if (option != (const char *) NULL)
04516 image->dispose=(DisposeType) ParseMagickOption(MagickDisposeOptions,
04517 MagickFalse,option);
04518 option=GetImageOption(image_info,"endian");
04519 if (option != (const char *) NULL)
04520 image->endian=(EndianType) ParseMagickOption(MagickEndianOptions,
04521 MagickFalse,option);
04522 if (image_info->extract != (char *) NULL)
04523 (void) ParseAbsoluteGeometry(image_info->extract,&image->extract_info);
04524 option=GetImageOption(image_info,"filter");
04525 if (option != (const char *) NULL)
04526 image->filter=(FilterTypes) ParseMagickOption(MagickFilterOptions,
04527 MagickFalse,option);
04528 option=GetImageOption(image_info,"fuzz");
04529 if (option != (const char *) NULL)
04530 image->fuzz=StringToDouble(option,QuantumRange);
04531 option=GetImageOption(image_info,"gravity");
04532 if (option != (const char *) NULL)
04533 image->gravity=(GravityType) ParseMagickOption(MagickGravityOptions,
04534 MagickFalse,option);
04535 option=GetImageOption(image_info,"green-primary");
04536 if (option != (const char *) NULL)
04537 {
04538 flags=ParseGeometry(option,&geometry_info);
04539 image->chromaticity.green_primary.x=geometry_info.rho;
04540 image->chromaticity.green_primary.y=geometry_info.sigma;
04541 if ((flags & SigmaValue) == 0)
04542 image->chromaticity.green_primary.y=image->chromaticity.green_primary.x;
04543 }
04544 option=GetImageOption(image_info,"intent");
04545 if (option != (const char *) NULL)
04546 image->rendering_intent=(RenderingIntent) ParseMagickOption(
04547 MagickIntentOptions,MagickFalse,option);
04548 option=GetImageOption(image_info,"interlace");
04549 if (option != (const char *) NULL)
04550 image->interlace=(InterlaceType) ParseMagickOption(MagickInterlaceOptions,
04551 MagickFalse,option);
04552 option=GetImageOption(image_info,"interpolate");
04553 if (option != (const char *) NULL)
04554 image->interpolate=(InterpolatePixelMethod) ParseMagickOption(
04555 MagickInterpolateOptions,MagickFalse,option);
04556 option=GetImageOption(image_info,"loop");
04557 if (option != (const char *) NULL)
04558 image->iterations=(unsigned long) atol(option);
04559 option=GetImageOption(image_info,"mattecolor");
04560 if (option != (const char *) NULL)
04561 (void) QueryColorDatabase(option,&image->matte_color,&image->exception);
04562 option=GetImageOption(image_info,"orient");
04563 if (option != (const char *) NULL)
04564 image->orientation=(OrientationType) ParseMagickOption(
04565 MagickOrientationOptions,MagickFalse,option);
04566 option=GetImageOption(image_info,"quality");
04567 if (option != (const char *) NULL)
04568 image->quality=(unsigned long) atol(option);
04569 option=GetImageOption(image_info,"page");
04570 if (option != (const char *) NULL)
04571 {
04572 char
04573 *geometry;
04574
04575 geometry=GetPageGeometry(option);
04576 flags=ParseAbsoluteGeometry(geometry,&image->page);
04577 geometry=DestroyString(geometry);
04578 }
04579 option=GetImageOption(image_info,"red-primary");
04580 if (option != (const char *) NULL)
04581 {
04582 flags=ParseGeometry(option,&geometry_info);
04583 image->chromaticity.red_primary.x=geometry_info.rho;
04584 image->chromaticity.red_primary.y=geometry_info.sigma;
04585 if ((flags & SigmaValue) == 0)
04586 image->chromaticity.red_primary.y=image->chromaticity.red_primary.x;
04587 }
04588 if (image_info->quality != UndefinedCompressionQuality)
04589 image->quality=image_info->quality;
04590 option=GetImageOption(image_info,"scene");
04591 if (option != (const char *) NULL)
04592 image->scene=(unsigned long) atol(option);
04593 option=GetImageOption(image_info,"taint");
04594 if (option != (const char *) NULL)
04595 image->taint=(MagickBooleanType) ParseMagickOption(MagickBooleanOptions,
04596 MagickFalse,option);
04597 option=GetImageOption(image_info,"tile-offset");
04598 if (option != (const char *) NULL)
04599 {
04600 char
04601 *geometry;
04602
04603 geometry=GetPageGeometry(option);
04604 flags=ParseAbsoluteGeometry(geometry,&image->tile_offset);
04605 geometry=DestroyString(geometry);
04606 }
04607 option=GetImageOption(image_info,"transparent-color");
04608 if (option != (const char *) NULL)
04609 (void) QueryColorDatabase(option,&image->transparent_color,
04610 &image->exception);
04611 option=GetImageOption(image_info,"type");
04612 if (option != (const char *) NULL)
04613 image->type=(ImageType) ParseMagickOption(MagickTypeOptions,MagickFalse,
04614 option);
04615 option=GetImageOption(image_info,"units");
04616 if (option != (const char *) NULL)
04617 image->units=(ResolutionType) ParseMagickOption(MagickResolutionOptions,
04618 MagickFalse,option);
04619 if (image_info->units != UndefinedResolution)
04620 {
04621 if (image->units != image_info->units)
04622 switch (image->units)
04623 {
04624 case PixelsPerInchResolution:
04625 {
04626 if (image_info->units == PixelsPerCentimeterResolution)
04627 {
04628 image->x_resolution/=2.54;
04629 image->y_resolution/=2.54;
04630 }
04631 break;
04632 }
04633 case PixelsPerCentimeterResolution:
04634 {
04635 if (image_info->units == PixelsPerInchResolution)
04636 {
04637 image->x_resolution*=2.54;
04638 image->y_resolution*=2.54;
04639 }
04640 break;
04641 }
04642 default:
04643 break;
04644 }
04645 image->units=image_info->units;
04646 }
04647 option=GetImageOption(image_info,"white-point");
04648 if (option != (const char *) NULL)
04649 {
04650 flags=ParseGeometry(option,&geometry_info);
04651 image->chromaticity.white_point.x=geometry_info.rho;
04652 image->chromaticity.white_point.y=geometry_info.sigma;
04653 if ((flags & SigmaValue) == 0)
04654 image->chromaticity.white_point.y=image->chromaticity.white_point.x;
04655 }
04656 ResetImageOptionIterator(image_info);
04657 for (option=GetNextImageOption(image_info); option != (const char *) NULL; )
04658 {
04659 value=GetImageOption(image_info,option);
04660 if (value != (const char *) NULL)
04661 {
04662 (void) FormatMagickString(property,MaxTextExtent,"%s",option);
04663 (void) SetImageArtifact(image,property,value);
04664 }
04665 option=GetNextImageOption(image_info);
04666 }
04667 return(MagickTrue);
04668 }
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695 MagickExport MagickBooleanType TextureImage(Image *image,const Image *texture)
04696 {
04697 #define TextureImageTag "Texture/Image"
04698
04699 ExceptionInfo
04700 *exception;
04701
04702 long
04703 progress,
04704 y;
04705
04706 MagickBooleanType
04707 status;
04708
04709 ViewInfo
04710 *image_view,
04711 *texture_view;
04712
04713 assert(image != (Image *) NULL);
04714 if (image->debug != MagickFalse)
04715 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
04716 assert(image->signature == MagickSignature);
04717 if (texture == (const Image *) NULL)
04718 return(MagickFalse);
04719 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
04720 return(MagickFalse);
04721
04722
04723
04724 status=MagickTrue;
04725 progress=0;
04726 exception=(&image->exception);
04727 image_view=AcquireCacheView(image);
04728 texture_view=AcquireCacheView(texture);
04729 (void) SetCacheViewVirtualPixelMethod(texture_view,TileVirtualPixelMethod);
04730 #if defined(MAGICKCORE_OPENMP_SUPPORT)
04731 #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
04732 #endif
04733 for (y=0; y < (long) image->rows; y++)
04734 {
04735 const PixelPacket
04736 *pixels;
04737
04738 MagickPixelPacket
04739 composite,
04740 source;
04741
04742 register long
04743 x;
04744
04745 register const IndexPacket
04746 *__restrict texture_indexes;
04747
04748 register const PixelPacket
04749 *__restrict p;
04750
04751 register IndexPacket
04752 *__restrict indexes;
04753
04754 register PixelPacket
04755 *__restrict q;
04756
04757 if (status == MagickFalse)
04758 continue;
04759 p=GetCacheViewVirtualPixels(texture_view,texture->tile_offset.x,(y+
04760 texture->tile_offset.y) % texture->rows,texture->columns,1,
04761 &image->exception);
04762 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
04763 exception);
04764 if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
04765 {
04766 status=MagickFalse;
04767 continue;
04768 }
04769 texture_indexes=GetCacheViewVirtualIndexQueue(texture_view);
04770 indexes=GetCacheViewAuthenticIndexQueue(image_view);
04771 if (image->matte != MagickFalse)
04772 {
04773 GetMagickPixelPacket(image,&source);
04774 GetMagickPixelPacket(texture,&composite);
04775 }
04776 pixels=p;
04777 for (x=0; x < (long) image->columns; x+=texture->columns)
04778 {
04779 register long
04780 z;
04781
04782 unsigned long
04783 width;
04784
04785 width=texture->columns;
04786 if ((unsigned long) (x+width) > image->columns)
04787 width=image->columns-x;
04788 p=pixels;
04789 if (image->matte == MagickFalse)
04790 {
04791 (void) CopyMagickMemory(q,p,width*sizeof(*p));
04792 q+=width;
04793 if ((indexes != (IndexPacket *) NULL) &&
04794 (texture_indexes != (IndexPacket *) NULL))
04795 {
04796 (void) CopyMagickMemory(indexes,texture_indexes,width*
04797 sizeof(*texture_indexes));
04798 indexes+=width;
04799 texture_indexes+=width;
04800 }
04801 }
04802 else
04803 for (z=0; z < (long) width; z++)
04804 {
04805 SetMagickPixelPacket(image,p,texture_indexes+x+z,&source);
04806 SetMagickPixelPacket(image,q,indexes+x+z,&composite);
04807 MagickPixelCompositeOver(&source,(texture->matte != MagickFalse ?
04808 source.opacity : OpaqueOpacity),&composite,(image->matte !=
04809 MagickFalse ? composite.opacity : OpaqueOpacity),&composite);
04810 SetPixelPacket(image,&composite,q,indexes+x+z);
04811 p++;
04812 q++;
04813 }
04814 }
04815 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
04816 status=MagickFalse;
04817 if (image->progress_monitor != (MagickProgressMonitor) NULL)
04818 {
04819 MagickBooleanType
04820 proceed;
04821
04822 #if defined(MAGICKCORE_OPENMP_SUPPORT)
04823 #pragma omp critical (MagickCore_TextureImage)
04824 #endif
04825 proceed=SetImageProgress(image,TextureImageTag,progress++,image->rows);
04826 if (proceed == MagickFalse)
04827 status=MagickFalse;
04828 }
04829 }
04830 texture_view=DestroyCacheView(texture_view);
04831 image_view=DestroyCacheView(image_view);
04832 return(status);
04833 }