This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via 59508f340d3fd1d02e11371c913d4e7656f8ce4f (commit) via c99c44f51072de292b49f4d0ba38d0e9caa82def (commit) from 947b2af03a9283240687cdfb2ecc4e855893ad9a (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/59508f340d3fd1d02e11371c913d4e7656f8c...
commit 59508f340d3fd1d02e11371c913d4e7656f8ce4f Author: Cyril Hrubis metan@ucw.cz Date: Tue Aug 20 00:58:57 2013 +0200
filters: Cleanup Resize filters + docs.
This is a major cleanup in resize filters implementation.
The only visible change is that the GP_FilterResize() is split into allocating and non-allocating filter (as rest of the API was quite a time ago). The rest of the changes mostly shuffles code and headers.
This commit also fixes the python wrappings for resize filters.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/build/syms/Filters_symbols.txt b/build/syms/Filters_symbols.txt index f523674..839c437 100644 --- a/build/syms/Filters_symbols.txt +++ b/build/syms/Filters_symbols.txt @@ -75,8 +75,6 @@ GP_FilterHistogram GP_FilterHistogramAlloc GP_FilterHistogram_Raw
-GP_FilterInterpolate_Cubic - GP_FilterInvert GP_FilterInvert_Raw
@@ -137,23 +135,13 @@ GP_FilterPoint GP_FilterPoint_Raw
GP_FilterResize -GP_FilterResize_Raw +GP_FilterResizeAlloc
GP_FilterResizeLinearInt -GP_FilterResizeLinearIntAlloc -GP_FilterResizeLinearInt_Raw - GP_FilterResizeLinearLFInt -GP_FilterResizeLinearLFIntAlloc -GP_FilterResizeLinearLFInt_Raw - -GP_FilterResizeCubicInt -GP_FilterResizeCubicIntAlloc -GP_FilterResizeCubicInt_Raw - GP_FilterResizeNN -GP_FilterResizeNNAlloc -GP_FilterResizeNN_Raw +GP_FilterResizeCubicInt +GP_FilterResizeCubic
GP_FilterRotate180 GP_FilterRotate180Alloc diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 6bdf006..d81cf9f 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -124,7 +124,7 @@ static int resize(GP_Context **c, const char *params) GP_Size h = ratio * (*c)->h; GP_Context *res = NULL;
- res = GP_FilterResize(*c, NULL, alg, w, h, progress_callback); + res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
if (res == NULL) return EINVAL; @@ -187,7 +187,7 @@ static int scale(GP_Context **c, const char *params)
GP_Context *res = NULL;
- res = GP_FilterResize(*c, NULL, alg, w, h, progress_callback); + res = GP_FilterResizeAlloc(*c, alg, w, h, progress_callback);
if (res == NULL) return EINVAL; @@ -986,6 +986,10 @@ static void save_by_fmt(struct GP_Context *bitmap, const char *name, const char ret = GP_SaveJPG(bitmap, name, progress_callback); else if (!strcmp(fmt, "png")) ret = GP_SavePNG(bitmap, name, progress_callback); + else { + printf("Invalid format %sn", fmt); + exit(1); + }
if (ret) { fprintf(stderr, "Failed to save bitmap: %sn", diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c index 66284ba..1736b4d 100644 --- a/demos/spiv/spiv.c +++ b/demos/spiv/spiv.c @@ -437,8 +437,8 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size cpu_timer_start(&timer, "Blur"); callback.priv = "Blurring Image";
- res = GP_FilterGaussianBlurAlloc(img, 0.3/params->rat, - 0.3/params->rat, &callback); + res = GP_FilterGaussianBlurAlloc(img, 0.4/params->rat, + 0.4/params->rat, &callback);
if (res == NULL) return NULL; @@ -452,9 +452,9 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
cpu_timer_start(&timer, "Resampling"); callback.priv = "Resampling Image"; - GP_Context *i1 = GP_FilterResize(img, NULL, params->resampling_method, w, h, &callback); + GP_Context *i1 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback); // img->gamma = NULL; -// GP_Context *i2 = GP_FilterResize(img, NULL, params->resampling_method, w, h, &callback); +// GP_Context *i2 = GP_FilterResizeAlloc(img, params->resampling_method, w, h, &callback); // img = GP_FilterDifferenceAlloc(i2, i1, NULL); // img = GP_FilterInvert(img, NULL, NULL); img = i1; @@ -844,7 +844,8 @@ int main(int argc, char *argv[])
if (params.resampling_method > GP_INTERP_MAX) params.resampling_method = 0; - + if (params.resampling_method == GP_INTERP_CUBIC) + params.resampling_method++; if (params.resampling_method == GP_INTERP_LINEAR_LF_INT) { params.use_low_pass = 0; params.show_nn_first = 0; @@ -861,7 +862,8 @@ int main(int argc, char *argv[]) params.resampling_method = GP_INTERP_MAX; else params.resampling_method--; - + if (params.resampling_method == GP_INTERP_CUBIC) + params.resampling_method--; if (params.resampling_method == GP_INTERP_LINEAR_LF_INT) { params.use_low_pass = 0; params.show_nn_first = 0; diff --git a/doc/Makefile b/doc/Makefile index cf80c1c..9ec16a1 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -3,7 +3,7 @@ SOURCES=general.txt context.txt loaders.txt filters.txt basic_types.txt environment_variables.txt debug.txt core.txt api.txt input.txt gen.txt pixels.txt coordinate_system.txt coding_style.txt get_put_pixel.txt blits.txt progress_callback.txt text_api.txt - event_queue.txt compilation.txt + event_queue.txt compilation.txt filters_resize.txt SOURCES+=core_python.txt gfx_python.txt loaders_python.txt backends_python.txt
diff --git a/doc/filters.txt b/doc/filters.txt index 106be48..c456bf5 100644 --- a/doc/filters.txt +++ b/doc/filters.txt @@ -874,35 +874,7 @@ filter before image is resampled non proportionally. Interpolation filters ~~~~~~~~~~~~~~~~~~~~~
-[source,c] -------------------------------------------------------------------------------- -#include <GP_Filters.h> - -typedef enum GP_InterpolationType { - GP_INTERP_NN, /* Nearest Neighbour */ - GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */ - GP_INTERP_LINEAR_LF_INT, /* Bilinear + low pass filter on downscaling */ - GP_INTERP_CUBIC, /* Bicubic */ - GP_INTERP_CUBIC_INT, /* Bicubic - fixed point arithmetics */ - GP_INTERP_MAX = GP_INTERP_CUBIC_INT, -} GP_InterpolationType; - -GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback); -------------------------------------------------------------------------------- - -Interpolate (resize) the context. - -Doesn't work 'in-place' (this is quite impossible as the size of the bitmap is -changed by the filter). - -If the filter destination is non 'NULL' and the 'w' and 'h' is smaller than the -destination size the source image is interpolated into sub-context of -destination defined by 'w' and 'h'. - -'TODO:' this filter is implemented for RGB888 only. +Filters to link:filters_resize.html[resize image].
Nearest Neighbour Interpolation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/filters_resize.txt b/doc/filters_resize.txt new file mode 100644 index 0000000..0331077 --- /dev/null +++ b/doc/filters_resize.txt @@ -0,0 +1,139 @@ +Resize filters +-------------- + +Common API +~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------------------- +#include <GP.h> +/* or */ +#include <filters/GP_Resize.h> + +typedef enum GP_InterpolationType { + GP_INTERP_NN, /* Nearest Neighbour */ + GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */ + GP_INTERP_LINEAR_LF_INT, /* Bilinear + low pass filter on downscaling */ + GP_INTERP_CUBIC, /* Bicubic */ + GP_INTERP_CUBIC_INT, /* Bicubic - fixed point arithmetics */ + GP_INTERP_MAX = GP_INTERP_CUBIC_INT, +} GP_InterpolationType; + +const char *GP_InterpolationTypeName(enum GP_InterpolationType interp_type); + +int GP_FilterResize(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterResizeAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_InterpolationType type, + GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Interpolate (resize) the context. + +Resize image given size and interpolation type. + +GP_FilterResize +^^^^^^^^^^^^^^^ + +The +GP_FilterReize()+ function resizes 'src' to fit 'dst' exactly. + +Both 'src' and 'dst' must have the same pixel type. + +Returns zero on success, non-zero on failure and sets 'errno'. + +GP_FilterResizeAlloc +^^^^^^^^^^^^^^^^^^^^ + +The +GP_FilterResizeAlloc()+ allocates the destination give it's size. + +Returns pointer to newly allocated context or 'NULL' in case of failure and +'errno' is set. + +Nearest Neighbour Interpolation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------------------- +#include <GP.h> +/* or */ +#include <filters/GP_ResizeNN.h> + +int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +static inline GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Pixel value is choosen as value of the closest pixel in the source bitmap +(after destination coodinates are mapped to the source coordinates). + +Fast, but produces "pixelated" images. May however work better for images with +sharp edges mostly consisting of big one color regions (it doesn't blur the +result on upscaling). + +Is commonly used to show preview before you resample the image correctly. + +Bilinear Interpolation +~~~~~~~~~~~~~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------------------- +#include <GP.h> +/* or */ +#include <filters/GP_ResizeLinear.h> + +int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Bilinear is faster than bicubic interpolation and produces quite good results +especially the low pass (LF) variant doesn't need additional low-pass filter +on down-sampling. + +Bicubic Interpolation +~~~~~~~~~~~~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------------------- +#include <GP.h> +/* or */ +#include <filters/GP_ResizeCubic.h> + +int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterResizeCubicAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Works well as is on image upscaling. To get decent result on downscaling +low-pass filter (Gaussian blur) must be used on original image before actual +downscaling. + +To do this reasonably fast we could cheat a little: first resize big images a +little without the low-pass filter, then apply low-pass filter and finally +downscale it to desired size. diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h index f79c2d2..621d232 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_Filters.h @@ -58,6 +58,9 @@
/* Image scaling (resampling) */ #include "filters/GP_Resize.h" +#include "filters/GP_ResizeNN.h" +#include "filters/GP_ResizeLinear.h" +#include "filters/GP_ResizeCubic.h"
/* Bitmap dithering */ #include "filters/GP_Dither.h" diff --git a/include/filters/GP_Resize.h b/include/filters/GP_Resize.h index 31b96a0..179d88c 100644 --- a/include/filters/GP_Resize.h +++ b/include/filters/GP_Resize.h @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
@@ -56,15 +56,6 @@
#include "GP_Filter.h"
-/* Nearest Neighbour */ -int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); - -GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback); - - typedef enum GP_InterpolationType { GP_INTERP_NN, /* Nearest Neighbour */ GP_INTERP_LINEAR_INT, /* Bilinear - fixed point arithmetics */ @@ -84,18 +75,24 @@ int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback);
/* - * If destination is non NULL, the w and h are used to create subcontext from - * destination which is then used to interpolate the image to. + * Resize src to fit the dst, both src and dst must have the same pixel_type. + * + * Returns non-zero on error (interrupted from callback), zero on success. + */ +int GP_FilterResize(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback); + +/* + * Resize src to wxh, the result is allocated. * - * Otherwise if destination is NULL, the context of size w and h is allocated - * and returned. + * Returns pointer to newly created context. * - * In both cases the pointer to destination or NULL in case of failure is - * returned. + * Returns NULL in case of failure and errno is set correspondinlgy. */ -GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback); +GP_Context *GP_FilterResizeAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_InterpolationType type, + GP_ProgressCallback *callback);
#endif /* FILTERS_GP_RESIZE_H */ diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeCubic.h similarity index 53% copy from include/filters/GP_Filters.h copy to include/filters/GP_ResizeCubic.h index f79c2d2..ebbab41 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_ResizeCubic.h @@ -16,65 +16,40 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- GP_Context filters. + Bicubic interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H -#define FILTERS_GP_FILTERS_H - -/* Filter per channel parameter passing interface */ -#include "filters/GP_FilterParam.h" - -/* Point filters, brightness, contrast ... */ -#include "filters/GP_Point.h" - -/* Addition, difference, min, max ... */ -#include "filters/GP_Arithmetic.h" - -/* Histograms, ... */ -#include "filters/GP_Stats.h" - -/* Image rotations (90 180 270 grads) and mirroring */ -#include "filters/GP_Rotate.h" - -/* Linear convolution Raw API */ -#include "filters/GP_Linear.h" - -/* Convolution filters */ -#include "filters/GP_Convolution.h" - -/* Blur filters */ -#include "filters/GP_Blur.h" - -/* Image scaling (resampling) */ -#include "filters/GP_Resize.h" - -/* Bitmap dithering */ -#include "filters/GP_Dither.h" +#ifndef FILTERS_GP_RESIZE_CUBIC_H +#define FILTERS_GP_RESIZE_CUBIC_H
-/* Laplace based filters */ -#include "filters/GP_Laplace.h" +#include "GP_Filter.h" +#include "GP_Resize.h"
-/* Median filter */ -#include "filters/GP_Median.h" +int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-/* Weighted Median filter */ -#include "filters/GP_WeightedMedian.h" +int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-/* Sigma Mean filter */ -#include "filters/GP_Sigma.h" +static inline GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + return GP_FilterResizeAlloc(src, w, h, GP_INTERP_CUBIC_INT, callback); +}
-/* Gaussian noise filter */ -#include "filters/GP_GaussianNoise.h" +static inline GP_Context *GP_FilterResizeCubicAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + return GP_FilterResizeAlloc(src, w, h, GP_INTERP_CUBIC, callback); +}
-#endif /* FILTERS_GP_FILTERS_H */ +#endif /* FILTERS_GP_RESIZE_CUBIC_H */ diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeLinear.h similarity index 53% copy from include/filters/GP_Filters.h copy to include/filters/GP_ResizeLinear.h index f79c2d2..5506751 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_ResizeLinear.h @@ -16,65 +16,40 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- GP_Context filters. + Bilinear interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H -#define FILTERS_GP_FILTERS_H - -/* Filter per channel parameter passing interface */ -#include "filters/GP_FilterParam.h" - -/* Point filters, brightness, contrast ... */ -#include "filters/GP_Point.h" - -/* Addition, difference, min, max ... */ -#include "filters/GP_Arithmetic.h" - -/* Histograms, ... */ -#include "filters/GP_Stats.h" - -/* Image rotations (90 180 270 grads) and mirroring */ -#include "filters/GP_Rotate.h" - -/* Linear convolution Raw API */ -#include "filters/GP_Linear.h" - -/* Convolution filters */ -#include "filters/GP_Convolution.h" - -/* Blur filters */ -#include "filters/GP_Blur.h" - -/* Image scaling (resampling) */ -#include "filters/GP_Resize.h" - -/* Bitmap dithering */ -#include "filters/GP_Dither.h" +#ifndef FILTERS_GP_RESIZE_LINEAR_H +#define FILTERS_GP_RESIZE_LINEAR_H
-/* Laplace based filters */ -#include "filters/GP_Laplace.h" +#include "GP_Filter.h" +#include "GP_Resize.h"
-/* Median filter */ -#include "filters/GP_Median.h" +int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-/* Weighted Median filter */ -#include "filters/GP_WeightedMedian.h" +int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-/* Sigma Mean filter */ -#include "filters/GP_Sigma.h" +static inline GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + return GP_FilterResizeAlloc(src, w, h, GP_INTERP_LINEAR_INT, callback); +}
-/* Gaussian noise filter */ -#include "filters/GP_GaussianNoise.h" +static inline GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + return GP_FilterResizeAlloc(src, w, h, GP_INTERP_LINEAR_LF_INT, callback); +}
-#endif /* FILTERS_GP_FILTERS_H */ +#endif /* FILTERS_GP_RESIZE_LINEAR_H */ diff --git a/include/filters/GP_Filters.h b/include/filters/GP_ResizeNN.h similarity index 53% copy from include/filters/GP_Filters.h copy to include/filters/GP_ResizeNN.h index f79c2d2..d511702 100644 --- a/include/filters/GP_Filters.h +++ b/include/filters/GP_ResizeNN.h @@ -16,65 +16,30 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- GP_Context filters. + Nearest neighbour interpolation.
*/
-#ifndef FILTERS_GP_FILTERS_H -#define FILTERS_GP_FILTERS_H - -/* Filter per channel parameter passing interface */ -#include "filters/GP_FilterParam.h" - -/* Point filters, brightness, contrast ... */ -#include "filters/GP_Point.h" - -/* Addition, difference, min, max ... */ -#include "filters/GP_Arithmetic.h" - -/* Histograms, ... */ -#include "filters/GP_Stats.h" - -/* Image rotations (90 180 270 grads) and mirroring */ -#include "filters/GP_Rotate.h" - -/* Linear convolution Raw API */ -#include "filters/GP_Linear.h" - -/* Convolution filters */ -#include "filters/GP_Convolution.h" - -/* Blur filters */ -#include "filters/GP_Blur.h" - -/* Image scaling (resampling) */ -#include "filters/GP_Resize.h" - -/* Bitmap dithering */ -#include "filters/GP_Dither.h" - -/* Laplace based filters */ -#include "filters/GP_Laplace.h" - -/* Median filter */ -#include "filters/GP_Median.h" +#ifndef FILTERS_GP_RESIZE_NN_H +#define FILTERS_GP_RESIZE_NN_H
-/* Weighted Median filter */ -#include "filters/GP_WeightedMedian.h" +#include "GP_Filter.h" +#include "GP_Resize.h"
-/* Sigma Mean filter */ -#include "filters/GP_Sigma.h" +int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-/* Gaussian noise filter */ -#include "filters/GP_GaussianNoise.h" +static inline GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_ProgressCallback *callback) +{ + return GP_FilterResizeAlloc(src, w, h, GP_INTERP_NN, callback); +}
-#endif /* FILTERS_GP_FILTERS_H */ +#endif /* FILTERS_GP_RESIZE_NN_H */ diff --git a/libs/filters/GP_Resize.c b/libs/filters/GP_Resize.c index 24d58a2..fa0da01 100644 --- a/libs/filters/GP_Resize.c +++ b/libs/filters/GP_Resize.c @@ -20,131 +20,16 @@ * * *****************************************************************************/
-#include <math.h> +#include <errno.h>
#include "core/GP_Context.h" -#include "core/GP_GetPutPixel.h" -#include "core/GP_Gamma.h" - #include "core/GP_Debug.h"
+#include "GP_ResizeNN.h" +#include "GP_ResizeLinear.h" +#include "GP_ResizeCubic.h" #include "GP_Resize.h"
-/* See GP_ResizeNN.gen.c */ -int GP_FilterResizeNN_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); - -int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - GP_ASSERT(src->pixel_type == dst->pixel_type); - - return GP_FilterResizeNN_Raw(src, dst, callback); -} - -GP_Context *GP_FilterResizeNNAlloc(const GP_Context *src, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback) -{ - GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type); - - if (res == NULL) - return NULL; - - if (GP_FilterResizeNN_Raw(src, res, callback)) { - GP_ContextFree(res); - return NULL; - } - - return res; -} - -/* See GP_ResizeCubic.gen.c */ -int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); - -int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - GP_ASSERT(src->pixel_type == dst->pixel_type); - - return GP_FilterResizeCubicInt_Raw(src, dst, callback); -} - -GP_Context *GP_FilterResizeCubicIntAlloc(const GP_Context *src, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback) -{ - GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type); - - if (res == NULL) - return NULL; - - if (GP_FilterResizeCubicInt_Raw(src, res, callback)) { - GP_ContextFree(res); - return NULL; - } - - return res; -} - -/* See GP_ResizeLinear.gen.c */ -int GP_FilterResizeLinearInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); - -int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); - -int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - GP_ASSERT(src->pixel_type == dst->pixel_type); - - return GP_FilterResizeLinearInt_Raw(src, dst, callback); -} - -int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - GP_ASSERT(src->pixel_type == dst->pixel_type); - - return GP_FilterResizeLinearInt_Raw(src, dst, callback); -} - -GP_Context *GP_FilterResizeLinearIntAlloc(const GP_Context *src, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback) -{ - GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type); - - if (res == NULL) - return NULL; - - if (GP_FilterResizeCubicInt_Raw(src, res, callback)) { - GP_ContextFree(res); - return NULL; - } - - return res; -} - -GP_Context *GP_FilterResizeLinearLFIntAlloc(const GP_Context *src, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback) -{ - GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type); - - if (res == NULL) - return NULL; - - if (GP_FilterResizeLinearLFInt_Raw(src, res, callback)) { - GP_ContextFree(res); - return NULL; - } - - return res; -} - static const char *interp_types[] = { "Nearest Neighbour", "Linear (Int)", @@ -161,241 +46,56 @@ const char *GP_InterpolationTypeName(enum GP_InterpolationType interp_type) return interp_types[interp_type]; }
-#define A 0.5 - -static float cubic(float x) -{ - if (x < 0) - x = -x; - - if (x < 1) - return (2 - A)*x*x*x + (A - 3)*x*x + 1; - - if (x < 2) - return -A*x*x*x + 5*A*x*x - 8*A*x + 4*A; - - return 0; -} - -typedef float v4sf __attribute__ ((vector_size (sizeof(float) * 4))); - -typedef union v4f { - v4sf v; - float f[4]; -} v4f; - -#define GP_USE_GCC_VECTOR - -#ifdef GP_USE_GCC_VECTOR -#define MUL_V4SF(a, b) ({v4f ret; ret.v = (a).v * (b).v; ret;}) -#else -#define MUL_V4SF(a, b) ({v4f ret; - ret.f[0] = (a).f[0] * (b).f[0]; - ret.f[1] = (a).f[1] * (b).f[1]; - ret.f[2] = (a).f[2] * (b).f[2]; - ret.f[3] = (a).f[3] * (b).f[3]; - ret;}) -#endif /* GP_USE_GCC_VECTOR */ - -#define SUM_V4SF(a) ((a).f[0] + (a).f[1] + (a).f[2] + (a).f[3]) - -#define CLAMP(val) do { - if (val < 0) - val = 0; - if (val > 255) - val = 255; -} while (0) - -int GP_FilterInterpolate_Cubic(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) -{ - float col_r[src->h], col_g[src->h], col_b[src->h]; - uint32_t i, j; - - if (src->pixel_type != GP_PIXEL_RGB888) - return 1; - - GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f", - src->w, src->h, dst->w, dst->h, - 1.00 * dst->w / src->w, 1.00 * dst->h / src->h); - - for (i = 0; i < dst->w; i++) { - float x = (1.00 * i / (dst->w - 1)) * (src->w - 1); - v4f cvx; - int xi[4]; - - xi[0] = floor(x - 1); - xi[1] = x; - xi[2] = x + 1; - xi[3] = x + 2; - - cvx.f[0] = cubic(xi[0] - x); - cvx.f[1] = cubic(xi[1] - x); - cvx.f[2] = cubic(xi[2] - x); - cvx.f[3] = cubic(xi[3] - x); - - if (xi[0] < 0) - xi[0] = 0; - - if (xi[2] >= (int)src->w) - xi[2] = src->w - 1; - - if (xi[3] >= (int)src->w) - xi[3] = src->w - 1; - - /* Generate interpolated column */ - for (j = 0; j < src->h; j++) { - v4f rv, gv, bv; - GP_Pixel pix[4]; - - pix[0] = GP_GetPixel_Raw_24BPP(src, xi[0], j); - pix[1] = GP_GetPixel_Raw_24BPP(src, xi[1], j); - pix[2] = GP_GetPixel_Raw_24BPP(src, xi[2], j); - pix[3] = GP_GetPixel_Raw_24BPP(src, xi[3], j); - - rv.f[0] = GP_Pixel_GET_R_RGB888(pix[0]); - rv.f[1] = GP_Pixel_GET_R_RGB888(pix[1]); - rv.f[2] = GP_Pixel_GET_R_RGB888(pix[2]); - rv.f[3] = GP_Pixel_GET_R_RGB888(pix[3]); - - gv.f[0] = GP_Pixel_GET_G_RGB888(pix[0]); - gv.f[1] = GP_Pixel_GET_G_RGB888(pix[1]); - gv.f[2] = GP_Pixel_GET_G_RGB888(pix[2]); - gv.f[3] = GP_Pixel_GET_G_RGB888(pix[3]); - - bv.f[0] = GP_Pixel_GET_B_RGB888(pix[0]); - bv.f[1] = GP_Pixel_GET_B_RGB888(pix[1]); - bv.f[2] = GP_Pixel_GET_B_RGB888(pix[2]); - bv.f[3] = GP_Pixel_GET_B_RGB888(pix[3]); - - rv = MUL_V4SF(rv, cvx); - gv = MUL_V4SF(gv, cvx); - bv = MUL_V4SF(bv, cvx); - - col_r[j] = SUM_V4SF(rv); - col_g[j] = SUM_V4SF(gv); - col_b[j] = SUM_V4SF(bv); - } - - /* now interpolate column for new image */ - for (j = 0; j < dst->h; j++) { - float y = (1.00 * j / (dst->h - 1)) * (src->h - 1); - v4f cvy, rv, gv, bv; - float r, g, b; - int yi[4]; - - yi[0] = floor(y - 1); - yi[1] = y; - yi[2] = y + 1; - yi[3] = y + 2; - - cvy.f[0] = cubic(yi[0] - y); - cvy.f[1] = cubic(yi[1] - y); - cvy.f[2] = cubic(yi[2] - y); - cvy.f[3] = cubic(yi[3] - y); - - if (yi[0] < 0) - yi[0] = 0; - - if (yi[2] >= (int)src->h) - yi[2] = src->h - 1; - - if (yi[3] >= (int)src->h) - yi[3] = src->h - 1; - - rv.f[0] = col_r[yi[0]]; - rv.f[1] = col_r[yi[1]]; - rv.f[2] = col_r[yi[2]]; - rv.f[3] = col_r[yi[3]]; - - gv.f[0] = col_g[yi[0]]; - gv.f[1] = col_g[yi[1]]; - gv.f[2] = col_g[yi[2]]; - gv.f[3] = col_g[yi[3]]; - - bv.f[0] = col_b[yi[0]]; - bv.f[1] = col_b[yi[1]]; - bv.f[2] = col_b[yi[2]]; - bv.f[3] = col_b[yi[3]]; - - rv = MUL_V4SF(rv, cvy); - gv = MUL_V4SF(gv, cvy); - bv = MUL_V4SF(bv, cvy); - - r = SUM_V4SF(rv); - g = SUM_V4SF(gv); - b = SUM_V4SF(bv); - - CLAMP(r); - CLAMP(g); - CLAMP(b); - - GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b); - GP_PutPixel_Raw_24BPP(dst, i, j, pix); - } - - if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h)) - return 1; - } - - GP_ProgressCallbackDone(callback); - return 0; -} - -int GP_FilterResize_Raw(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_ProgressCallback *callback) +static int resize(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback) { switch (type) { case GP_INTERP_NN: - return GP_FilterResizeNN_Raw(src, dst, callback); + return GP_FilterResizeNN(src, dst, callback); case GP_INTERP_LINEAR_INT: - return GP_FilterResizeLinearInt_Raw(src, dst, callback); + return GP_FilterResizeLinearInt(src, dst, callback); case GP_INTERP_LINEAR_LF_INT: - return GP_FilterResizeLinearLFInt_Raw(src, dst, callback); + return GP_FilterResizeLinearLFInt(src, dst, callback); case GP_INTERP_CUBIC: - return GP_FilterInterpolate_Cubic(src, dst, callback); + return GP_FilterResizeCubic(src, dst, callback); case GP_INTERP_CUBIC_INT: - return GP_FilterResizeCubicInt_Raw(src, dst, callback); + return GP_FilterResizeCubicInt(src, dst, callback); }
+ GP_WARN("Invalid interpolation type %u", (unsigned int)type); + + errno = EINVAL; return 1; }
-GP_Context *GP_FilterResize(const GP_Context *src, GP_Context *dst, - GP_InterpolationType type, - GP_Size w, GP_Size h, - GP_ProgressCallback *callback) +int GP_FilterResize(const GP_Context *src, GP_Context *dst, + GP_InterpolationType type, + GP_ProgressCallback *callback) { - GP_Context sub, *res; - - if (dst == NULL) { - res = GP_ContextAlloc(w, h, src->pixel_type); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - /* - * The size of w and h is asserted in subcontext initalization - */ - res = GP_SubContext(dst, &sub, 0, 0, w, h); + if (src->pixel_type != dst->pixel_type) { + GP_WARN("The src and dst pixel types must match"); + errno = EINVAL; + return 1; }
- /* - * Operation was aborted by progress callback. - * - * Free any alloacted data and exit. - */ - if (GP_FilterResize_Raw(src, res, type, callback)) { - GP_DEBUG(1, "Operation aborted"); + return resize(src, dst, type, callback); +} + +GP_Context *GP_FilterResizeAlloc(const GP_Context *src, + GP_Size w, GP_Size h, + GP_InterpolationType type, + GP_ProgressCallback *callback) +{ + GP_Context *res = GP_ContextAlloc(w, h, src->pixel_type);
- if (dst == NULL) - GP_ContextFree(dst); + if (!res) + return NULL;
+ if (resize(src, res, type, callback)) { + GP_ContextFree(res); return NULL; }
- return dst == NULL ? res : dst; + return res; } diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t index a273d14..9120fa7 100644 --- a/libs/filters/GP_ResizeCubic.gen.c.t +++ b/libs/filters/GP_ResizeCubic.gen.c.t @@ -26,6 +26,7 @@
%% block body
+#include <errno.h> #include <math.h>
#include "core/GP_Context.h" @@ -51,9 +52,9 @@ ((a)[0] + (a)[1] + (a)[2] + (a)[3])
%% for pt in pixeltypes -%% if not pt.is_unknown() and not pt.is_palette() +%% if not pt.is_unknown() and not pt.is_palette()
-static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src, +static int resize_cubic_{{ pt.name }}(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { %% for c in pt.chanslist @@ -194,23 +195,35 @@ static int GP_FilterResizeCubicInt_{{ pt.name }}_Raw(const GP_Context *src, return 0; }
-%% endif +%% endif %% endfor
-int GP_FilterResizeCubicInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +static int resize_cubic(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { switch (src->pixel_type) { %% for pt in pixeltypes - %% if not pt.is_unknown() and not pt.is_palette() + %% if not pt.is_unknown() and not pt.is_palette() case GP_PIXEL_{{ pt.name }}: - return GP_FilterResizeCubicInt_{{ pt.name }}_Raw(src, dst, callback); + return resize_cubic_{{ pt.name }}(src, dst, callback); break; - %% endif + %% endif %% endfor default: return -1; } }
+int GP_FilterResizeCubicInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + if (src->pixel_type != dst->pixel_type) { + GP_WARN("The src and dst pixel types must match"); + errno = EINVAL; + return 1; + } + + return resize_cubic(src, dst, callback); +} + %% endblock body diff --git a/libs/filters/GP_ResizeCubicFloat.c b/libs/filters/GP_ResizeCubicFloat.c new file mode 100644 index 0000000..f16ab7a --- /dev/null +++ b/libs/filters/GP_ResizeCubicFloat.c @@ -0,0 +1,212 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <math.h> + +#include "core/GP_Context.h" +#include "core/GP_GetPutPixel.h" +#include "core/GP_Gamma.h" + +#include "core/GP_Debug.h" + +#include "GP_ResizeCubic.h" + +#define A 0.5 + +static float cubic(float x) +{ + if (x < 0) + x = -x; + + if (x < 1) + return (2 - A)*x*x*x + (A - 3)*x*x + 1; + + if (x < 2) + return -A*x*x*x + 5*A*x*x - 8*A*x + 4*A; + + return 0; +} + +typedef float v4sf __attribute__ ((vector_size (sizeof(float) * 4))); + +typedef union v4f { + v4sf v; + float f[4]; +} v4f; + +#define GP_USE_GCC_VECTOR + +#ifdef GP_USE_GCC_VECTOR +#define MUL_V4SF(a, b) ({v4f ret; ret.v = (a).v * (b).v; ret;}) +#else +#define MUL_V4SF(a, b) ({v4f ret; + ret.f[0] = (a).f[0] * (b).f[0]; + ret.f[1] = (a).f[1] * (b).f[1]; + ret.f[2] = (a).f[2] * (b).f[2]; + ret.f[3] = (a).f[3] * (b).f[3]; + ret;}) +#endif /* GP_USE_GCC_VECTOR */ + +#define SUM_V4SF(a) ((a).f[0] + (a).f[1] + (a).f[2] + (a).f[3]) + +#define CLAMP(val) do { + if (val < 0) + val = 0; + if (val > 255) + val = 255; +} while (0) + +int GP_FilterResizeCubic(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + float col_r[src->h], col_g[src->h], col_b[src->h]; + uint32_t i, j; + + if (src->pixel_type != GP_PIXEL_RGB888 || dst->pixel_type != GP_PIXEL_RGB888) + return 1; + + GP_DEBUG(1, "Scaling image %ux%u -> %ux%u %2.2f %2.2f", + src->w, src->h, dst->w, dst->h, + 1.00 * dst->w / src->w, 1.00 * dst->h / src->h); + + for (i = 0; i < dst->w; i++) { + float x = (1.00 * i / (dst->w - 1)) * (src->w - 1); + v4f cvx; + int xi[4]; + + xi[0] = floor(x - 1); + xi[1] = x; + xi[2] = x + 1; + xi[3] = x + 2; + + cvx.f[0] = cubic(xi[0] - x); + cvx.f[1] = cubic(xi[1] - x); + cvx.f[2] = cubic(xi[2] - x); + cvx.f[3] = cubic(xi[3] - x); + + if (xi[0] < 0) + xi[0] = 0; + + if (xi[2] >= (int)src->w) + xi[2] = src->w - 1; + + if (xi[3] >= (int)src->w) + xi[3] = src->w - 1; + + /* Generate interpolated column */ + for (j = 0; j < src->h; j++) { + v4f rv, gv, bv; + GP_Pixel pix[4]; + + pix[0] = GP_GetPixel_Raw_24BPP(src, xi[0], j); + pix[1] = GP_GetPixel_Raw_24BPP(src, xi[1], j); + pix[2] = GP_GetPixel_Raw_24BPP(src, xi[2], j); + pix[3] = GP_GetPixel_Raw_24BPP(src, xi[3], j); + + rv.f[0] = GP_Pixel_GET_R_RGB888(pix[0]); + rv.f[1] = GP_Pixel_GET_R_RGB888(pix[1]); + rv.f[2] = GP_Pixel_GET_R_RGB888(pix[2]); + rv.f[3] = GP_Pixel_GET_R_RGB888(pix[3]); + + gv.f[0] = GP_Pixel_GET_G_RGB888(pix[0]); + gv.f[1] = GP_Pixel_GET_G_RGB888(pix[1]); + gv.f[2] = GP_Pixel_GET_G_RGB888(pix[2]); + gv.f[3] = GP_Pixel_GET_G_RGB888(pix[3]); + + bv.f[0] = GP_Pixel_GET_B_RGB888(pix[0]); + bv.f[1] = GP_Pixel_GET_B_RGB888(pix[1]); + bv.f[2] = GP_Pixel_GET_B_RGB888(pix[2]); + bv.f[3] = GP_Pixel_GET_B_RGB888(pix[3]); + + rv = MUL_V4SF(rv, cvx); + gv = MUL_V4SF(gv, cvx); + bv = MUL_V4SF(bv, cvx); + + col_r[j] = SUM_V4SF(rv); + col_g[j] = SUM_V4SF(gv); + col_b[j] = SUM_V4SF(bv); + } + + /* now interpolate column for new image */ + for (j = 0; j < dst->h; j++) { + float y = (1.00 * j / (dst->h - 1)) * (src->h - 1); + v4f cvy, rv, gv, bv; + float r, g, b; + int yi[4]; + + yi[0] = floor(y - 1); + yi[1] = y; + yi[2] = y + 1; + yi[3] = y + 2; + + cvy.f[0] = cubic(yi[0] - y); + cvy.f[1] = cubic(yi[1] - y); + cvy.f[2] = cubic(yi[2] - y); + cvy.f[3] = cubic(yi[3] - y); + + if (yi[0] < 0) + yi[0] = 0; + + if (yi[2] >= (int)src->h) + yi[2] = src->h - 1; + + if (yi[3] >= (int)src->h) + yi[3] = src->h - 1; + + rv.f[0] = col_r[yi[0]]; + rv.f[1] = col_r[yi[1]]; + rv.f[2] = col_r[yi[2]]; + rv.f[3] = col_r[yi[3]]; + + gv.f[0] = col_g[yi[0]]; + gv.f[1] = col_g[yi[1]]; + gv.f[2] = col_g[yi[2]]; + gv.f[3] = col_g[yi[3]]; + + bv.f[0] = col_b[yi[0]]; + bv.f[1] = col_b[yi[1]]; + bv.f[2] = col_b[yi[2]]; + bv.f[3] = col_b[yi[3]]; + + rv = MUL_V4SF(rv, cvy); + gv = MUL_V4SF(gv, cvy); + bv = MUL_V4SF(bv, cvy); + + r = SUM_V4SF(rv); + g = SUM_V4SF(gv); + b = SUM_V4SF(bv); + + CLAMP(r); + CLAMP(g); + CLAMP(b); + + GP_Pixel pix = GP_Pixel_CREATE_RGB888((uint8_t)r, (uint8_t)g, (uint8_t)b); + GP_PutPixel_Raw_24BPP(dst, i, j, pix); + } + + if (GP_ProgressCallbackReport(callback, i, dst->w, dst->h)) + return 1; + } + + GP_ProgressCallbackDone(callback); + return 0; +} diff --git a/libs/filters/GP_ResizeLinear.gen.c.t b/libs/filters/GP_ResizeLinear.gen.c.t index b2bfc68..958c01c 100644 --- a/libs/filters/GP_ResizeLinear.gen.c.t +++ b/libs/filters/GP_ResizeLinear.gen.c.t @@ -26,6 +26,8 @@
%% block body
+#include <errno.h> + #include "core/GP_Context.h" #include "core/GP_GetPutPixel.h" #include "core/GP_Gamma.h" @@ -103,8 +105,8 @@ * * The implementation is inspired by imlib2 downscaling algorithm. */ -static int GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +static int resize_lin_lf_{{ pt.name }}(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { uint32_t xmap[dst->w + 1]; uint32_t ymap[dst->h + 1]; @@ -199,7 +201,7 @@ static int GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(const GP_Context *src, G %% for pt in pixeltypes %% if not pt.is_unknown() and not pt.is_palette()
-static int GP_FilterResizeLinearInt_{{ pt.name }}_Raw(const GP_Context *src, GP_Context *dst, +static int resize_lin{{ pt.name }}(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback) { uint32_t xmap[dst->w + 1]; @@ -290,24 +292,39 @@ static int GP_FilterResizeLinearInt_{{ pt.name }}_Raw(const GP_Context *src, GP_ %% endif %% endfor
-int GP_FilterResizeLinearInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +static int resize_lin(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { switch (src->pixel_type) { %% for pt in pixeltypes - %% if not pt.is_unknown() and not pt.is_palette() + %% if not pt.is_unknown() and not pt.is_palette() case GP_PIXEL_{{ pt.name }}: - return GP_FilterResizeLinearInt_{{ pt.name }}_Raw(src, dst, callback); + return resize_lin{{ pt.name }}(src, dst, callback); break; - %% endif + %% endif %% endfor default: + GP_WARN("Invalid pixel type %s", + GP_PixelTypeName(src->pixel_type)); + errno = EINVAL; return -1; } }
-int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterResizeLinearInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + if (src->pixel_type != dst->pixel_type) { + GP_WARN("The src and dst pixel types must match"); + errno = EINVAL; + return 1; + } + + return resize_lin(src, dst, callback); +} + +static int resize_lin_lf2(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { float x_rat = 1.00 * dst->w / src->w; float y_rat = 1.00 * dst->h / src->h; @@ -321,7 +338,7 @@ int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst, %% for pt in pixeltypes %% if not pt.is_unknown() and not pt.is_palette() case GP_PIXEL_{{ pt.name }}: - return GP_FilterResizeLinearLFInt_{{ pt.name }}_Raw(src, dst, callback); + return resize_lin_lf_{{ pt.name }}(src, dst, callback); break; %% endif %% endfor @@ -333,7 +350,19 @@ int GP_FilterResizeLinearLFInt_Raw(const GP_Context *src, GP_Context *dst, //TODO: x_rat > 1.00 && y_rat < 1.00 //TODO: x_rat < 1.00 && y_rat > 1.00
- return GP_FilterResizeLinearInt_Raw(src, dst, callback); + return resize_lin(src, dst, callback); +} + +int GP_FilterResizeLinearLFInt(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + if (src->pixel_type != dst->pixel_type) { + GP_WARN("The src and dst pixel types must match"); + errno = EINVAL; + return 1; + } + + return resize_lin_lf2(src, dst, callback); }
%% endblock body diff --git a/libs/filters/GP_ResizeNN.gen.c.t b/libs/filters/GP_ResizeNN.gen.c.t index 55eb34d..4874288 100644 --- a/libs/filters/GP_ResizeNN.gen.c.t +++ b/libs/filters/GP_ResizeNN.gen.c.t @@ -26,18 +26,20 @@
%% block body
+#include <errno.h> + #include "core/GP_Context.h" #include "core/GP_GetPutPixel.h"
#include "core/GP_Debug.h"
-#include "GP_Resize.h" +#include "GP_ResizeNN.h"
%% for pt in pixeltypes -%% if not pt.is_unknown() +%% if not pt.is_unknown()
-static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src, - GP_Context *dst, GP_ProgressCallback *callback) +static int resize_nn{{ pt.name }}(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { uint32_t xmap[dst->w]; uint32_t ymap[dst->h]; @@ -50,7 +52,7 @@ static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src,
/* Pre-compute mapping for interpolation */ for (i = 0; i < dst->w; i++) - xmap[i] = ((((i * (src->w - 1))<<8) + (dst->w - 1)/2) / (dst->w - 1) + (1<<7))>>8; + xmap[i] = ((((i * (src->w - 1))<<8)) / (dst->w - 1) + (1<<7))>>8;
for (i = 0; i < dst->h; i++) ymap[i] = ((((i * (src->h - 1))<<8) + (dst->h - 1)/2) / (dst->h - 1) + (1<<7))>>8; @@ -63,31 +65,45 @@ static int GP_FilterResizeNN_{{ pt.name }}_Raw(const GP_Context *src, GP_PutPixel_Raw_{{ pt.pixelsize.suffix }}(dst, x, y, pix); }
- if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) + if (GP_ProgressCallbackReport(callback, y, dst->h, dst->w)) { + errno = ECANCELED; return 1; + } }
GP_ProgressCallbackDone(callback); return 0; }
-%% endif +%% endif %% endfor
-int GP_FilterResizeNN_Raw(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +static int resize_nn(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { switch (src->pixel_type) { %% for pt in pixeltypes - %% if not pt.is_unknown() + %% if not pt.is_unknown() case GP_PIXEL_{{ pt.name }}: - return GP_FilterResizeNN_{{ pt.name }}_Raw(src, dst, callback); + return resize_nn{{ pt.name }}(src, dst, callback); break; - %% endif + %% endif %% endfor default: return -1; } }
+int GP_FilterResizeNN(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) +{ + if (src->pixel_type != dst->pixel_type) { + GP_WARN("The src and dst pixel types must match"); + errno = EINVAL; + return 1; + } + + return resize_nn(src, dst, callback); +} + %% endblock body diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i index 6adf8a7..d803993 100644 --- a/pylib/gfxprim/filters/filters.i +++ b/pylib/gfxprim/filters/filters.i @@ -6,17 +6,31 @@ #include "core/GP_Debug.h" %}
-%import ../core/core.i - -%include "GP_Filters.h" - /* Listed in GP_Filters.h: */ %include "GP_Point.h" %ignore GP_Histogram::hist; %include "GP_Stats.h" %include "GP_Linear.h" + +/* Resize filters */ +ERROR_ON_NONZERO(GP_FilterResize); +%newobject GP_FilterResizeAlloc; +ERROR_ON_NULL(GP_FilterResizeAlloc); %include "GP_Resize.h"
+ERROR_ON_NONZERO(GP_FilterResizeNN); +%newobject GP_FilterResizeNNAlloc; +ERROR_ON_NULL(GP_FilterResizeNNAlloc); +%include "GP_ResizeNN.h" + +ERROR_ON_NONZERO(GP_FilterResizeLinearInt); +%newobject GP_FilterResizeLinearIntAlloc; +ERROR_ON_NULL(GP_FilterResizeLinearIntAlloc); +ERROR_ON_NONZERO(GP_FilterResizeLinearLFInt); +%newobject GP_FilterResizeLinearLFIntAlloc; +ERROR_ON_NULL(GP_FilterResizeLinearLFIntAlloc); +%include "GP_ResizeLinear.h" + %extend GP_FilterParam { ~GP_FilterParam() { GP_DEBUG(2, "[wrapper] GP_FilterParamFree");
http://repo.or.cz/w/gfxprim.git/commit/c99c44f51072de292b49f4d0ba38d0e9caa82...
commit c99c44f51072de292b49f4d0ba38d0e9caa82def Author: Cyril Hrubis metan@ucw.cz Date: Mon Aug 19 20:25:23 2013 +0200
build: Update Loaders symbols (Add JP2 funcs)
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt index 1814807..9a933e7 100644 --- a/build/syms/Loaders_symbols.txt +++ b/build/syms/Loaders_symbols.txt @@ -55,6 +55,11 @@ GP_LoadPNM GP_SavePNM GP_MatchPNM
+GP_ReadJP2 +GP_OpenJP2 +GP_LoadJP2 +GP_MatchJP2 + GP_SaveTmpFile GP_LoadTmpFile
-----------------------------------------------------------------------
Summary of changes: build/syms/Filters_symbols.txt | 18 +- build/syms/Loaders_symbols.txt | 5 + demos/grinder/grinder.c | 8 +- demos/spiv/spiv.c | 14 +- doc/Makefile | 2 +- doc/filters.txt | 30 +-- doc/filters_resize.txt | 139 ++++++++ include/filters/GP_Filters.h | 3 + include/filters/GP_Resize.h | 37 +- .../filters/GP_ResizeCubic.h | 61 ++-- .../filters/GP_ResizeLinear.h | 61 ++-- .../filters/GP_ResizeNN.h | 26 +- libs/filters/GP_Resize.c | 372 ++------------------ libs/filters/GP_ResizeCubic.gen.c.t | 29 ++- libs/filters/GP_ResizeCubicFloat.c | 212 +++++++++++ libs/filters/GP_ResizeLinear.gen.c.t | 53 +++- libs/filters/GP_ResizeNN.gen.c.t | 40 ++- pylib/gfxprim/filters/filters.i | 22 +- 18 files changed, 595 insertions(+), 537 deletions(-) create mode 100644 doc/filters_resize.txt copy demos/c_simple/debug_handler.c => include/filters/GP_ResizeCubic.h (61%) copy demos/c_simple/debug_handler.c => include/filters/GP_ResizeLinear.h (60%) copy demos/c_simple/pretty_print.c => include/filters/GP_ResizeNN.h (75%) create mode 100644 libs/filters/GP_ResizeCubicFloat.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.