65 #if defined(MAGICKCORE_FFTW_DELEGATE) 66 #if defined(MAGICKCORE_HAVE_COMPLEX_H) 70 #if !defined(MAGICKCORE_HAVE_CABS) 71 #define cabs(z) (sqrt(z[0]*z[0]+z[1]*z[1])) 73 #if !defined(MAGICKCORE_HAVE_CARG) 74 #define carg(z) (atan2(cimag(z),creal(z))) 76 #if !defined(MAGICKCORE_HAVE_CIMAG) 77 #define cimag(z) (z[1]) 79 #if !defined(MAGICKCORE_HAVE_CREAL) 80 #define creal(z) (z[0]) 133 #define ComplexImageTag "Complex/Image" 175 assert(images != (
Image *) NULL);
184 "ImageSequenceRequired",
"`%s'",images->
filename);
185 return((
Image *) NULL);
188 if (image == (
Image *) NULL)
189 return((
Image *) NULL);
199 if (image == (
Image *) NULL)
202 return(complex_images);
209 return(complex_images);
216 if (artifact != (
const char *) NULL)
219 Ai_image=images->
next;
221 Bi_image=images->
next;
228 Cr_image=complex_images;
229 Ci_image=complex_images->
next;
244 #if defined(MAGICKCORE_OPENMP_SUPPORT) 245 #pragma omp parallel for schedule(static) shared(progress,status) \ 246 magick_number_threads(Cr_image,complex_images,rows,1L) 248 for (y=0; y < (ssize_t) rows; y++)
271 if ((Ar == (
const Quantum *) NULL) || (Ai == (
const Quantum *) NULL) ||
272 (Br == (
const Quantum *) NULL) || (Bi == (
const Quantum *) NULL) ||
278 for (x=0; x < (ssize_t) columns; x++)
283 for (i=0; i < (ssize_t) number_channels; i++)
314 Ci[i]=atan2((
double) Ai[i],(
double) Ar[i])/(2.0*
MagickPI)+0.5;
325 Cr[i]=Ar[i]*cos(2.0*
MagickPI*(Ai[i]-0.5));
326 Ci[i]=Ar[i]*sin(2.0*
MagickPI*(Ai[i]-0.5));
353 #if defined(MAGICKCORE_OPENMP_SUPPORT) 370 return(complex_images);
404 #if defined(MAGICKCORE_FFTW_DELEGATE) 407 const ssize_t x_offset,
const ssize_t y_offset,
double *roll_pixels)
432 for (y=0L; y < (ssize_t) height; y++)
435 v=((y+y_offset) < 0L) ? y+y_offset+(ssize_t) height : y+y_offset;
437 v=((y+y_offset) > ((ssize_t) height-1L)) ? y+y_offset-(ssize_t) height :
439 for (x=0L; x < (ssize_t) width; x++)
442 u=((x+x_offset) < 0L) ? x+x_offset+(ssize_t) width : x+x_offset;
444 u=((x+x_offset) > ((ssize_t) width-1L)) ? x+x_offset-(ssize_t) width :
446 source_pixels[v*width+u]=roll_pixels[i++];
449 (void) memcpy(roll_pixels,source_pixels,height*width*
450 sizeof(*source_pixels));
456 const size_t height,
double *source_pixels,
double *forward_pixels)
471 center=(ssize_t) (width/2L)+1L;
472 status=RollFourier((
size_t) center,height,0L,(ssize_t) height/2L,
476 for (y=0L; y < (ssize_t) height; y++)
477 for (x=0L; x < (ssize_t) (width/2L); x++)
478 forward_pixels[y*width+x+width/2L]=source_pixels[y*center+x];
479 for (y=1; y < (ssize_t) height; y++)
480 for (x=0L; x < (ssize_t) (width/2L); x++)
481 forward_pixels[(height-y)*width+width/2L-x-1L]=
482 source_pixels[y*center+x+1L];
483 for (x=0L; x < (ssize_t) (width/2L); x++)
484 forward_pixels[width/2L-x-1L]=source_pixels[x+1L];
488 static void CorrectPhaseLHS(
const size_t width,
const size_t height,
489 double *fourier_pixels)
497 for (y=0L; y < (ssize_t) height; y++)
498 for (x=0L; x < (ssize_t) (width/2L); x++)
499 fourier_pixels[y*width+x]*=(-1.0);
536 if (phase_image == (
Image *) NULL)
539 "ImageSequenceRequired",
"`%s'",image->
filename);
546 fourier_info->
height*
sizeof(*magnitude_pixels));
548 fourier_info->
height*
sizeof(*phase_pixels));
549 if ((magnitude_info == (
MemoryInfo *) NULL) ||
561 (void) memset(magnitude_pixels,0,fourier_info->
width*
562 fourier_info->
height*
sizeof(*magnitude_pixels));
564 (void) memset(phase_pixels,0,fourier_info->
width*
565 fourier_info->
height*
sizeof(*phase_pixels));
566 status=ForwardQuadrantSwap(fourier_info->
width,fourier_info->
height,
567 magnitude,magnitude_pixels);
569 status=ForwardQuadrantSwap(fourier_info->
width,fourier_info->
height,phase,
571 CorrectPhaseLHS(fourier_info->
width,fourier_info->
height,phase_pixels);
575 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
576 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
579 phase_pixels[i]+=0.5;
585 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
591 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
599 magnitude_pixels[i]),q);
605 magnitude_pixels[i]),q);
611 magnitude_pixels[i]),q);
617 magnitude_pixels[i]),q);
623 magnitude_pixels[i]),q);
637 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
643 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
693 const Image *image,
double *magnitude_pixels,
double *phase_pixels,
729 fourier_info->
height*
sizeof(*source_pixels));
737 memset(source_pixels,0,fourier_info->
width*fourier_info->
height*
738 sizeof(*source_pixels));
741 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
745 if (p == (
const Quantum *) NULL)
747 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
784 (fourier_info->
height/2+1)*
sizeof(*forward_pixels));
793 #if defined(MAGICKCORE_OPENMP_SUPPORT) 794 #pragma omp critical (MagickCore_ForwardFourierTransform) 796 fftw_r2c_plan=fftw_plan_dft_r2c_2d(fourier_info->
width,fourier_info->
height,
797 source_pixels,forward_pixels,FFTW_ESTIMATE);
798 fftw_execute_dft_r2c(fftw_r2c_plan,source_pixels,forward_pixels);
799 fftw_destroy_plan(fftw_r2c_plan);
802 if ((value == (
const char *) NULL) || (
LocaleCompare(value,
"forward") == 0))
813 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
814 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
816 #if defined(MAGICKCORE_HAVE_COMPLEX_H) 817 forward_pixels[i]*=gamma;
819 forward_pixels[i][0]*=gamma;
820 forward_pixels[i][1]*=gamma;
830 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
831 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
833 magnitude_pixels[i]=cabs(forward_pixels[i]);
834 phase_pixels[i]=carg(forward_pixels[i]);
838 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
839 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
841 magnitude_pixels[i]=creal(forward_pixels[i]);
842 phase_pixels[i]=cimag(forward_pixels[i]);
870 ((image->
rows % 2) != 0))
873 fourier_info.
width=(extent & 0x01) == 1 ? extent+1UL : extent;
876 fourier_info.
center=(ssize_t) (fourier_info.
width/2L)+1L;
880 (fourier_info.
height/2+1)*
sizeof(*magnitude_pixels));
882 (fourier_info.
height/2+1)*
sizeof(*phase_pixels));
883 if ((magnitude_info == (
MemoryInfo *) NULL) ||
896 status=ForwardFourierTransform(&fourier_info,image,magnitude_pixels,
897 phase_pixels,exception);
899 status=ForwardFourier(&fourier_info,fourier_image,magnitude_pixels,
900 phase_pixels,exception);
914 #if !defined(MAGICKCORE_FFTW_DELEGATE) 931 ((image->
rows % 2) != 0))
935 width=(extent & 0x01) == 1 ? extent+1UL : extent;
939 if (magnitude_image != (
Image *) NULL)
945 magnitude_image->
depth=32UL;
947 if (phase_image == (
Image *) NULL)
956 phase_image->
depth=32UL;
961 #if defined(MAGICKCORE_OPENMP_SUPPORT) 962 #pragma omp parallel sections 965 #if defined(MAGICKCORE_OPENMP_SUPPORT) 973 thread_status=ForwardFourierTransformChannel(image,
976 thread_status=ForwardFourierTransformChannel(image,
979 status=thread_status;
981 #if defined(MAGICKCORE_OPENMP_SUPPORT) 990 thread_status=ForwardFourierTransformChannel(image,
993 status=thread_status;
995 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1004 thread_status=ForwardFourierTransformChannel(image,
1007 status=thread_status;
1009 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1018 thread_status=ForwardFourierTransformChannel(image,
1021 status=thread_status;
1023 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1032 thread_status=ForwardFourierTransformChannel(image,
1035 status=thread_status;
1045 return(fourier_image);
1082 #if defined(MAGICKCORE_FFTW_DELEGATE) 1084 const size_t height,
const double *source,
double *destination)
1096 center=(ssize_t) (width/2L)+1L;
1097 for (y=1L; y < (ssize_t) height; y++)
1098 for (x=0L; x < (ssize_t) (width/2L+1L); x++)
1099 destination[(height-y)*center-x+width/2L]=source[y*width+x];
1100 for (y=0L; y < (ssize_t) height; y++)
1101 destination[y*center]=source[y*width+width/2L];
1102 for (x=0L; x < center; x++)
1103 destination[x]=source[center-x-1L];
1104 return(RollFourier(center,height,0L,(ssize_t) height/-2L,destination));
1108 const Image *magnitude_image,
const Image *phase_image,
1142 fourier_info->
height*
sizeof(*magnitude_pixels));
1144 fourier_info->
height*
sizeof(*phase_pixels));
1146 (fourier_info->
height/2+1)*
sizeof(*inverse_pixels));
1147 if ((magnitude_info == (
MemoryInfo *) NULL) ||
1167 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1171 if (p == (
const Quantum *) NULL)
1173 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
1175 switch (fourier_info->
channel)
1209 status=InverseQuadrantSwap(fourier_info->
width,fourier_info->
height,
1210 magnitude_pixels,inverse_pixels);
1211 (void) memcpy(magnitude_pixels,inverse_pixels,fourier_info->
height*
1212 fourier_info->
center*
sizeof(*magnitude_pixels));
1215 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1219 if (p == (
const Quantum *) NULL)
1221 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
1223 switch (fourier_info->
channel)
1259 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1260 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
1262 phase_pixels[i]-=0.5;
1268 CorrectPhaseLHS(fourier_info->
width,fourier_info->
height,phase_pixels);
1270 status=InverseQuadrantSwap(fourier_info->
width,fourier_info->
height,
1271 phase_pixels,inverse_pixels);
1272 (void) memcpy(phase_pixels,inverse_pixels,fourier_info->
height*
1273 fourier_info->
center*
sizeof(*phase_pixels));
1280 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1281 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
1283 #if defined(MAGICKCORE_HAVE_COMPLEX_H) 1284 fourier_pixels[i]=magnitude_pixels[i]*cos(phase_pixels[i])+I*
1285 magnitude_pixels[i]*sin(phase_pixels[i]);
1287 fourier_pixels[i][0]=magnitude_pixels[i]*cos(phase_pixels[i]);
1288 fourier_pixels[i][1]=magnitude_pixels[i]*sin(phase_pixels[i]);
1293 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1294 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
1296 #if defined(MAGICKCORE_HAVE_COMPLEX_H) 1297 fourier_pixels[i]=magnitude_pixels[i]+I*phase_pixels[i];
1299 fourier_pixels[i][0]=magnitude_pixels[i];
1300 fourier_pixels[i][1]=phase_pixels[i];
1338 fourier_info->
height*
sizeof(*source_pixels));
1358 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1359 for (x=0L; x < (ssize_t) fourier_info->
center; x++)
1361 #if defined(MAGICKCORE_HAVE_COMPLEX_H) 1362 fourier_pixels[i]*=gamma;
1364 fourier_pixels[i][0]*=gamma;
1365 fourier_pixels[i][1]*=gamma;
1370 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1371 #pragma omp critical (MagickCore_InverseFourierTransform) 1373 fftw_c2r_plan=fftw_plan_dft_c2r_2d(fourier_info->
width,fourier_info->
height,
1374 fourier_pixels,source_pixels,FFTW_ESTIMATE);
1375 fftw_execute_dft_c2r(fftw_c2r_plan,fourier_pixels,source_pixels);
1376 fftw_destroy_plan(fftw_c2r_plan);
1379 for (y=0L; y < (ssize_t) fourier_info->
height; y++)
1381 if (y >= (ssize_t) image->
rows)
1387 for (x=0L; x < (ssize_t) fourier_info->
width; x++)
1389 if (x < (ssize_t) image->
columns)
1390 switch (fourier_info->
channel)
1435 const Image *magnitude_image,
const Image *phase_image,
1453 if ((magnitude_image->
columns != magnitude_image->
rows) ||
1454 ((magnitude_image->
columns % 2) != 0) ||
1455 ((magnitude_image->
rows % 2) != 0))
1457 size_t extent=magnitude_image->
columns < magnitude_image->
rows ?
1459 fourier_info.
width=(extent & 0x01) == 1 ? extent+1UL : extent;
1462 fourier_info.
center=(ssize_t) (fourier_info.
width/2L)+1L;
1466 (fourier_info.
height/2+1)*
sizeof(*inverse_pixels));
1475 status=InverseFourier(&fourier_info,magnitude_image,phase_image,
1476 inverse_pixels,exception);
1478 status=InverseFourierTransform(&fourier_info,inverse_pixels,fourier_image,
1492 assert(magnitude_image != (
Image *) NULL);
1497 if (phase_image == (
Image *) NULL)
1500 "ImageSequenceRequired",
"`%s'",magnitude_image->
filename);
1501 return((
Image *) NULL);
1503 #if !defined(MAGICKCORE_FFTW_DELEGATE) 1504 fourier_image=(
Image *) NULL;
1513 if (fourier_image != (
Image *) NULL)
1523 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1524 #pragma omp parallel sections 1527 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1535 thread_status=InverseFourierTransformChannel(magnitude_image,
1538 thread_status=InverseFourierTransformChannel(magnitude_image,
1541 status=thread_status;
1543 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1552 thread_status=InverseFourierTransformChannel(magnitude_image,
1555 status=thread_status;
1557 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1566 thread_status=InverseFourierTransformChannel(magnitude_image,
1569 status=thread_status;
1571 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1580 thread_status=InverseFourierTransformChannel(magnitude_image,
1583 status=thread_status;
1585 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1594 thread_status=InverseFourierTransformChannel(magnitude_image,
1597 status=thread_status;
1606 return(fourier_image);
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
MagickExport MemoryInfo * RelinquishVirtualMemory(MemoryInfo *memory_info)
MagickProgressMonitor progress_monitor
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static Quantum GetPixelRed(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MemoryInfo * AcquireVirtualMemory(const size_t count, const size_t quantum)
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
static double StringToDouble(const char *magick_restrict string, char **magick_restrict sentinal)
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
static Quantum ClampToQuantum(const MagickRealType quantum)
MagickExport Image * ForwardFourierTransformImage(const Image *image, const MagickBooleanType modulus, ExceptionInfo *exception)
#define MagickCoreSignature
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport Image * GetFirstImageInList(const Image *images)
MagickExport Image * NewImageList(void)
static double PerceptibleReciprocal(const double x)
static Quantum GetPixelGreen(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static Quantum GetPixelBlack(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport Quantum * QueueCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
struct _FourierInfo FourierInfo
static void SetPixelBlue(const Image *magick_restrict image, const Quantum blue, Quantum *magick_restrict pixel)
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
MagickExport Image * DestroyImageList(Image *images)
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickBooleanType modulus
MagickExport int LocaleCompare(const char *p, const char *q)
char filename[MagickPathExtent]
#define GetMagickModule()
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
MagickExport MagickBooleanType IsImageGray(const Image *image)
MagickExport Image * GetNextImageInList(const Image *images)
MagickExport void AppendImageToList(Image **images, const Image *append)
static void SetPixelAlpha(const Image *magick_restrict image, const Quantum alpha, Quantum *magick_restrict pixel)
static void SetPixelRed(const Image *magick_restrict image, const Quantum red, Quantum *magick_restrict pixel)
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
static void SetPixelBlack(const Image *magick_restrict image, const Quantum black, Quantum *magick_restrict pixel)
static Quantum GetPixelBlue(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport void * GetVirtualMemoryBlob(const MemoryInfo *memory_info)
MagickExport Image * DestroyImage(Image *image)
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
ColorspaceType colorspace
MagickExport Image * ComplexImages(const Image *images, const ComplexOperator op, ExceptionInfo *exception)
MagickExport MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
static void SetPixelGreen(const Image *magick_restrict image, const Quantum green, Quantum *magick_restrict pixel)
MagickExport Image * InverseFourierTransformImage(const Image *magnitude_image, const Image *phase_image, const MagickBooleanType modulus, ExceptionInfo *exception)