{
CacheView
*composite_view,
- *destination_view;
+ *destination_view,
+ *image_view;
MagickPixelPacket
pixel;
register PixelPacket
*restrict r;
- ResampleFilter
- *resample_filter;
-
/*
Displace/Distort based on overlay gradient map:
X = red_channel; Y = green_channel;
*/
pixel=zero;
exception=(&image->exception);
- resample_filter=AcquireResampleFilter(image,&image->exception);
+ image_view=AcquireCacheView(image);
destination_view=AcquireCacheView(destination_image);
composite_view=AcquireCacheView(composite_image);
for (y=0; y < (ssize_t) composite_image->rows; y++)
offset.y=(vertical_scale*(p->green-(((MagickRealType) QuantumRange+
1.0)/2.0)))/(((MagickRealType) QuantumRange+1.0)/2.0)+
center.y+((compose == DisplaceCompositeOp) ? y : 0);
- (void) ResamplePixelColor(resample_filter,(double) offset.x,
- (double) offset.y,&pixel);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ (double) offset.x,(double) offset.y,&pixel,exception);
/*
Mask with the 'invalid pixel mask' in alpha channel.
*/
if (sync == MagickFalse)
break;
}
- resample_filter=DestroyResampleFilter(resample_filter);
- composite_view=DestroyCacheView(composite_view);
destination_view=DestroyCacheView(destination_view);
+ composite_view=DestroyCacheView(composite_view);
+ image_view=DestroyCacheView(image_view);
composite_image=destination_image;
break;
}
register ssize_t
i;
- ResampleFilter
- **restrict resample_filter;
-
SegmentInfo
edge;
inverse_affine=InverseAffineMatrix(affine);
GetMagickPixelPacket(image,&zero);
exception=(&image->exception);
- resample_filter=AcquireResampleFilterThreadSet(source,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
image_view=AcquireCacheView(image);
source_view=AcquireCacheView(source);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
inverse_affine.tx;
point.y=(double) x*inverse_affine.rx+y*inverse_affine.sy+
inverse_affine.ty;
- (void) ResamplePixelColor(resample_filter[id],point.x,point.y,&pixel);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ point.x,point.y,&pixel,exception);
SetMagickPixelPacket(image,q,indexes+x_offset,&composite);
MagickPixelCompositeOver(&pixel,pixel.opacity,&composite,
composite.opacity,&composite);
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
status=MagickFalse;
}
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
source_view=DestroyCacheView(source_view);
image_view=DestroyCacheView(image_view);
return(status);
break;
}
}
- preview_image=StatisticImage(thumbnail,NonpeakStatistic,i,i,
- exception);
+ preview_image=StatisticImage(thumbnail,NonpeakStatistic,(size_t) i,
+ (size_t) i,exception);
(void) FormatMagickString(label,MaxTextExtent,"+noise %s",factor);
break;
}
RandomInfo
**restrict random_info;
- ResampleFilter
- **restrict resample_filter;
-
size_t
width;
progress=0;
GetMagickPixelPacket(spread_image,&bias);
width=GetOptimalKernelWidth1D(radius,0.5);
- resample_filter=AcquireResampleFilterThreadSet(image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
random_info=AcquireRandomInfoThreadSet();
image_view=AcquireCacheView(spread_image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
pixel=bias;
for (x=0; x < (ssize_t) spread_image->columns; x++)
{
- (void) ResamplePixelColor(resample_filter[id],(double) x+width*
- (GetPseudoRandomValue(random_info[id])-0.5),(double) y+width*
- (GetPseudoRandomValue(random_info[id])-0.5),&pixel);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ (double) x+width*(GetPseudoRandomValue(random_info[id])-0.5),(double)
+ y+width*(GetPseudoRandomValue(random_info[id])-0.5),&pixel,
+ exception);
SetPixelPacket(spread_image,&pixel,q,indexes+x);
q++;
}
}
image_view=DestroyCacheView(image_view);
random_info=DestroyRandomInfoThreadSet(random_info);
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
return(spread_image);
}
\f
channel;
size_t
- color;
+ color,
+ maximum;
ssize_t
count;
unsigned short
- channels[ListChannels],
- maximum;
+ channels[ListChannels];
/*
Find the maximum value for each of the color.
if (color > maximum)
maximum=color;
count+=list->nodes[color].count;
- } while (count < pixel_list->length);
+ } while (count < (ssize_t) pixel_list->length);
channels[channel]=(unsigned short) maximum;
}
GetMagickPixelPacket((const Image *) NULL,&pixel);
color=list->nodes[color].next[0];
mean+=list->nodes[color].count*color;
count+=list->nodes[color].count;
- } while (count < pixel_list->length);
+ } while (count < (ssize_t) pixel_list->length);
channels[channel]=(unsigned short) (mean/pixel_list->length);
}
GetMagickPixelPacket((const Image *) NULL,&pixel);
{
color=list->nodes[color].next[0];
count+=list->nodes[color].count;
- } while (count <= (pixel_list->length >> 1));
+ } while (count <= (ssize_t) (pixel_list->length >> 1));
channels[channel]=(unsigned short) color;
}
GetMagickPixelPacket((const Image *) NULL,&pixel);
channel;
size_t
- color;
+ color,
+ minimum;
ssize_t
count;
unsigned short
- channels[ListChannels],
- minimum;
+ channels[ListChannels];
/*
Find the minimum value for each of the color.
if (color < minimum)
minimum=color;
count+=list->nodes[color].count;
- } while (count < pixel_list->length);
+ } while (count < (ssize_t) pixel_list->length);
channels[channel]=(unsigned short) minimum;
}
GetMagickPixelPacket((const Image *) NULL,&pixel);
max_count=list->nodes[mode].count;
}
count+=list->nodes[color].count;
- } while (count < pixel_list->length);
+ } while (count < (ssize_t) pixel_list->length);
channels[channel]=(unsigned short) mode;
}
GetMagickPixelPacket((const Image *) NULL,&pixel);
color=next;
next=list->nodes[color].next[0];
count+=list->nodes[color].count;
- } while (count <= (pixel_list->length >> 1));
+ } while (count <= (ssize_t) (pixel_list->length >> 1));
if ((previous == 65536UL) && (next != 65536UL))
color=next;
else
const size_t height,ExceptionInfo *exception)
{
#define StatisticWidth \
- (width == 0 ? GetOptimalKernelWidth2D(width,0.5) : width)
+ (width == 0 ? GetOptimalKernelWidth2D((double) width,0.5) : width)
#define StatisticHeight \
- (height == 0 ? GetOptimalKernelWidth2D(height,0.5) : height)
+ (height == 0 ? GetOptimalKernelWidth2D((double) height,0.5) : height)
#define StatisticImageTag "Statistic/Image"
CacheView
register ssize_t
i;
- ResampleFilter
- **restrict resample_filter;
-
ssize_t
adjust,
y;
progress=0;
adjust=(ssize_t) (clut_image->interpolate == IntegerInterpolatePixel ? 0 : 1);
exception=(&image->exception);
- resample_filter=AcquireResampleFilterThreadSet(clut_image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
+ image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(dynamic,4)
#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
{
- const int
- id = GetOpenMPThreadId();
-
GetMagickPixelPacket(clut_image,clut_map+i);
- (void) ResamplePixelColor(resample_filter[id],QuantumScale*i*
- (clut_image->columns-adjust),QuantumScale*i*(clut_image->rows-adjust),
- clut_map+i);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ QuantumScale*i*(clut_image->columns-adjust),QuantumScale*i*
+ (clut_image->rows-adjust),clut_map+i,exception);
}
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
- image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(dynamic,4) shared(progress,status)
#endif
{
if (clut_image->matte == MagickFalse)
q->opacity=(Quantum) (QuantumRange-MagickPixelIntensityToQuantum(
- clut_map+ScaleQuantumToMap(GetAlphaPixelComponent(q))));
+ clut_map+ScaleQuantumToMap((Quantum) GetAlphaPixelComponent(q))));
else
if (image->matte == MagickFalse)
SetOpacityPixelComponent(q,ClampOpacityPixelComponent(clut_map+
- ScaleQuantumToMap(MagickPixelIntensity(&pixel))));
+ ScaleQuantumToMap((Quantum) MagickPixelIntensity(&pixel))));
else
SetOpacityPixelComponent(q,ClampOpacityPixelComponent(
clut_map+ScaleQuantumToMap(q->opacity)));
MagickPixelPacket
zero;
- ResampleFilter
- **restrict resample_filter;
-
size_t
cube_size,
length,
width=(double) hald_image->columns;
GetMagickPixelPacket(hald_image,&zero);
exception=(&image->exception);
- resample_filter=AcquireResampleFilterThreadSet(hald_image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
image_view=AcquireCacheView(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(dynamic,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
- const int
- id = GetOpenMPThreadId();
-
double
offset;
point.x-=floor(point.x);
point.y-=floor(point.y);
point.z-=floor(point.z);
- (void) ResamplePixelColor(resample_filter[id],fmod(offset,width),
- floor(offset/width),&pixel1);
- (void) ResamplePixelColor(resample_filter[id],fmod(offset+level,width),
- floor((offset+level)/width),&pixel2);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ fmod(offset,width),floor(offset/width),&pixel1,exception);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ fmod(offset+level,width),floor((offset+level)/width),&pixel2,exception);
MagickPixelCompositeAreaBlend(&pixel1,pixel1.opacity,&pixel2,
pixel2.opacity,point.y,&pixel3);
offset+=cube_size;
- (void) ResamplePixelColor(resample_filter[id],fmod(offset,width),
- floor(offset/width),&pixel1);
- (void) ResamplePixelColor(resample_filter[id],fmod(offset+level,width),
- floor((offset+level)/width),&pixel2);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ fmod(offset,width),floor(offset/width),&pixel1,exception);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ fmod(offset+level,width),floor((offset+level)/width),&pixel2,exception);
MagickPixelCompositeAreaBlend(&pixel1,pixel1.opacity,&pixel2,
pixel2.opacity,point.y,&pixel4);
MagickPixelCompositeAreaBlend(&pixel3,pixel3.opacity,&pixel4,
}
}
image_view=DestroyCacheView(image_view);
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
return(status);
}
\f
*colors,
*symbols;
- ResampleFilter
- **resample_filter;
+ CacheView
+ **view;
RandomInfo
*random_info;
RelinquishMagickMemory);
fx_info->symbols=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
RelinquishMagickMemory);
- fx_info->resample_filter=(ResampleFilter **) AcquireQuantumMemory(
- GetImageListLength(fx_info->images),sizeof(*fx_info->resample_filter));
- if (fx_info->resample_filter == (ResampleFilter **) NULL)
+ fx_info->view=(CacheView **) AcquireQuantumMemory(GetImageListLength(
+ fx_info->images),sizeof(*fx_info->view));
+ if (fx_info->view == (CacheView **) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
i=0;
next=GetFirstImageInList(fx_info->images);
for ( ; next != (Image *) NULL; next=next->next)
{
- fx_info->resample_filter[i]=AcquireResampleFilter(next,fx_info->exception);
- SetResampleFilter(fx_info->resample_filter[i],PointFilter,1.0);
- (void) SetResampleFilterInterpolateMethod(fx_info->resample_filter[i],
- NearestNeighborInterpolatePixel);
+ fx_info->view[i]=AcquireCacheView(next);
i++;
}
fx_info->random_info=AcquireRandomInfo();
fx_info->symbols=DestroySplayTree(fx_info->symbols);
fx_info->colors=DestroySplayTree(fx_info->colors);
for (i=(ssize_t) GetImageListLength(fx_info->images)-1; i >= 0; i--)
- fx_info->resample_filter[i]=DestroyResampleFilter(
- fx_info->resample_filter[i]);
- fx_info->resample_filter=(ResampleFilter **) RelinquishMagickMemory(
- fx_info->resample_filter);
+ fx_info->view[i]=DestroyCacheView(fx_info->view[i]);
+ fx_info->view=(CacheView **) RelinquishMagickMemory(fx_info->view);
fx_info->random_info=DestroyRandomInfo(fx_info->random_info);
fx_info=(FxInfo *) RelinquishMagickMemory(fx_info);
return(fx_info);
"NoSuchImage","`%s'",expression);
return(0.0);
}
- (void) ResamplePixelColor(fx_info->resample_filter[i],point.x,point.y,&pixel);
+ (void) InterpolatePixelPacket(image,fx_info->view[i],
+ NearestNeighborInterpolatePixel,point.x,point.y,&pixel,exception);
if ((strlen(p) > 2) &&
(LocaleCompare(p,"intensity") != 0) &&
(LocaleCompare(p,"luminance") != 0) &&
center,
scale;
- ResampleFilter
- **restrict resample_filter;
-
ssize_t
y;
status=MagickTrue;
progress=0;
GetMagickPixelPacket(implode_image,&zero);
- resample_filter=AcquireResampleFilterThreadSet(image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
image_view=AcquireCacheView(image);
implode_view=AcquireCacheView(implode_image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
- const int
- id = GetOpenMPThreadId();
-
MagickPixelPacket
pixel;
if (distance > 0.0)
factor=pow(sin((double) (MagickPI*sqrt((double) distance)/
radius/2)),-amount);
- (void) ResamplePixelColor(resample_filter[id],(double)
- (factor*delta.x/scale.x+center.x),(double) (factor*delta.y/
- scale.y+center.y),&pixel);
+ (void) InterpolatePixelPacket(image,image_view,
+ image->interpolate,(double) (factor*delta.x/scale.x+center.x),
+ (double) (factor*delta.y/scale.y+center.y),&pixel,exception);
SetPixelPacket(implode_image,&pixel,q,implode_indexes+x);
}
q++;
}
implode_view=DestroyCacheView(implode_view);
image_view=DestroyCacheView(image_view);
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
if (status == MagickFalse)
implode_image=DestroyImage(implode_image);
return(implode_image);
center,
scale;
- ResampleFilter
- **restrict resample_filter;
-
ssize_t
y;
status=MagickTrue;
progress=0;
GetMagickPixelPacket(swirl_image,&zero);
- resample_filter=AcquireResampleFilterThreadSet(image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
image_view=AcquireCacheView(image);
swirl_view=AcquireCacheView(swirl_image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
- const int
- id = GetOpenMPThreadId();
-
MagickPixelPacket
pixel;
factor=1.0-sqrt((double) distance)/radius;
sine=sin((double) (degrees*factor*factor));
cosine=cos((double) (degrees*factor*factor));
- (void) ResamplePixelColor(resample_filter[id],(double) ((cosine*
- delta.x-sine*delta.y)/scale.x+center.x),(double) ((sine*delta.x+
- cosine*delta.y)/scale.y+center.y),&pixel);
+ (void) InterpolatePixelPacket(image,image_view,
+ image->interpolate,(double) ((cosine*delta.x-sine*delta.y)/scale.x+
+ center.x),(double) ((sine*delta.x+cosine*delta.y)/scale.y+
+ center.y),&pixel,exception);
SetPixelPacket(swirl_image,&pixel,q,swirl_indexes+x);
}
q++;
}
swirl_view=DestroyCacheView(swirl_view);
image_view=DestroyCacheView(image_view);
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
if (status == MagickFalse)
swirl_image=DestroyImage(swirl_image);
return(swirl_image);
#define WaveImageTag "Wave/Image"
CacheView
+ *image_view,
*wave_view;
Image
register ssize_t
i;
- ResampleFilter
- **restrict resample_filter;
-
ssize_t
y;
status=MagickTrue;
progress=0;
GetMagickPixelPacket(wave_image,&zero);
- resample_filter=AcquireResampleFilterThreadSet(image,
- BackgroundVirtualPixelMethod,MagickTrue,exception);
+ image_view=AcquireCacheView(image);
wave_view=AcquireCacheView(wave_image);
+ (void) SetCacheViewVirtualPixelMethod(image_view,
+ BackgroundVirtualPixelMethod);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(dynamic,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) wave_image->rows; y++)
{
- const int
- id = GetOpenMPThreadId();
-
MagickPixelPacket
pixel;
pixel=zero;
for (x=0; x < (ssize_t) wave_image->columns; x++)
{
- (void) ResamplePixelColor(resample_filter[id],(double) x,(double) (y-
- sine_map[x]),&pixel);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ (double) x,(double) (y-sine_map[x]),&pixel,exception);
SetPixelPacket(wave_image,&pixel,q,indexes+x);
q++;
}
}
}
wave_view=DestroyCacheView(wave_view);
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
+ image_view=DestroyCacheView(image_view);
sine_map=(MagickRealType *) RelinquishMagickMemory(sine_map);
if (status == MagickFalse)
wave_image=DestroyImage(wave_image);
#include "magick/blob.h"
#include "magick/blob-private.h"
#include "magick/color-private.h"
+#include "magick/draw.h"
#include "magick/exception.h"
#include "magick/exception-private.h"
#include "magick/cache.h"
#include "magick/statistic.h"
#include "magick/stream.h"
#include "magick/string_.h"
+#include "magick/transform.h"
#include "magick/utility.h"
\f
/*
quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
return(MagickTrue);
}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n t e r p o l a t e P i x e l P a c k e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InterpolatePixelPacket() applies bi-linear or tri-linear interpolation
+% between a floating point coordinate and the pixels surrounding that
+% coordinate. No pixel area resampling, or scaling of the result is
+% performed.
+%
+% The format of the InterpolatePixelPacket method is:
+%
+% MagickBooleanType InterpolatePixelPacket(const Image *image,
+% CacheView *image_view,const InterpolatePixelMethod method,
+% const double x,const double y,MagickPixelPacket *pixel,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+% o image_view: the image view.
+%
+% o method: the pixel color interpolation method.
+%
+% o x,y: A double representing the current (x,y) position of the pixel.
+%
+% o pixel: return the interpolated pixel here.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline double MagickMax(const double x,const double y)
+{
+ if (x > y)
+ return(x);
+ return(y);
+}
+
+static void BicubicInterpolate(const MagickPixelPacket *pixels,const double dx,
+ MagickPixelPacket *pixel)
+{
+ MagickRealType
+ dx2,
+ p,
+ q,
+ r,
+ s;
+
+ dx2=dx*dx;
+ p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
+ q=(pixels[0].red-pixels[1].red)-p;
+ r=pixels[2].red-pixels[0].red;
+ s=pixels[1].red;
+ pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
+ q=(pixels[0].green-pixels[1].green)-p;
+ r=pixels[2].green-pixels[0].green;
+ s=pixels[1].green;
+ pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
+ q=(pixels[0].blue-pixels[1].blue)-p;
+ r=pixels[2].blue-pixels[0].blue;
+ s=pixels[1].blue;
+ pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ p=(pixels[3].opacity-pixels[2].opacity)-(pixels[0].opacity-pixels[1].opacity);
+ q=(pixels[0].opacity-pixels[1].opacity)-p;
+ r=pixels[2].opacity-pixels[0].opacity;
+ s=pixels[1].opacity;
+ pixel->opacity=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ if (pixel->colorspace == CMYKColorspace)
+ {
+ p=(pixels[3].index-pixels[2].index)-(pixels[0].index-pixels[1].index);
+ q=(pixels[0].index-pixels[1].index)-p;
+ r=pixels[2].index-pixels[0].index;
+ s=pixels[1].index;
+ pixel->index=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
+ }
+}
+
+static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
+{
+ MagickRealType
+ alpha,
+ gamma;
+
+ alpha=MagickMax(x+2.0,0.0);
+ gamma=1.0*alpha*alpha*alpha;
+ alpha=MagickMax(x+1.0,0.0);
+ gamma-=4.0*alpha*alpha*alpha;
+ alpha=MagickMax(x+0.0,0.0);
+ gamma+=6.0*alpha*alpha*alpha;
+ alpha=MagickMax(x-1.0,0.0);
+ gamma-=4.0*alpha*alpha*alpha;
+ return(gamma/6.0);
+}
+
+static inline double MeshInterpolate(const PointInfo *delta,const double p,
+ const double x,const double y)
+{
+ return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
+}
+
+static inline ssize_t NearestNeighbor(MagickRealType x)
+{
+ if (x >= 0.0)
+ return((ssize_t) (x+0.5));
+ return((ssize_t) (x-0.5));
+}
+
+MagickExport MagickBooleanType InterpolatePixelPacket(const Image *image,
+ CacheView *image_view,const InterpolatePixelMethod method,const double x,
+ const double y,MagickPixelPacket *pixel,ExceptionInfo *exception)
+{
+ MagickBooleanType
+ status;
+
+ register const IndexPacket
+ *indexes;
+
+ register const PixelPacket
+ *p;
+
+ register ssize_t
+ i;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image_view != (CacheView *) NULL);
+ status=MagickTrue;
+ switch (method)
+ {
+ case AverageInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[16];
+
+ MagickRealType
+ alpha[16],
+ gamma;
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,
+ (ssize_t) floor(y)-1,4,4,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ for (i=0; i < 16L; i++)
+ {
+ GetMagickPixelPacket(image,pixels+i);
+ SetMagickPixelPacket(image,p,indexes+i,pixels+i);
+ alpha[i]=1.0;
+ if (pixels[i].matte != MagickFalse)
+ {
+ alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
+ pixels[i].red*=alpha[i];
+ pixels[i].green*=alpha[i];
+ pixels[i].blue*=alpha[i];
+ if (pixels[i].colorspace == CMYKColorspace)
+ pixels[i].index*=alpha[i];
+ }
+ gamma=alpha[i];
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red+=gamma*0.0625*pixels[i].red;
+ pixel->green+=gamma*0.0625*pixels[i].green;
+ pixel->blue+=gamma*0.0625*pixels[i].blue;
+ pixel->opacity+=0.0625*pixels[i].opacity;
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index+=gamma*0.0625*pixels[i].index;
+ p++;
+ }
+ break;
+ }
+ case BicubicInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[16],
+ u[4];
+
+ MagickRealType
+ alpha[16];
+
+ PointInfo
+ delta;
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,(ssize_t)
+ floor(y)-1,4,4,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ for (i=0; i < 16L; i++)
+ {
+ GetMagickPixelPacket(image,pixels+i);
+ SetMagickPixelPacket(image,p,indexes+i,pixels+i);
+ alpha[i]=1.0;
+ if (pixels[i].matte != MagickFalse)
+ {
+ alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
+ pixels[i].red*=alpha[i];
+ pixels[i].green*=alpha[i];
+ pixels[i].blue*=alpha[i];
+ if (pixels[i].colorspace == CMYKColorspace)
+ pixels[i].index*=alpha[i];
+ }
+ p++;
+ }
+ delta.x=x-floor(x);
+ for (i=0; i < 4L; i++)
+ BicubicInterpolate(pixels+4*i,delta.x,u+i);
+ delta.y=y-floor(y);
+ BicubicInterpolate(u,delta.y,pixel);
+ break;
+ }
+ case BilinearInterpolatePixel:
+ default:
+ {
+ MagickPixelPacket
+ pixels[4];
+
+ MagickRealType
+ alpha[4],
+ gamma;
+
+ PointInfo
+ delta,
+ epsilon;
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
+ floor(y),2,2,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ for (i=0; i < 4L; i++)
+ {
+ GetMagickPixelPacket(image,pixels+i);
+ pixels[i].red=(MagickRealType) p[i].red;
+ pixels[i].green=(MagickRealType) p[i].green;
+ pixels[i].blue=(MagickRealType) p[i].blue;
+ pixels[i].opacity=(MagickRealType) p[i].opacity;
+ alpha[i]=1.0;
+ if (pixels[i].matte != MagickFalse)
+ {
+ alpha[i]=QuantumScale*((MagickRealType) QuantumRange-p[i].opacity);
+ pixels[i].red*=alpha[i];
+ pixels[i].green*=alpha[i];
+ pixels[i].blue*=alpha[i];
+ }
+ if (indexes != (IndexPacket *) NULL)
+ {
+ pixels[i].index=(MagickRealType) indexes[i];
+ if (pixels[i].colorspace == CMYKColorspace)
+ pixels[i].index*=alpha[i];
+ }
+ }
+ delta.x=x-floor(x);
+ delta.y=y-floor(y);
+ epsilon.x=1.0-delta.x;
+ epsilon.y=1.0-delta.y;
+ gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
+ (epsilon.x*alpha[2]+delta.x*alpha[3])));
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
+ pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
+ pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
+ pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
+ pixels[3].green));
+ pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
+ pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
+ pixels[3].blue));
+ pixel->opacity=(epsilon.y*(epsilon.x*pixels[0].opacity+delta.x*
+ pixels[1].opacity)+delta.y*(epsilon.x*pixels[2].opacity+delta.x*
+ pixels[3].opacity));
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index=gamma*(epsilon.y*(epsilon.x*pixels[0].index+delta.x*
+ pixels[1].index)+delta.y*(epsilon.x*pixels[2].index+delta.x*
+ pixels[3].index));
+ break;
+ }
+ case FilterInterpolatePixel:
+ {
+ CacheView
+ *filter_view;
+
+ Image
+ *excerpt_image,
+ *filter_image;
+
+ MagickPixelPacket
+ pixels[1];
+
+ RectangleInfo
+ geometry;
+
+ geometry.width=4L;
+ geometry.height=4L;
+ geometry.x=(ssize_t) floor(x)-1L;
+ geometry.y=(ssize_t) floor(y)-1L;
+ excerpt_image=ExcerptImage(image,&geometry,exception);
+ if (excerpt_image == (Image *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ filter_image=ResizeImage(excerpt_image,1,1,image->filter,image->blur,
+ exception);
+ excerpt_image=DestroyImage(excerpt_image);
+ if (filter_image == (Image *) NULL)
+ break;
+ filter_view=AcquireCacheView(filter_image);
+ p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
+ if (p != (const PixelPacket *) NULL)
+ {
+ indexes=GetVirtualIndexQueue(filter_image);
+ GetMagickPixelPacket(image,pixels);
+ SetMagickPixelPacket(image,p,indexes,pixel);
+ }
+ filter_view=DestroyCacheView(filter_view);
+ filter_image=DestroyImage(filter_image);
+ break;
+ }
+ case IntegerInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[1];
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
+ floor(y),1,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ GetMagickPixelPacket(image,pixels);
+ SetMagickPixelPacket(image,p,indexes,pixel);
+ break;
+ }
+ case MeshInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[4];
+
+ MagickRealType
+ alpha[4],
+ gamma;
+
+ PointInfo
+ delta,
+ luminance;
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x),(ssize_t)
+ floor(y),2,2,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ for (i=0; i < 4L; i++)
+ {
+ GetMagickPixelPacket(image,pixels+i);
+ SetMagickPixelPacket(image,p,indexes+i,pixels+i);
+ alpha[i]=1.0;
+ if (pixels[i].matte != MagickFalse)
+ {
+ alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
+ pixels[i].red*=alpha[i];
+ pixels[i].green*=alpha[i];
+ pixels[i].blue*=alpha[i];
+ if (pixels[i].colorspace == CMYKColorspace)
+ pixels[i].index*=alpha[i];
+ }
+ p++;
+ }
+ delta.x=x-floor(x);
+ delta.y=y-floor(y);
+ luminance.x=MagickPixelLuminance(pixels+0)-MagickPixelLuminance(pixels+3);
+ luminance.y=MagickPixelLuminance(pixels+1)-MagickPixelLuminance(pixels+2);
+ if (fabs(luminance.x) < fabs(luminance.y))
+ {
+ /*
+ Diagonal 0-3 NW-SE.
+ */
+ if (delta.x <= delta.y)
+ {
+ /*
+ Bottom-left triangle (pixel:2, diagonal: 0-3).
+ */
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
+ pixels[3].red,pixels[0].red);
+ pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
+ pixels[3].green,pixels[0].green);
+ pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
+ pixels[3].blue,pixels[0].blue);
+ pixel->opacity=gamma*MeshInterpolate(&delta,pixels[2].opacity,
+ pixels[3].opacity,pixels[0].opacity);
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index=gamma*MeshInterpolate(&delta,pixels[2].index,
+ pixels[3].index,pixels[0].index);
+ }
+ else
+ {
+ /*
+ Top-right triangle (pixel:1, diagonal: 0-3).
+ */
+ delta.x=1.0-delta.x;
+ gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
+ pixels[0].red,pixels[3].red);
+ pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
+ pixels[0].green,pixels[3].green);
+ pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
+ pixels[0].blue,pixels[3].blue);
+ pixel->opacity=gamma*MeshInterpolate(&delta,pixels[1].opacity,
+ pixels[0].opacity,pixels[3].opacity);
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index=gamma*MeshInterpolate(&delta,pixels[1].index,
+ pixels[0].index,pixels[3].index);
+ }
+ }
+ else
+ {
+ /*
+ Diagonal 1-2 NE-SW.
+ */
+ if (delta.x <= (1.0-delta.y))
+ {
+ /*
+ Top-left triangle (pixel 0, diagonal: 1-2).
+ */
+ gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
+ pixels[1].red,pixels[2].red);
+ pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
+ pixels[1].green,pixels[2].green);
+ pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
+ pixels[1].blue,pixels[2].blue);
+ pixel->opacity=gamma*MeshInterpolate(&delta,pixels[0].opacity,
+ pixels[1].opacity,pixels[2].opacity);
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index=gamma*MeshInterpolate(&delta,pixels[0].index,
+ pixels[1].index,pixels[2].index);
+ }
+ else
+ {
+ /*
+ Bottom-right triangle (pixel: 3, diagonal: 1-2).
+ */
+ delta.x=1.0-delta.x;
+ delta.y=1.0-delta.y;
+ gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
+ pixels[2].red,pixels[1].red);
+ pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
+ pixels[2].green,pixels[1].green);
+ pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
+ pixels[2].blue,pixels[1].blue);
+ pixel->opacity=gamma*MeshInterpolate(&delta,pixels[3].opacity,
+ pixels[2].opacity,pixels[1].opacity);
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index=gamma*MeshInterpolate(&delta,pixels[3].index,
+ pixels[2].index,pixels[1].index);
+ }
+ }
+ break;
+ }
+ case NearestNeighborInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[1];
+
+ p=GetCacheViewVirtualPixels(image_view,NearestNeighbor(x),
+ NearestNeighbor(y),1,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ GetMagickPixelPacket(image,pixels);
+ SetMagickPixelPacket(image,p,indexes,pixel);
+ break;
+ }
+ case SplineInterpolatePixel:
+ {
+ MagickPixelPacket
+ pixels[16];
+
+ MagickRealType
+ alpha[16],
+ dx,
+ dy,
+ gamma;
+
+ PointInfo
+ delta;
+
+ ssize_t
+ j,
+ n;
+
+ p=GetCacheViewVirtualPixels(image_view,(ssize_t) floor(x)-1,(ssize_t)
+ floor(y)-1,4,4,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ n=0;
+ delta.x=x-floor(x);
+ delta.y=y-floor(y);
+ for (i=(-1); i < 3L; i++)
+ {
+ dy=CubicWeightingFunction((MagickRealType) i-delta.y);
+ for (j=(-1); j < 3L; j++)
+ {
+ GetMagickPixelPacket(image,pixels+n);
+ SetMagickPixelPacket(image,p,indexes+n,pixels+n);
+ alpha[n]=1.0;
+ if (pixels[i].matte != MagickFalse)
+ {
+ alpha[n]=QuantumScale*((MagickRealType)
+ GetAlphaPixelComponent(p));
+ pixels[n].red*=alpha[n];
+ pixels[n].green*=alpha[n];
+ pixels[n].blue*=alpha[n];
+ if (pixels[i].colorspace == CMYKColorspace)
+ pixels[n].index*=alpha[n];
+ }
+ dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
+ gamma=alpha[n];
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ pixel->red+=gamma*dx*dy*pixels[n].red;
+ pixel->green+=gamma*dx*dy*pixels[n].green;
+ pixel->blue+=gamma*dx*dy*pixels[n].blue;
+ if (pixel->matte != MagickFalse)
+ pixel->opacity+=dx*dy*pixels[n].opacity;
+ if (pixel->colorspace == CMYKColorspace)
+ pixel->index+=gamma*dx*dy*pixels[n].index;
+ n++;
+ p++;
+ }
+ }
+ break;
+ }
+ }
+ return(status);
+}
#define SetYellowPixelComponent(q,value) ((q)->blue=(value))
#define SetBlackPixelComponent(p,x,value) (p[x]=(value))
+typedef enum
+{
+ UndefinedInterpolatePixel,
+ AverageInterpolatePixel,
+ BicubicInterpolatePixel,
+ BilinearInterpolatePixel,
+ FilterInterpolatePixel,
+ IntegerInterpolatePixel,
+ MeshInterpolatePixel,
+ NearestNeighborInterpolatePixel,
+ SplineInterpolatePixel
+} InterpolatePixelMethod;
+
typedef struct _DoublePixelPacket
{
double
#endif
} PixelPacket;
+typedef struct _CacheView
+ CacheView_;
+
extern MagickExport MagickBooleanType
ExportImagePixels(const Image *,const ssize_t,const ssize_t,const size_t,
const size_t,const char *,const StorageType,void *,ExceptionInfo *),
ImportImagePixels(Image *,const ssize_t,const ssize_t,const size_t,
- const size_t,const char *,const StorageType,const void *);
+ const size_t,const char *,const StorageType,const void *),
+ InterpolatePixelPacket(const Image *,CacheView_ *,
+ const InterpolatePixelMethod,const double,const double,MagickPixelPacket *,
+ ExceptionInfo *);
extern MagickExport void
GetMagickPixelPacket(const Image *,MagickPixelPacket *);
% %
% %
% %
-% I n t e r p o l a t e R e s a m p l e F i l t e r %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% InterpolateResampleFilter() applies bi-linear or tri-linear interpolation
-% between a floating point coordinate and the pixels surrounding that
-% coordinate. No pixel area resampling, or scaling of the result is
-% performed.
-%
-% The format of the InterpolateResampleFilter method is:
-%
-% MagickBooleanType InterpolateResampleFilter(
-% ResampleInfo *resample_filter,const InterpolatePixelMethod method,
-% const double x,const double y,MagickPixelPacket *pixel)
-%
-% A description of each parameter follows:
-%
-% o resample_filter: the resample filter.
-%
-% o method: the pixel clor interpolation method.
-%
-% o x,y: A double representing the current (x,y) position of the pixel.
-%
-% o pixel: return the interpolated pixel here.
-%
-*/
-
-static inline double MagickMax(const double x,const double y)
-{
- if (x > y)
- return(x);
- return(y);
-}
-
-static void BicubicInterpolate(const MagickPixelPacket *pixels,const double dx,
- MagickPixelPacket *pixel)
-{
- MagickRealType
- dx2,
- p,
- q,
- r,
- s;
-
- dx2=dx*dx;
- p=(pixels[3].red-pixels[2].red)-(pixels[0].red-pixels[1].red);
- q=(pixels[0].red-pixels[1].red)-p;
- r=pixels[2].red-pixels[0].red;
- s=pixels[1].red;
- pixel->red=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].green-pixels[2].green)-(pixels[0].green-pixels[1].green);
- q=(pixels[0].green-pixels[1].green)-p;
- r=pixels[2].green-pixels[0].green;
- s=pixels[1].green;
- pixel->green=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].blue-pixels[2].blue)-(pixels[0].blue-pixels[1].blue);
- q=(pixels[0].blue-pixels[1].blue)-p;
- r=pixels[2].blue-pixels[0].blue;
- s=pixels[1].blue;
- pixel->blue=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- p=(pixels[3].opacity-pixels[2].opacity)-(pixels[0].opacity-pixels[1].opacity);
- q=(pixels[0].opacity-pixels[1].opacity)-p;
- r=pixels[2].opacity-pixels[0].opacity;
- s=pixels[1].opacity;
- pixel->opacity=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- if (pixel->colorspace == CMYKColorspace)
- {
- p=(pixels[3].index-pixels[2].index)-(pixels[0].index-pixels[1].index);
- q=(pixels[0].index-pixels[1].index)-p;
- r=pixels[2].index-pixels[0].index;
- s=pixels[1].index;
- pixel->index=(dx*dx2*p)+(dx2*q)+(dx*r)+s;
- }
-}
-
-static inline MagickRealType CubicWeightingFunction(const MagickRealType x)
-{
- MagickRealType
- alpha,
- gamma;
-
- alpha=MagickMax(x+2.0,0.0);
- gamma=1.0*alpha*alpha*alpha;
- alpha=MagickMax(x+1.0,0.0);
- gamma-=4.0*alpha*alpha*alpha;
- alpha=MagickMax(x+0.0,0.0);
- gamma+=6.0*alpha*alpha*alpha;
- alpha=MagickMax(x-1.0,0.0);
- gamma-=4.0*alpha*alpha*alpha;
- return(gamma/6.0);
-}
-
-static inline double MeshInterpolate(const PointInfo *delta,const double p,
- const double x,const double y)
-{
- return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
-}
-
-static inline ssize_t NearestNeighbor(MagickRealType x)
-{
- if (x >= 0.0)
- return((ssize_t) (x+0.5));
- return((ssize_t) (x-0.5));
-}
-
-static MagickBooleanType InterpolateResampleFilter(
- ResampleFilter *resample_filter,const InterpolatePixelMethod method,
- const double x,const double y,MagickPixelPacket *pixel)
-{
- MagickBooleanType
- status;
-
- register const IndexPacket
- *indexes;
-
- register const PixelPacket
- *p;
-
- register ssize_t
- i;
-
- assert(resample_filter != (ResampleFilter *) NULL);
- assert(resample_filter->signature == MagickSignature);
- status=MagickTrue;
-
- switch (method)
- {
- case AverageInterpolatePixel:
- {
- MagickPixelPacket
- pixels[16];
-
- MagickRealType
- alpha[16],
- gamma;
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x)-1,
- (ssize_t) floor(y)-1,4,4,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- for (i=0; i < 16L; i++)
- {
- GetMagickPixelPacket(resample_filter->image,pixels+i);
- SetMagickPixelPacket(resample_filter->image,p,indexes+i,pixels+i);
- alpha[i]=1.0;
- if (pixels[i].matte != MagickFalse)
- {
- alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
- pixels[i].red*=alpha[i];
- pixels[i].green*=alpha[i];
- pixels[i].blue*=alpha[i];
- if (pixels[i].colorspace == CMYKColorspace)
- pixels[i].index*=alpha[i];
- }
- gamma=alpha[i];
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red+=gamma*0.0625*pixels[i].red;
- pixel->green+=gamma*0.0625*pixels[i].green;
- pixel->blue+=gamma*0.0625*pixels[i].blue;
- pixel->opacity+=0.0625*pixels[i].opacity;
- if (pixel->colorspace == CMYKColorspace)
- pixel->index+=gamma*0.0625*pixels[i].index;
- p++;
- }
- break;
- }
- case BicubicInterpolatePixel:
- {
- MagickPixelPacket
- pixels[16],
- u[4];
-
- MagickRealType
- alpha[16];
-
- PointInfo
- delta;
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x)-1,
- (ssize_t) floor(y)-1,4,4,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- for (i=0; i < 16L; i++)
- {
- GetMagickPixelPacket(resample_filter->image,pixels+i);
- SetMagickPixelPacket(resample_filter->image,p,indexes+i,pixels+i);
- alpha[i]=1.0;
- if (pixels[i].matte != MagickFalse)
- {
- alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
- pixels[i].red*=alpha[i];
- pixels[i].green*=alpha[i];
- pixels[i].blue*=alpha[i];
- if (pixels[i].colorspace == CMYKColorspace)
- pixels[i].index*=alpha[i];
- }
- p++;
- }
- delta.x=x-floor(x);
- for (i=0; i < 4L; i++)
- BicubicInterpolate(pixels+4*i,delta.x,u+i);
- delta.y=y-floor(y);
- BicubicInterpolate(u,delta.y,pixel);
- break;
- }
- case BilinearInterpolatePixel:
- default:
- {
- MagickPixelPacket
- pixels[4];
-
- MagickRealType
- alpha[4],
- gamma;
-
- PointInfo
- delta,
- epsilon;
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x),
- (ssize_t) floor(y),2,2,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- for (i=0; i < 4L; i++)
- {
- GetMagickPixelPacket(resample_filter->image,pixels+i);
- pixels[i].red=(MagickRealType) p[i].red;
- pixels[i].green=(MagickRealType) p[i].green;
- pixels[i].blue=(MagickRealType) p[i].blue;
- pixels[i].opacity=(MagickRealType) p[i].opacity;
- alpha[i]=1.0;
- if (pixels[i].matte != MagickFalse)
- {
- alpha[i]=QuantumScale*((MagickRealType) QuantumRange-p[i].opacity);
- pixels[i].red*=alpha[i];
- pixels[i].green*=alpha[i];
- pixels[i].blue*=alpha[i];
- }
- if (indexes != (IndexPacket *) NULL)
- {
- pixels[i].index=(MagickRealType) indexes[i];
- if (pixels[i].colorspace == CMYKColorspace)
- pixels[i].index*=alpha[i];
- }
- }
- delta.x=x-floor(x);
- delta.y=y-floor(y);
- epsilon.x=1.0-delta.x;
- epsilon.y=1.0-delta.y;
- gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
- (epsilon.x*alpha[2]+delta.x*alpha[3])));
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
- pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
- pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
- pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
- pixels[3].green));
- pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
- pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
- pixels[3].blue));
- pixel->opacity=(epsilon.y*(epsilon.x*pixels[0].opacity+delta.x*
- pixels[1].opacity)+delta.y*(epsilon.x*pixels[2].opacity+delta.x*
- pixels[3].opacity));
- if (pixel->colorspace == CMYKColorspace)
- pixel->index=gamma*(epsilon.y*(epsilon.x*pixels[0].index+delta.x*
- pixels[1].index)+delta.y*(epsilon.x*pixels[2].index+delta.x*
- pixels[3].index));
- break;
- }
- case FilterInterpolatePixel:
- {
- CacheView
- *filter_view;
-
- Image
- *excerpt_image,
- *filter_image;
-
- MagickPixelPacket
- pixels[1];
-
- RectangleInfo
- geometry;
-
- geometry.width=4L;
- geometry.height=4L;
- geometry.x=(ssize_t) floor(x)-1L;
- geometry.y=(ssize_t) floor(y)-1L;
- excerpt_image=ExcerptImage(resample_filter->image,&geometry,
- resample_filter->exception);
- if (excerpt_image == (Image *) NULL)
- {
- status=MagickFalse;
- break;
- }
- filter_image=ResizeImage(excerpt_image,1,1,resample_filter->image->filter,
- resample_filter->image->blur,resample_filter->exception);
- excerpt_image=DestroyImage(excerpt_image);
- if (filter_image == (Image *) NULL)
- break;
- filter_view=AcquireCacheView(filter_image);
- p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,
- resample_filter->exception);
- if (p != (const PixelPacket *) NULL)
- {
- indexes=GetVirtualIndexQueue(filter_image);
- GetMagickPixelPacket(resample_filter->image,pixels);
- SetMagickPixelPacket(resample_filter->image,p,indexes,pixel);
- }
- filter_view=DestroyCacheView(filter_view);
- filter_image=DestroyImage(filter_image);
- break;
- }
- case IntegerInterpolatePixel:
- {
- MagickPixelPacket
- pixels[1];
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x),
- (ssize_t) floor(y),1,1,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- GetMagickPixelPacket(resample_filter->image,pixels);
- SetMagickPixelPacket(resample_filter->image,p,indexes,pixel);
- break;
- }
- case MeshInterpolatePixel:
- {
- MagickPixelPacket
- pixels[4];
-
- MagickRealType
- alpha[4],
- gamma;
-
- PointInfo
- delta,
- luminance;
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x),
- (ssize_t) floor(y),2,2,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- for (i=0; i < 4L; i++)
- {
- GetMagickPixelPacket(resample_filter->image,pixels+i);
- SetMagickPixelPacket(resample_filter->image,p,indexes+i,pixels+i);
- alpha[i]=1.0;
- if (pixels[i].matte != MagickFalse)
- {
- alpha[i]=QuantumScale*((MagickRealType) GetAlphaPixelComponent(p));
- pixels[i].red*=alpha[i];
- pixels[i].green*=alpha[i];
- pixels[i].blue*=alpha[i];
- if (pixels[i].colorspace == CMYKColorspace)
- pixels[i].index*=alpha[i];
- }
- p++;
- }
- delta.x=x-floor(x);
- delta.y=y-floor(y);
- luminance.x=MagickPixelLuminance(pixels+0)-MagickPixelLuminance(pixels+3);
- luminance.y=MagickPixelLuminance(pixels+1)-MagickPixelLuminance(pixels+2);
- if (fabs(luminance.x) < fabs(luminance.y))
- {
- /*
- Diagonal 0-3 NW-SE.
- */
- if (delta.x <= delta.y)
- {
- /*
- Bottom-left triangle (pixel:2, diagonal: 0-3).
- */
- delta.y=1.0-delta.y;
- gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
- pixels[3].red,pixels[0].red);
- pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
- pixels[3].green,pixels[0].green);
- pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
- pixels[3].blue,pixels[0].blue);
- pixel->opacity=gamma*MeshInterpolate(&delta,pixels[2].opacity,
- pixels[3].opacity,pixels[0].opacity);
- if (pixel->colorspace == CMYKColorspace)
- pixel->index=gamma*MeshInterpolate(&delta,pixels[2].index,
- pixels[3].index,pixels[0].index);
- }
- else
- {
- /*
- Top-right triangle (pixel:1, diagonal: 0-3).
- */
- delta.x=1.0-delta.x;
- gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
- pixels[0].red,pixels[3].red);
- pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
- pixels[0].green,pixels[3].green);
- pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
- pixels[0].blue,pixels[3].blue);
- pixel->opacity=gamma*MeshInterpolate(&delta,pixels[1].opacity,
- pixels[0].opacity,pixels[3].opacity);
- if (pixel->colorspace == CMYKColorspace)
- pixel->index=gamma*MeshInterpolate(&delta,pixels[1].index,
- pixels[0].index,pixels[3].index);
- }
- }
- else
- {
- /*
- Diagonal 1-2 NE-SW.
- */
- if (delta.x <= (1.0-delta.y))
- {
- /*
- Top-left triangle (pixel 0, diagonal: 1-2).
- */
- gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
- pixels[1].red,pixels[2].red);
- pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
- pixels[1].green,pixels[2].green);
- pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
- pixels[1].blue,pixels[2].blue);
- pixel->opacity=gamma*MeshInterpolate(&delta,pixels[0].opacity,
- pixels[1].opacity,pixels[2].opacity);
- if (pixel->colorspace == CMYKColorspace)
- pixel->index=gamma*MeshInterpolate(&delta,pixels[0].index,
- pixels[1].index,pixels[2].index);
- }
- else
- {
- /*
- Bottom-right triangle (pixel: 3, diagonal: 1-2).
- */
- delta.x=1.0-delta.x;
- delta.y=1.0-delta.y;
- gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
- pixels[2].red,pixels[1].red);
- pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
- pixels[2].green,pixels[1].green);
- pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
- pixels[2].blue,pixels[1].blue);
- pixel->opacity=gamma*MeshInterpolate(&delta,pixels[3].opacity,
- pixels[2].opacity,pixels[1].opacity);
- if (pixel->colorspace == CMYKColorspace)
- pixel->index=gamma*MeshInterpolate(&delta,pixels[3].index,
- pixels[2].index,pixels[1].index);
- }
- }
- break;
- }
- case NearestNeighborInterpolatePixel:
- {
- MagickPixelPacket
- pixels[1];
-
- p=GetCacheViewVirtualPixels(resample_filter->view,NearestNeighbor(x),
- NearestNeighbor(y),1,1,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- GetMagickPixelPacket(resample_filter->image,pixels);
- SetMagickPixelPacket(resample_filter->image,p,indexes,pixel);
- break;
- }
- case SplineInterpolatePixel:
- {
- MagickPixelPacket
- pixels[16];
-
- MagickRealType
- alpha[16],
- dx,
- dy,
- gamma;
-
- PointInfo
- delta;
-
- ssize_t
- j,
- n;
-
- p=GetCacheViewVirtualPixels(resample_filter->view,(ssize_t) floor(x)-1,
- (ssize_t) floor(y)-1,4,4,resample_filter->exception);
- if (p == (const PixelPacket *) NULL)
- {
- status=MagickFalse;
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(resample_filter->view);
- n=0;
- delta.x=x-floor(x);
- delta.y=y-floor(y);
- for (i=(-1); i < 3L; i++)
- {
- dy=CubicWeightingFunction((MagickRealType) i-delta.y);
- for (j=(-1); j < 3L; j++)
- {
- GetMagickPixelPacket(resample_filter->image,pixels+n);
- SetMagickPixelPacket(resample_filter->image,p,indexes+n,pixels+n);
- alpha[n]=1.0;
- if (pixels[i].matte != MagickFalse)
- {
- alpha[n]=QuantumScale*((MagickRealType)
- GetAlphaPixelComponent(p));
- pixels[n].red*=alpha[n];
- pixels[n].green*=alpha[n];
- pixels[n].blue*=alpha[n];
- if (pixels[i].colorspace == CMYKColorspace)
- pixels[n].index*=alpha[n];
- }
- dx=CubicWeightingFunction(delta.x-(MagickRealType) j);
- gamma=alpha[n];
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- pixel->red+=gamma*dx*dy*pixels[n].red;
- pixel->green+=gamma*dx*dy*pixels[n].green;
- pixel->blue+=gamma*dx*dy*pixels[n].blue;
- if (pixel->matte != MagickFalse)
- pixel->opacity+=dx*dy*pixels[n].opacity;
- if (pixel->colorspace == CMYKColorspace)
- pixel->index+=gamma*dx*dy*pixels[n].index;
- n++;
- p++;
- }
- }
- break;
- }
- }
- return(status);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
% R e s a m p l e P i x e l C o l o r %
% %
% %
status=MagickTrue;
GetMagickPixelPacket(resample_filter->image,pixel);
if ( resample_filter->do_interpolate ) {
- status=InterpolateResampleFilter(resample_filter,
- resample_filter->interpolate,u0,v0,pixel);
+ status=InterpolatePixelPacket(resample_filter->image,
+ resample_filter->view,resample_filter->interpolate,u0,v0,pixel,
+ resample_filter->exception);
return(status);
}
}
if ( hit ) {
/* whole area is a solid color -- just return that color */
- status=InterpolateResampleFilter(resample_filter,IntegerInterpolatePixel,
- u0,v0,pixel);
+ status=InterpolatePixelPacket(resample_filter->image,
+ resample_filter->view,IntegerInterpolatePixel,u0,v0,pixel,
+ resample_filter->exception);
return(status);
}
works well in general, but falls down for TileEdge methods.
This needs to be done properly!!!!!!
*/
- status=InterpolateResampleFilter(resample_filter,
- AverageInterpolatePixel,u0,v0,pixel);
+ status=InterpolatePixelPacket(resample_filter->image,
+ resample_filter->view,AverageInterpolatePixel,u0,v0,pixel,
+ resample_filter->exception);
break;
case HorizontalTileVirtualPixelMethod:
case VerticalTileVirtualPixelMethod:
/* just return the background pixel - Is there more direct way? */
- status=InterpolateResampleFilter(resample_filter,
- IntegerInterpolatePixel,(double)-1,(double)-1,pixel);
+ status=InterpolatePixelPacket(resample_filter->image,
+ resample_filter->view,IntegerInterpolatePixel,-1.0,-1.0,pixel,
+ resample_filter->exception);
break;
case TileVirtualPixelMethod:
case MirrorVirtualPixelMethod:
pixel->opacity = pixel->red = pixel->green = pixel->blue = 0;
pixel->red = QuantumRange; /* show pixels for which EWA fails */
#else
- status=InterpolateResampleFilter(resample_filter,
- resample_filter->interpolate,u0,v0,pixel);
+ status=InterpolatePixelPacket(resample_filter->image,
+ resample_filter->view,resample_filter->interpolate,u0,v0,pixel,
+ resample_filter->exception);
#endif
return status;
}
#include <magick/cache-view.h>
/*
- WARNING: The order of this table must also match the order
- of a table located in AcquireResizeFilter() or "resize.c"
- Otherwise the users filter will not match the actual filter
- that is setup.
+ WARNING: The order of this table must also match the order of a table
+ located in AcquireResizeFilter() or "resize.c" otherwise the users filter
+ will not match the actual filter that is setup.
*/
typedef enum
{
*/
#define BesselFilter JincFilter
-typedef enum
-{
- UndefinedInterpolatePixel,
- AverageInterpolatePixel,
- BicubicInterpolatePixel,
- BilinearInterpolatePixel,
- FilterInterpolatePixel,
- IntegerInterpolatePixel,
- MeshInterpolatePixel,
- NearestNeighborInterpolatePixel,
- SplineInterpolatePixel
-} InterpolatePixelMethod;
-
typedef struct _ResampleFilter
ResampleFilter;
#define AdaptiveResizeImageTag "Resize/Image"
CacheView
+ *image_view,
*resize_view;
Image
MagickOffsetType
progress;
- ResampleFilter
- **resample_filter;
-
ssize_t
y;
}
status=MagickTrue;
progress=0;
- resample_filter=AcquireResampleFilterThreadSet(image,
- UndefinedVirtualPixelMethod,MagickTrue,exception);
+ image_view=AcquireCacheView(image);
resize_view=AcquireCacheView(resize_image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
#endif
for (y=0; y < (ssize_t) resize_image->rows; y++)
{
- const int
- id = GetOpenMPThreadId();
-
MagickPixelPacket
pixel;
for (x=0; x < (ssize_t) resize_image->columns; x++)
{
offset.x=((MagickRealType) x*image->columns/resize_image->columns);
- (void) ResamplePixelColor(resample_filter[id],offset.x-0.5,offset.y-0.5,
- &pixel);
+ (void) InterpolatePixelPacket(image,image_view,image->interpolate,
+ offset.x-0.5,offset.y-0.5,&pixel,exception);
SetPixelPacket(resize_image,&pixel,q,resize_indexes+x);
q++;
}
status=MagickFalse;
}
}
- resample_filter=DestroyResampleFilterThreadSet(resample_filter);
resize_view=DestroyCacheView(resize_view);
+ image_view=DestroyCacheView(image_view);
if (status == MagickFalse)
resize_image=DestroyImage(resize_image);
return(resize_image);