Resize filters
--------------

Common API
~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <filters/gp_resize.h>

typedef enum gp_interpolation_type {
        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_interpolation_type;

const char *gp_interpolation_type_name(enum gp_interpolation_type interp_type);

int gp_filter_resize(const gp_pixmap *src, gp_pixmap *dst,
                    gp_interpolation_type type,
                    gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_alloc(const gp_pixmap *src,
                                  gp_size w, gp_size h,
                                  gp_interpolation_type type,
                                  gp_progress_cb *callback);
-------------------------------------------------------------------------------

Interpolate (resize) the pixmap.

Resize image given size and interpolation type.

gp_filter_resize
^^^^^^^^^^^^^^^^

The +gp_filter_reize()+ 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_filter_resize_alloc
^^^^^^^^^^^^^^^^^^^^^^

The +gp_filter_resize_alloc()+ allocates the destination give it's size.

Returns pointer to newly allocated pixmap or NULL in case of failure and
errno is set.

Nearest Neighbour Interpolation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[source,c]
-------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <filters/gp_resize_nn.h>

int gp_filter_resize_nn(const gp_pixmap *src, gp_pixmap *dst,
                        gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_nn_alloc(const gp_pixmap *src,
                                     gp_size w, gp_size h,
                                     gp_progress_cb *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 <gfxprim.h>
/* or */
#include <filters/gp_resize_linear.h>

int gp_filter_resize_linear_int(const gp_pixmap *src, gp_pixmap *dst,
                                gp_progress_cb *callback);

int gp_filter_resize_linear_lf_int(const gp_pixmap *src, gp_pixmap *dst,
                                   gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_linear_int_alloc(const gp_pixmap *src,
                                             gp_size w, gp_size h,
                                             gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_linear_lf_int_alloc(const gp_pixmap *src,
                                                gp_size w, gp_size h,
                                                gp_progress_cb *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 <gfxprim.h>
/* or */
#include <filters/gp_resize_cubic.h>

int gp_filter_resize_cubic_int(const gp_pixmap *src, gp_pixmap *dst,
                               gp_progress_cb *callback);

int gp_filter_resize_cubic(const gp_pixmap *src, gp_pixmap *dst,
                           gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_cubic_int_alloc(const gp_pixmap *src,
                                            gp_size w, gp_size h,
                                            gp_progress_cb *callback);

gp_pixmap *gp_filter_resize_cubic_alloc(const gp_pixmap *src,
                                        gp_size w, gp_size h,
                                        gp_progress_cb *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.
