% July 1992 %
% %
% %
-% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
#include "magick/pixel.h"
#include "magick/option.h"
#include "magick/resample.h"
+#include "magick/resample-private.h"
#include "magick/resize.h"
#include "magick/resize-private.h"
#include "magick/string_.h"
window_support, /* window support, usally equal to support (expert only) */
scale, /* dimension scaling to fit window support (usally 1.0) */
blur, /* x-scale (blur-sharpen) */
- coeff[7]; /* cubic coefficents for BC-cubic spline filters */
+ coefficient[7]; /* cubic coefficents for BC-cubic spline filters */
size_t
signature;
(slope).
*/
if (x < 1.0)
- return(resize_filter->coeff[0]+x*(x*
- (resize_filter->coeff[1]+x*resize_filter->coeff[2])));
+ return(resize_filter->coefficient[0]+x*(x*
+ (resize_filter->coefficient[1]+x*resize_filter->coefficient[2])));
if (x < 2.0)
- return(resize_filter->coeff[3]+x*(resize_filter->coeff[4]+x*
- (resize_filter->coeff[5]+x*resize_filter->coeff[6])));
+ return(resize_filter->coefficient[3]+x*(resize_filter->coefficient[4]+x*
+ (resize_filter->coefficient[5]+x*resize_filter->coefficient[6])));
return(0.0);
}
/*
Gaussian with a fixed sigma = 1/2
- Gaussian Formula...
- exp( -(x^2)/((2.0*sigma^2) ) / sqrt(2*PI*sigma^2)))
+ Gaussian Formula (1D) ...
+ exp( -(x^2)/((2.0*sigma^2) ) / sqrt(2*PI)sigma^2))
The constants are pre-calculated...
exp( -coeff[0]*(x^2)) ) * coeff[1]
However the multiplier coefficent (1) is not needed and not used.
- This separates the gaussian 'sigma' value from the 'blur/support' settings
- allowing for its use in special 'small sigma' gaussians, without the filter
- 'missing' pixels when blurring because the support is too small.
+ Gaussian Formula (2D) ...
+ exp( -(x^2)/((2.0*sigma^2) ) / (PI*sigma^2) )
+ Note that it is only a change in the normalization multiplier
+ which is not needed or used when gausian is used as a filter.
+
+ This separates the gaussian 'sigma' value from the 'blur/support'
+ settings allowing for its use in special 'small sigma' gaussians,
+ without the filter 'missing' pixels because the support becomes too
+ small.
*/
- return(exp((double)(-resize_filter->coeff[0]*x*x)));
+ return(exp((double)(-resize_filter->coefficient[0]*x*x)));
}
static MagickRealType Hanning(const MagickRealType x,
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% AcquireResizeFilter() allocates the ResizeFilter structure. Choose
-% from these filters:
+% AcquireResizeFilter() allocates the ResizeFilter structure. Choose from
+% these filters:
%
% FIR (Finite impulse Response) Filters
% Box Triangle Quadratic
% settings for that filter from a internal table. However any provided
% 'expert' settings (see below) may override this selection.
%
-% FIR filters are used as is, and are limited to that filters support
-% window (unless over-ridden). 'Gaussian' while classed as an IIR
-% filter, is also simply clipped by its support size (currently 1.5
-% or approximatally 3*sigma as recommended by many references)
-%
-% The special a 'cylindrical' filter flag will promote the default
-% 4-lobed Windowed Sinc filter to a 3-lobed Windowed Jinc equivelent,
-% which is better suited to this style of image resampling. This
-% typically happens when using such a filter for images distortions.
-%
-% Directly requesting 'Sinc', 'Jinc' function as a filter will force
-% the use of function without any windowing, or promotion for
-% cylindrical usage. This is not recommended, except by image
-% processing experts, especially as part of expert option filter
-% function selection.
-%
-% Two forms of the 'Sinc' function are available: Sinc and SincFast.
-% Sinc is computed using the traditional sin(pi*x)/(pi*x); it is
-% selected if the user specifically specifies the use of a Sinc
-% filter. SincFast uses highly accurate (and fast) polynomial (low Q)
-% and rational (high Q) approximations, and will be used by default in
-% most cases.
-%
-% Lanczos filter is a special 3-lobed Sinc windowed Sinc filter,
-% (or cylindrical promoted Jinc-Jinc filter). This filter is
-% probably the most popular windowed filter.
-%
-% LanczosSharp is a slightly sharpened (blur=0.98303932214489908)
-% form of the Lanczos filter. It was designed specifically for
-% cylindrical EWA (Elliptical Weighted Average) distortion (as a
-% Jinc-Jinc filter), but can used as a slightly sharper orthogonal
-% Lanczos (Sinc-Sinc) filter. The chosen blur value comes as close as
-% possible to satisfying the following condition without changing the
-% character of the corresponding EWA filter:
-%
-% 'No-Op' Vertical and Horizontal Line Preservation Condition:
-% Images with only vertical or horizontal features are preserved
-% when performing 'no-op" with EWA distortion.
-%
-% The Lanczos2 and Lanczos2Sharp filters are simply 2-lobe versions
-% of the Lanczos filters. The 'sharp' version uses a blur factor of
-% 0.958027803631219, again chosen because the resulting EWA filter
-% comes as close as possible to preserving vertical and horizontal
-% lines without changing its character. (There are other optimal
-% values; we use the least sharpening one).
-%
-% Robidoux is another filter tuned for EWA. It is the Keys cubic
-% filter defined by B=(228 - 108 sqrt(2))/199. Robidoux satisfies the
-% "'No-Op' Vertical and Horizontal Line Preservation Condition"
-% exactly. It also seems to provide only minimal bluring of a low
-% level 'pixel-hash' pattern in the 'No-Op Distort' case. It turns
-% out to be close to both plain Mitchell and Lanczos2Sharp filters.
-% For example, its first crossing is at (36 sqrt(2) + 123)/(72
-% sqrt(2) + 47) which is almost the same as the first crossing
-% of the other two.
-%
+% FIR filters are used as is, and are limited to that filters support window
+% (unless over-ridden). 'Gaussian' while classed as an IIR filter, is also
+% simply clipped by its support size (currently 1.5 or approximatally 3*sigma
+% as recommended by many references)
+%
+% The special a 'cylindrical' filter flag will promote the default 4-lobed
+% Windowed Sinc filter to a 3-lobed Windowed Jinc equivelent, which is better
+% suited to this style of image resampling. This typically happens when using
+% such a filter for images distortions.
+%
+% Directly requesting 'Sinc', 'Jinc' function as a filter will force the use
+% of function without any windowing, or promotion for cylindrical usage. This
+% is not recommended, except by image processing experts, especially as part
+% of expert option filter function selection.
+%
+% Two forms of the 'Sinc' function are available: Sinc and SincFast. Sinc is
+% computed using the traditional sin(pi*x)/(pi*x); it is selected if the user
+% specifically specifies the use of a Sinc filter. SincFast uses highly
+% accurate (and fast) polynomial (low Q) and rational (high Q) approximations,
+% and will be used by default in most cases.
+%
+% The Lanczos filter is a special 3-lobed Sinc-windowed Sinc filter (promoted
+% to Jinc-windowed Jinc for cylindrical (Elliptical Weighted Average) use).
+% The Sinc version is the most popular windowed filter.
+%
+% LanczosSharp is a slightly sharpened (blur=0.9812505644269356 < 1) form of
+% the Lanczos filter, specifically designed for EWA distortion (as a
+% Jinc-Jinc); it can also be used as a slightly sharper orthogonal Lanczos
+% (Sinc-Sinc) filter. The chosen blur value comes as close as possible to
+% satisfying the following condition without changing the character of the
+% corresponding EWA filter:
+%
+% 'No-Op' Vertical and Horizontal Line Preservation Condition: Images with
+% only vertical or horizontal features are preserved when performing 'no-op"
+% with EWA distortion.
+%
+% The Lanczos2 and Lanczos2Sharp filters are 2-lobe versions of the Lanczos
+% filters. The 'sharp' version uses a blur factor of 0.9549963639785485,
+% again chosen because the resulting EWA filter comes as close as possible to
+% satisfying the above condition.
+%
+% Robidoux is another filter tuned for EWA. It is the Keys cubic filter
+% defined by B=(228 - 108 sqrt(2))/199. Robidoux satisfies the "'No-Op'
+% Vertical and Horizontal Line Preservation Condition" exactly, and it
+% moderately blurs high frequency 'pixel-hash' patterns under no-op. It turns
+% out to be close to both Mitchell and Lanczos2Sharp. For example, its first
+% crossing is at (36 sqrt(2) + 123)/(72 sqrt(2) + 47), almost the same as the
+% first crossing of Mitchell and Lanczos2Sharp.
%
% 'EXPERT' OPTIONS:
%
-% These artifact "defines" are not recommended for production use
-% without expert knowledge of resampling, filtering, and the effects
-% they have on the resulting resampled (resize ro distorted) image.
+% These artifact "defines" are not recommended for production use without
+% expert knowledge of resampling, filtering, and the effects they have on the
+% resulting resampled (resize ro distorted) image.
%
% They can be used to override any and all filter default, and it is
-% recommended you make good use of "filter:verbose" to make sure that
-% the overall effect of your selection (before and after) is as
-% expected.
-%
-% "filter:verbose" controls whether to output the exact results of
-% the filter selections made, as well as plotting data for
-% graphing the resulting filter over the filters support range.
-%
-% "filter:filter" Select the main function associated with
-% this filter name, as the weighting function of the filter.
-% This can be used to set a windowing function as a weighting
-% function, for special purposes, such as graphing.
-%
-% If a "filter:window" operation has not been provided, then a
-% 'Box' windowing function will be set to denote that no
-% windowing function is being used.
-%
-% "filter:window" Select this windowing function for the filter.
-% While any filter could be used as a windowing function, using
-% the 'first lobe' of that filter over the whole support
-% window, using a non-windowing function is not advisible. If
-% no weighting filter function is specifed a 'SincFast' filter
-% will be used.
-%
-% "filter:lobes" Number of lobes to use for the Sinc/Jinc filter.
-% This a simpler method of setting filter support size that
-% will correctly handle the Sinc/Jinc switch for an operators
-% filtering requirements. Only integers should be given.
-%
-% "filter:support" Set the support size for filtering to the size
-% given This not recommended for Sinc/Jinc windowed filters
-% (lobes should be used instead). This will override any
-% 'filter:lobes' option.
-%
-% "filter:win-support" Scale windowing function to this size
-% instead. This causes the windowing (or self-windowing
-% Lagrange filter) to act is if the support window it much much
-% larger than what is actually supplied to the calling
-% operator. The filter however is still clipped to the real
-% support size given, by the support range suppiled to the
-% caller. If unset this will equal the normal filter support
-% size.
-%
-% "filter:blur" Scale the filter and support window by this amount.
-% A value >1 will generally result in a more burred image with
-% more ringing effects, while a value <1 will sharpen the
-% resulting image with more aliasing effects.
-%
-% "filter:sigma" The sigma value to use for the Gaussian filter
-% only. Defaults to '1/2' for orthogonal and 'sqrt(2)/2' for
-% cylindrical usage. It effectially provides a alturnative to
-% 'blur' for Gaussians without it also effecting the final
-% 'practical support' size.
+% recommended you make good use of "filter:verbose" to make sure that the
+% overall effect of your selection (before and after) is as expected.
+%
+% "filter:verbose" controls whether to output the exact results of the
+% filter selections made, as well as plotting data for graphing the
+% resulting filter over the filters support range.
+%
+% "filter:filter" select the main function associated with this filter
+% name, as the weighting function of the filter. This can be used to
+% set a windowing function as a weighting function, for special
+% purposes, such as graphing.
+%
+% If a "filter:window" operation has not been provided, a 'Box'
+% windowing function will be set to denote that no windowing function is
+% being used.
+%
+% "filter:window" Select this windowing function for the filter. While any
+% filter could be used as a windowing function, using the 'first lobe' of
+% that filter over the whole support window, using a non-windowing
+% function is not advisible. If no weighting filter function is specifed
+% a 'SincFast' filter is used.
+%
+% "filter:lobes" Number of lobes to use for the Sinc/Jinc filter. This a
+% simpler method of setting filter support size that will correctly
+% handle the Sinc/Jinc switch for an operators filtering requirements.
+% Only integers should be given.
+%
+% "filter:support" Set the support size for filtering to the size given.
+% This not recommended for Sinc/Jinc windowed filters (lobes should be
+% used instead). This will override any 'filter:lobes' option.
+%
+% "filter:win-support" Scale windowing function to this size instead. This
+% causes the windowing (or self-windowing Lagrange filter) to act is if
+% the support window it much much larger than what is actually supplied
+% to the calling operator. The filter however is still clipped to the
+% real support size given, by the support range suppiled to the caller.
+% If unset this will equal the normal filter support size.
+%
+% "filter:blur" Scale the filter and support window by this amount. A value
+% > 1 will generally result in a more burred image with more ringing
+% effects, while a value <1 will sharpen the resulting image with more
+% aliasing effects.
+%
+% "filter:sigma" The sigma value to use for the Gaussian filter only.
+% Defaults to '1/2'. Using a different sigma effectively provides a
+% method of using the filter as a 'blur' convolution. Particularly when
+% using it for Distort.
%
% "filter:b"
-% "filter:c" Override the preset B,C values for a Cubic type of
-% filter If only one of these are given it is assumes to be a
-% 'Keys' type of filter such that B+2C=1, where Keys 'alpha'
-% value = C
+% "filter:c" Override the preset B,C values for a Cubic type of filter.
+% If only one of these are given it is assumes to be a 'Keys' type of
+% filter such that B+2C=1, where Keys 'alpha' value = C.
%
% Examples:
%
% -filter Lanczos
% -define filter:lobes=8
%
-%
% The format of the AcquireResizeFilter method is:
%
% ResizeFilter *AcquireResizeFilter(const Image *image,
%
% o image: the image.
%
-% o filter: the filter type, defining a preset filter, window and
-% support. The artifact settings listed above will override
-% those selections.
+% o filter: the filter type, defining a preset filter, window and support.
+% The artifact settings listed above will override those selections.
%
% o blur: blur the filter by this amount, use 1.0 if unknown. Image
-% artifact "filter:blur" will override this API call usage, including
-% any internal change (such as for cylindrical usage).
+% artifact "filter:blur" will override this API call usage, including any
+% internal change (such as for cylindrical usage).
%
-% o radial: use a 1D orthogonal filter (Sinc) or 2D cylindrical
-% (radial) filter (Jinc)
+% o radial: use a 1D orthogonal filter (Sinc) or 2D cylindrical (radial)
+% filter (Jinc).
%
% o exception: return any errors or warnings in this structure.
%
register ResizeFilter
*resize_filter;
-
/*
- Table Mapping given Filter, into Weighting and Windowing functions.
- A 'Box' windowing function means its a simble non-windowed filter.
- An 'SincFast' filter function could be upgraded to a 'Jinc' filter
- if a "cylindrical", unless a 'Sinc' or 'SincFast' filter was
- specifically requested.
+ Table Mapping given Filter, into Weighting and Windowing functions. A
+ 'Box' windowing function means its a simble non-windowed filter. An
+ 'SincFast' filter function could be upgraded to a 'Jinc' filter if a
+ "cylindrical", unless a 'Sinc' or 'SincFast' filter was specifically
+ requested.
- WARNING: The order of this tabel must match the order of the
- FilterTypes enumeration specified in "resample.h", or the filter
- names will not match the filter being setup.
+ WARNING: The order of this tabel must match the order of the FilterTypes
+ enumeration specified in "resample.h", or the filter names will not match
+ the filter being setup.
You can check filter setups with the "filter:verbose" setting.
*/
{ RobidouxFilter, BoxFilter }, /* Cubic Keys tuned for EWA */
};
/*
- Table mapping the filter/window from the above table to an actual
- function. The default support size for that filter as a weighting
- function, the range to scale with to use that function as a sinc
- windowing function, (typ 1.0).
+ Table mapping the filter/window from the above table to an actual function.
+ The default support size for that filter as a weighting function, the range
+ to scale with to use that function as a sinc windowing function, (typ 1.0).
Note that the filter_type -> function is 1 to 1 except for Sinc(),
- SincFast(), and CubicBC() functions, which may have multiple
- filter to function associations.
+ SincFast(), and CubicBC() functions, which may have multiple filter to
+ function associations.
- See "filter:verbose" handling below for the function -> filter
- mapping.
+ See "filter:verbose" handling below for the function -> filter mapping.
*/
static struct
{
/*
The known zero crossings of the Jinc() or more accurately the Jinc(x*PI)
function being used as a filter. It is used by the "filter:lobes" expert
- setting and for 'lobes' for Jinc functions in the previous table. This
- way users do not have to deal with the highly irrational lobe sizes of the
- Jinc filter.
+ setting and for 'lobes' for Jinc functions in the previous table. This way
+ users do not have to deal with the highly irrational lobe sizes of the Jinc
+ filter.
Values taken from
- http://cose.math.bas.bg/webMathematica/webComputing/BesselZeros.jsp
- using Jv-function with v=1, then dividing by PI.
+ http://cose.math.bas.bg/webMathematica/webComputing/BesselZeros.jsp using
+ Jv-function with v=1, then dividing by PI.
*/
static MagickRealType
jinc_zeros[16] =
*/
filter_type=mapping[filter].filter;
window_type=mapping[filter].window;
- resize_filter->blur = blur;
- sigma = 0.5;
+ resize_filter->blur = blur; /* function argument blur factor */
+ sigma = 0.5; /* guassian sigma of half a pixel by default */
/* Promote 1D Windowed Sinc Filters to a 2D Windowed Jinc filters */
if (cylindrical != MagickFalse && filter_type == SincFastFilter
&& filter != SincFastFilter )
{
ssize_t
option;
- option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
+
+ option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
if ((UndefinedFilter < option) && (option < SentinelFilter))
{ /* Raw filter request - no window function. */
filter_type=(FilterTypes) option;
artifact=GetImageArtifact(image,"filter:window");
if (artifact != (const char *) NULL)
{
- option=ParseMagickOption(MagickFilterOptions,MagickFalse,artifact);
+ option=ParseCommandOption(MagickFilterOptions,MagickFalse,artifact);
if ((UndefinedFilter < option) && (option < SentinelFilter))
window_type=(FilterTypes) option;
}
{
ssize_t
option;
- option=ParseMagickOption(MagickFilterOptions,MagickFalse,
+
+ option=ParseCommandOption(MagickFilterOptions,MagickFalse,
artifact);
if ((UndefinedFilter < option) && (option < SentinelFilter))
{
resize_filter->scale=filters[JincFilter].scale;
/* number of lobes (support window size) remain unchanged */
break;
- case GaussianFilter:
- /* Cylindrical Gaussian sigma is sqrt(2)/2. */
- sigma = (MagickRealType) (MagickSQ2/2.0);
- break;
default:
break;
}
switch (filter_type)
{
case LanczosSharpFilter:
- resize_filter->blur *= 0.98303932214489908;
+ resize_filter->blur *= 0.9812505644269356;
break;
case Lanczos2SharpFilter:
- resize_filter->blur *= 0.958027803631219;
+ resize_filter->blur *= 0.9549963639785485;
break;
default:
break;
artifact=GetImageArtifact(image,"filter:sigma");
if (artifact != (const char *) NULL)
sigma=StringToDouble(artifact);
- /* Define coefficents for Gaussian (assumes no cubic window) */
+ /* Define coefficents for Gaussian */
if ( GaussianFilter ) {
- resize_filter->coeff[0] = 1.0/(2.0*sigma*sigma);
- resize_filter->coeff[1] = (MagickRealType) (1.0/(Magick2PI*sigma*sigma)); /* unused */
+ resize_filter->coefficient[0]=1.0/(2.0*sigma*sigma);
+ resize_filter->coefficient[1]=(MagickRealType) (1.0/(Magick2PI*sigma*
+ sigma)); /* Normalization Multiplier - unneeded for filters */
}
/* Blur Override */
artifact=GetImageArtifact(image,"filter:blur");
if (artifact != (const char *) NULL)
- resize_filter->blur=StringToDouble(artifact);
+ resize_filter->blur *= StringToDouble(artifact);
if (resize_filter->blur < MagickEpsilon)
resize_filter->blur=(MagickRealType) MagickEpsilon;
/* Convert B,C values into Cubic Coefficents. See CubicBC(). */
{
const double twoB = B+B;
- resize_filter->coeff[0]=1.0-(1.0/3.0)*B;
- resize_filter->coeff[1]=-3.0+twoB+C;
- resize_filter->coeff[2]=2.0-1.5*B-C;
- resize_filter->coeff[3]=(4.0/3.0)*B+4.0*C;
- resize_filter->coeff[4]=-8.0*C-twoB;
- resize_filter->coeff[5]=B+5.0*C;
- resize_filter->coeff[6]=(-1.0/6.0)*B-C;
+ resize_filter->coefficient[0]=1.0-(1.0/3.0)*B;
+ resize_filter->coefficient[1]=-3.0+twoB+C;
+ resize_filter->coefficient[2]=2.0-1.5*B-C;
+ resize_filter->coefficient[3]=(4.0/3.0)*B+4.0*C;
+ resize_filter->coefficient[4]=-8.0*C-twoB;
+ resize_filter->coefficient[5]=B+5.0*C;
+ resize_filter->coefficient[6]=(-1.0/6.0)*B-C;
}
}
if (resize_filter->filter == SincFast) filter_type=SincFastFilter;
if (resize_filter->filter == Jinc) filter_type=JincFilter;
if (resize_filter->filter == CubicBC) filter_type=CubicFilter;
- if (resize_filter->filter == Box) window_type=BoxFilter;
+ if (resize_filter->window == Box) window_type=BoxFilter;
if (resize_filter->window == Sinc) window_type=SincFilter;
if (resize_filter->window == SincFast) window_type=SincFastFilter;
- if (resize_filter->filter == Jinc) window_type=JincFilter;
+ if (resize_filter->window == Jinc) window_type=JincFilter;
if (resize_filter->window == CubicBC) window_type=CubicFilter;
/*
Report Filter Details.
support=GetResizeFilterSupport(resize_filter); /* practical_support */
(void) fprintf(stdout,"# Resize Filter (for graphing)\n#\n");
(void) fprintf(stdout,"# filter = %s\n",
- MagickOptionToMnemonic(MagickFilterOptions,filter_type));
+ CommandOptionToMnemonic(MagickFilterOptions,filter_type));
(void) fprintf(stdout,"# window = %s\n",
- MagickOptionToMnemonic(MagickFilterOptions, window_type));
+ CommandOptionToMnemonic(MagickFilterOptions, window_type));
(void) fprintf(stdout,"# support = %.*g\n",
GetMagickPrecision(),(double) resize_filter->support);
(void) fprintf(stdout,"# win-support = %.*g\n",
#define AdaptiveResizeImageTag "Resize/Image"
CacheView
+ *image_view,
*resize_view;
Image
*resize_image;
MagickBooleanType
- proceed;
-
- MagickPixelPacket
- pixel;
-
- PointInfo
- offset;
+ status;
- ResampleFilter
- *resample_filter;
+ MagickOffsetType
+ progress;
ssize_t
y;
resize_image=DestroyImage(resize_image);
return((Image *) NULL);
}
- GetMagickPixelPacket(image,&pixel);
- resample_filter=AcquireResampleFilter(image,exception);
- (void) SetResampleFilter(resample_filter,PointFilter,1.0);
- (void) SetResampleFilterInterpolateMethod(resample_filter,
- MeshInterpolatePixel);
+ status=MagickTrue;
+ progress=0;
+ 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++)
{
+ MagickPixelPacket
+ pixel;
+
+ PointInfo
+ offset;
+
register IndexPacket
*restrict resize_indexes;
- register ssize_t
- x;
-
register PixelPacket
*restrict q;
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
q=QueueCacheViewAuthenticPixels(resize_view,0,y,resize_image->columns,1,
exception);
if (q == (PixelPacket *) NULL)
- break;
+ continue;
resize_indexes=GetCacheViewAuthenticIndexQueue(resize_view);
- offset.y=((MagickRealType) y*image->rows/resize_image->rows);
+ offset.y=((MagickRealType) (y+0.5)*image->rows/resize_image->rows);
+ GetMagickPixelPacket(image,&pixel);
for (x=0; x < (ssize_t) resize_image->columns; x++)
{
- offset.x=((MagickRealType) x*image->columns/resize_image->columns);
- (void) ResamplePixelColor(resample_filter,offset.x-0.5,offset.y-0.5,
- &pixel);
+ offset.x=((MagickRealType) (x+0.5)*image->columns/resize_image->columns);
+ (void) InterpolateMagickPixelPacket(image,image_view,
+ MeshInterpolatePixel,offset.x-0.5,offset.y-0.5,&pixel,exception);
SetPixelPacket(resize_image,&pixel,q,resize_indexes+x);
q++;
}
if (SyncCacheViewAuthenticPixels(resize_view,exception) == MagickFalse)
- break;
- proceed=SetImageProgress(image,AdaptiveResizeImageTag,(MagickOffsetType) y,
- image->rows);
- if (proceed == MagickFalse)
- break;
+ continue;
+ if (image->progress_monitor != (MagickProgressMonitor) NULL)
+ {
+ MagickBooleanType
+ proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp critical (MagickCore_AdaptiveResizeImage)
+#endif
+ proceed=SetImageProgress(image,AdaptiveResizeImageTag,progress++,
+ image->rows);
+ if (proceed == MagickFalse)
+ status=MagickFalse;
+ }
}
- resample_filter=DestroyResampleFilter(resample_filter);
resize_view=DestroyCacheView(resize_view);
+ image_view=DestroyCacheView(image_view);
+ if (status == MagickFalse)
+ resize_image=DestroyImage(resize_image);
return(resize_image);
}
\f
{
MagickRealType
scale,
+ weight,
x_blur;
/*
scale=resize_filter->scale;
scale=resize_filter->window(x_blur*scale,resize_filter);
}
- return(scale*resize_filter->filter(x_blur,resize_filter));
+ weight=scale*resize_filter->filter(x_blur,resize_filter);
+ return(weight);
}
\f
/*
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,
- 1.0,exception);
+ minify_image=ResizeImage(image,image->columns/2,image->rows/2,CubicFilter,1.0,
+ exception);
return(minify_image);
}
\f
pixel.index+=alpha*indexes[j];
}
resize_indexes[y]=(IndexPacket) ClampToQuantum(gamma*
- GetIndexPixelComponent(&pixel));
+ GetIndexPixelComponent(&pixel));
}
}
if ((resize_image->storage_class == PseudoClass) &&
exception);
if (q == (PixelPacket *) NULL)
break;
- scale_indexes=GetAuthenticIndexQueue(scale_image);
+ scale_indexes=GetCacheViewAuthenticIndexQueue(scale_view);
if (scale_image->rows == image->rows)
{
/*