From: cristy Date: Mon, 5 Mar 2012 19:18:42 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~6078 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c6437279e4a1b73d67b4f55738c5ed0a94f5a0e;p=imagemagick --- diff --git a/MagickCore/channel.c b/MagickCore/channel.c index 82fc69d8b..d114f0236 100644 --- a/MagickCore/channel.c +++ b/MagickCore/channel.c @@ -340,3 +340,370 @@ MagickExport Image *ChannelOperationImage(const Image *image, } return(destination_image); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% C o m b i n e I m a g e s % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% CombineImages() combines one or more images into a single image. The +% grayscale value of the pixels of each image in the sequence is assigned in +% order to the specified channels of the combined image. The typical +% ordering would be image 1 => Red, 2 => Green, 3 => Blue, etc. +% +% The format of the CombineImages method is: +% +% Image *CombineImages(const Image *image,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image: the image. +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport Image *CombineImages(const Image *image,ExceptionInfo *exception) +{ +#define CombineImageTag "Combine/Image" + + CacheView + *combine_view; + + Image + *combine_image; + + MagickBooleanType + status; + + MagickOffsetType + progress; + + ssize_t + y; + + /* + Ensure the image are the same size. + */ + assert(image != (const Image *) NULL); + assert(image->signature == MagickSignature); + if (image->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + combine_image=CloneImage(image,0,0,MagickTrue,exception); + if (combine_image == (Image *) NULL) + return((Image *) NULL); + if (SetImageStorageClass(combine_image,DirectClass,exception) == MagickFalse) + { + combine_image=DestroyImage(combine_image); + return((Image *) NULL); + } + if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) + combine_image->matte=MagickTrue; + /* + Combine images. + */ + status=MagickTrue; + progress=0; + combine_view=AcquireCacheView(combine_image); + for (y=0; y < (ssize_t) combine_image->rows; y++) + { + CacheView + *image_view; + + const Image + *next; + + Quantum + *pixels; + + register const Quantum + *restrict p; + + register Quantum + *restrict q; + + register ssize_t + i; + + if (status == MagickFalse) + continue; + pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns, + 1,exception); + if (pixels == (Quantum *) NULL) + { + status=MagickFalse; + continue; + } + next=image; + for (i=0; i < (ssize_t) GetPixelChannels(image); i++) + { + PixelChannel + channel; + + PixelTrait + combine_traits, + traits; + + register ssize_t + x; + + if (next == (Image *) NULL) + continue; + channel=GetPixelChannelMapChannel(image,i); + traits=GetPixelChannelMapTraits(image,channel); + combine_traits=GetPixelChannelMapTraits(combine_image,channel); + if ((traits == UndefinedPixelTrait) || + (combine_traits == UndefinedPixelTrait)) + continue; + image_view=AcquireCacheView(next); + p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception); + if (p == (const Quantum *) NULL) + continue; + q=pixels; + for (x=0; x < (ssize_t) combine_image->columns; x++) + { + if (x < (ssize_t) image->columns) + { + q[i]=GetPixelGray(image,p); + p+=GetPixelChannels(image); + } + q+=GetPixelChannels(combine_image); + } + image_view=DestroyCacheView(image_view); + next=GetNextImageInList(next); + if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse) + status=MagickFalse; + if (image->progress_monitor != (MagickProgressMonitor) NULL) + { + MagickBooleanType + proceed; + + proceed=SetImageProgress(image,CombineImageTag,progress++, + combine_image->rows); + if (proceed == MagickFalse) + status=MagickFalse; + } + } + } + combine_view=DestroyCacheView(combine_view); + if (status == MagickFalse) + combine_image=DestroyImage(combine_image); + return(combine_image); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S e p a r a t e I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% SeparateImage() separates a channel from the image and returns it as a +% grayscale image. +% +% The format of the SeparateImage method is: +% +% Image *SeparateImage(const Image *image,const ChannelType channel, +% ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image: the image. +% +% o channel: the image channel. +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport Image *SeparateImage(const Image *image, + const ChannelType channel_type,ExceptionInfo *exception) +{ +#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01) +#define SeparateImageTag "Separate/Image" + + CacheView + *image_view, + *separate_view; + + Image + *separate_image; + + MagickBooleanType + status; + + MagickOffsetType + progress; + + ssize_t + y; + + /* + Initialize spread image attributes. + */ + assert(image != (Image *) NULL); + assert(image->signature == MagickSignature); + if (image->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + separate_image=CloneImage(image,image->columns,image->rows,MagickTrue, + exception); + if (separate_image == (Image *) NULL) + return((Image *) NULL); + if (SetImageStorageClass(separate_image,DirectClass,exception) == MagickFalse) + { + separate_image=DestroyImage(separate_image); + return((Image *) NULL); + } + separate_image->colorspace=GRAYColorspace; + /* + Separate image. + */ + status=MagickTrue; + progress=0; + image_view=AcquireCacheView(image); + separate_view=AcquireCacheView(separate_image); +#if defined(MAGICKCORE_OPENMP_SUPPORT) + #pragma omp parallel for schedule(static) shared(progress,status) +#endif + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *restrict p; + + register Quantum + *restrict q; + + register ssize_t + x; + + if (status == MagickFalse) + continue; + p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); + q=QueueCacheViewAuthenticPixels(separate_view,0,y,separate_image->columns,1, + exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + { + status=MagickFalse; + continue; + } + for (x=0; x < (ssize_t) image->columns; x++) + { + register ssize_t + i; + + if (GetPixelMask(image,p) != 0) + { + p+=GetPixelChannels(image); + q+=GetPixelChannels(separate_image); + continue; + } + SetPixelChannel(separate_image,GrayPixelChannel,0,q); + for (i=0; i < (ssize_t) GetPixelChannels(image); i++) + { + PixelChannel + channel; + + PixelTrait + traits; + + channel=GetPixelChannelMapChannel(image,i); + traits=GetPixelChannelMapTraits(image,channel); + if ((traits == UndefinedPixelTrait) || + (GetChannelBit(channel_type,channel) == 0)) + continue; + SetPixelChannel(separate_image,GrayPixelChannel,p[i],q); + } + p+=GetPixelChannels(image); + q+=GetPixelChannels(separate_image); + } + if (SyncCacheViewAuthenticPixels(separate_view,exception) == MagickFalse) + status=MagickFalse; + if (image->progress_monitor != (MagickProgressMonitor) NULL) + { + MagickBooleanType + proceed; + +#if defined(MAGICKCORE_OPENMP_SUPPORT) + #pragma omp critical (MagickCore_SeparateImage) +#endif + proceed=SetImageProgress(image,SeparateImageTag,progress++,image->rows); + if (proceed == MagickFalse) + status=MagickFalse; + } + } + separate_view=DestroyCacheView(separate_view); + image_view=DestroyCacheView(image_view); + return(separate_image); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S e p a r a t e I m a g e s % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% SeparateImages() returns a separate grayscale image for each channel +% specified. +% +% The format of the SeparateImages method is: +% +% MagickBooleanType SeparateImages(const Image *image, +% ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image: the image. +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport Image *SeparateImages(const Image *image,ExceptionInfo *exception) +{ + Image + *images, + *separate_image; + + register ssize_t + i; + + assert(image != (Image *) NULL); + assert(image->signature == MagickSignature); + if (image->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); + images=NewImageList(); + for (i=0; i < (ssize_t) GetPixelChannels(image); i++) + { + PixelChannel + channel; + + PixelTrait + traits; + + channel=GetPixelChannelMapChannel(image,i); + traits=GetPixelChannelMapTraits(image,channel); + if ((traits == UndefinedPixelTrait) || + ((traits & UpdatePixelTrait) == 0)) + continue; + separate_image=SeparateImage(image,(ChannelType) (1 << channel),exception); + if (separate_image != (Image *) NULL) + AppendImageToList(&images,separate_image); + } + return(images); +}