/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e l i n q u i s h V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RelinquishVirtualMemory() frees memory acquired with AcquireVirtualMemory(). % % The format of the RelinquishVirtualMemory method is: % % MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info) % % A description of each parameter follows: % % o memory_info: A pointer to a block of memory to free for reuse. % */ MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info) { assert(memory_info != (MemoryInfo *) NULL); assert(memory_info->signature == MagickSignature); if (memory_info->blob != (void *) NULL) switch (memory_info->type) { case AlignedVirtualMemory: { memory_info->blob=RelinquishAlignedMemory(memory_info->blob); RelinquishMagickResource(MemoryResource,memory_info->length); break; } case MapVirtualMemory: { (void) UnmapBlob(memory_info->blob,memory_info->length); memory_info->blob=NULL; RelinquishMagickResource(MapResource,memory_info->length); if (*memory_info->filename != '\0') (void) RelinquishUniqueFileResource(memory_info->filename); break; } case UnalignedVirtualMemory: default: { memory_info->blob=RelinquishMagickMemory(memory_info->blob); break; } } memory_info->signature=(~MagickSignature); memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info); return(memory_info); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A l l o c a t e S e m a p h o r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AllocateSemaphoreInfo() initializes the SemaphoreInfo structure. % % The format of the AllocateSemaphoreInfo method is: % % SemaphoreInfo *AllocateSemaphoreInfo(void) % */ MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void) { SemaphoreInfo *semaphore_info; /* Allocate semaphore. */ semaphore_info=(SemaphoreInfo *) AcquireAlignedMemory(1, sizeof(SemaphoreInfo)); if (semaphore_info == (SemaphoreInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(semaphore_info,0,sizeof(SemaphoreInfo)); /* Initialize the semaphore. */ #if defined(MAGICKCORE_HAVE_PTHREAD) { int status; pthread_mutexattr_t mutex_info; status=pthread_mutexattr_init(&mutex_info); if (status != 0) { semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory( semaphore_info); ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } status=pthread_mutex_init(&semaphore_info->mutex,&mutex_info); (void) pthread_mutexattr_destroy(&mutex_info); if (status != 0) { semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory( semaphore_info); ThrowFatalException(ResourceLimitFatalError, "UnableToInitializeSemaphore"); } } #elif defined(MAGICKORE_HAVE_WINTHREADS) InitializeCriticalSection(&semaphore_info->mutex); #endif semaphore_info->id=GetMagickThreadId(); semaphore_info->reference_count=0; semaphore_info->signature=MagickSignature; return(semaphore_info); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s t r o y S e m a p h o r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DestroySemaphoreInfo() destroys a semaphore. % % The format of the DestroySemaphoreInfo method is: % % void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info) % % A description of each parameter follows: % % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure. % */ MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info) { assert(semaphore_info != (SemaphoreInfo **) NULL); assert((*semaphore_info) != (SemaphoreInfo *) NULL); assert((*semaphore_info)->signature == MagickSignature); LockMagickMutex(); #if defined(MAGICKCORE_HAVE_PTHREAD) { int status; status=pthread_mutex_destroy(&(*semaphore_info)->mutex); if (status != 0) { errno=status; ThrowFatalException(ResourceLimitFatalError,"UnableToDestroySemaphore"); } } #elif defined(MAGICKCORE_HAVE_WINTHREADS) DeleteCriticalSection(&(*semaphore_info)->mutex); #endif (*semaphore_info)->signature=(~MagickSignature); *semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory(*semaphore_info); UnlockMagickMutex(); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s t r o y C a c h e V i e w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DestroyCacheView() destroys the specified view returned by a previous call % to AcquireVirtualCacheView(). % % The format of the DestroyCacheView method is: % % CacheView *DestroyCacheView(CacheView *cache_view) % % A description of each parameter follows: % % o cache_view: the cache view. % */ MagickExport CacheView *DestroyCacheView(CacheView *cache_view) { assert(cache_view != (CacheView *) NULL); assert(cache_view->signature == MagickSignature); if (cache_view->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", cache_view->image->filename); if (cache_view->nexus_info != (NexusInfo **) NULL) cache_view->nexus_info=DestroyPixelCacheNexus(cache_view->nexus_info, cache_view->number_threads); cache_view->image=DestroyImage(cache_view->image); cache_view->signature=(~MagickSignature); cache_view=(CacheView *) RelinquishAlignedMemory(cache_view); return(cache_view); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e l i n q u i s h V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RelinquishVirtualMemory() frees memory acquired with AcquireVirtualMemory(). % % The format of the RelinquishVirtualMemory method is: % % MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info) % % A description of each parameter follows: % % o memory_info: A pointer to a block of memory to free for reuse. % */ MagickExport MemoryInfo *RelinquishVirtualMemory(MemoryInfo *memory_info) { assert(memory_info != (MemoryInfo *) NULL); assert(memory_info->signature == MagickSignature); if (memory_info->blob != (void *) NULL) { if (memory_info->mapped == MagickFalse) memory_info->blob=RelinquishMagickMemory(memory_info->blob); else { (void) UnmapBlob(memory_info->blob,memory_info->length); memory_info->blob=NULL; if (*memory_info->filename != '\0') (void) RelinquishUniqueFileResource(memory_info->filename); } } memory_info->signature=(~MagickSignature); memory_info=(MemoryInfo *) RelinquishAlignedMemory(memory_info); return(memory_info); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s t r o y S e m a p h o r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DestroySemaphoreInfo() destroys a semaphore. % % The format of the DestroySemaphoreInfo method is: % % void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info) % % A description of each parameter follows: % % o semaphore_info: Specifies a pointer to an SemaphoreInfo structure. % */ MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info) { assert(semaphore_info != (SemaphoreInfo **) NULL); assert((*semaphore_info) != (SemaphoreInfo *) NULL); assert((*semaphore_info)->signature == MagickSignature); #if defined(MAGICKCORE_HAVE_PTHREAD) (void) pthread_mutex_lock(&semaphore_mutex); #elif defined(MAGICKORE_HAVE_WINTHREADS) while (InterlockedCompareExchange(&semaphore_mutex,1L,0L) != 0) Sleep(10); #endif #if defined(MAGICKCORE_HAVE_PTHREAD) (void) pthread_mutex_destroy(&(*semaphore_info)->mutex); #elif defined(MAGICKORE_HAVE_WINTHREADS) DeleteCriticalSection(&(*semaphore_info)->mutex); #endif (*semaphore_info)->signature=(~MagickSignature); *semaphore_info=(SemaphoreInfo *) RelinquishAlignedMemory(*semaphore_info); #if defined(MAGICKCORE_HAVE_PTHREAD) (void) pthread_mutex_unlock(&semaphore_mutex); #elif defined(MAGICKORE_HAVE_WINTHREADS) InterlockedExchange(&semaphore_mutex,0L); #endif }
static MagickBooleanType ForwardFourierTransformChannel(const Image *image, const ChannelType channel,const MagickBooleanType modulus, Image *fourier_image,ExceptionInfo *exception) { double *magnitude, *phase; fftw_complex *fourier; MagickBooleanType status; FourierInfo fourier_info; size_t extent; fourier_info.width=image->columns; if ((image->columns != image->rows) || ((image->columns % 2) != 0) || ((image->rows % 2) != 0)) { extent=image->columns < image->rows ? image->rows : image->columns; fourier_info.width=(extent & 0x01) == 1 ? extent+1UL : extent; } fourier_info.height=fourier_info.width; fourier_info.center=(long) floor((double) fourier_info.width/2.0)+1L; fourier_info.channel=channel; fourier_info.modulus=modulus; magnitude=(double *) AcquireQuantumMemory((size_t) fourier_info.height, fourier_info.center*sizeof(*magnitude)); if (magnitude == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(MagickFalse); } phase=(double *) AcquireQuantumMemory((size_t) fourier_info.height, fourier_info.center*sizeof(*phase)); if (phase == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); magnitude=(double *) RelinquishMagickMemory(magnitude); return(MagickFalse); } fourier=(fftw_complex *) AcquireAlignedMemory((size_t) fourier_info.height, fourier_info.center*sizeof(*fourier)); if (fourier == (fftw_complex *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); phase=(double *) RelinquishMagickMemory(phase); magnitude=(double *) RelinquishMagickMemory(magnitude); return(MagickFalse); } status=ForwardFourierTransform(&fourier_info,image,magnitude,phase,exception); if (status != MagickFalse) status=ForwardFourier(&fourier_info,fourier_image,magnitude,phase, exception); fourier=(fftw_complex *) RelinquishAlignedMemory(fourier); phase=(double *) RelinquishMagickMemory(phase); magnitude=(double *) RelinquishMagickMemory(magnitude); return(status); }
static MagickBooleanType ForwardFourierTransform(FourierInfo *fourier_info, const Image *image,double *magnitude,double *phase,ExceptionInfo *exception) { CacheView *image_view; double n, *source; fftw_complex *fourier; fftw_plan fftw_r2c_plan; long y; register const IndexPacket *indexes; register const PixelPacket *p; register long i, x; /* Generate the forward Fourier transform. */ source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*source)); if (source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(MagickFalse); } ResetMagickMemory(source,0,fourier_info->width*fourier_info->height* sizeof(*source)); i=0L; image_view=AcquireCacheView(image); for (y=0L; y < (long) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(image_view,0L,y,fourier_info->width,1UL, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0L; x < (long) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { source[i]=QuantumScale*GetRedPixelComponent(p); break; } case GreenChannel: { source[i]=QuantumScale*GetGreenPixelComponent(p); break; } case BlueChannel: { source[i]=QuantumScale*GetBluePixelComponent(p); break; } case OpacityChannel: { source[i]=QuantumScale*GetOpacityPixelComponent(p); break; } case IndexChannel: { source[i]=QuantumScale*indexes[x]; break; } case GrayChannels: { source[i]=QuantumScale*GetRedPixelComponent(p); break; } } i++; p++; } } image_view=DestroyCacheView(image_view); fourier=(fftw_complex *) AcquireAlignedMemory((size_t) fourier_info->height, fourier_info->center*sizeof(*fourier)); if (fourier == (fftw_complex *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); source=(double *) RelinquishMagickMemory(source); return(MagickFalse); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_ForwardFourierTransform) #endif fftw_r2c_plan=fftw_plan_dft_r2c_2d(fourier_info->width,fourier_info->width, source,fourier,FFTW_ESTIMATE); fftw_execute(fftw_r2c_plan); fftw_destroy_plan(fftw_r2c_plan); source=(double *) RelinquishMagickMemory(source); /* Normalize Fourier transform. */ n=(double) fourier_info->width*(double) fourier_info->width; i=0L; for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) fourier[i++]/=n; /* Generate magnitude and phase (or real and imaginary). */ i=0L; if (fourier_info->modulus != MagickFalse) for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) { magnitude[i]=cabs(fourier[i]); phase[i]=carg(fourier[i]); i++; } else for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) { magnitude[i]=creal(fourier[i]); phase[i]=cimag(fourier[i]); i++; } fourier=(fftw_complex *) RelinquishAlignedMemory(fourier); return(MagickTrue); }