【VC开源代码栏目提醒】:网学会员,鉴于大家对VC开源代码十分关注,论文会员在此为大家搜集整理了“video_util_resize.cpp”一文,供大家参考学习!
/*
* Filtered Image Rescaling
*
Additional changes by Ray Gardener, Daylon Graphics Ltd.
December 4, 1999
Summary:
- Horizontal filter contributions are calculated on the fly,
as each column is mapped from src to dst image. This lets
us omit having to allocate a temporary full horizontal stretch
of the src image.
- If none of the src pixels within a sampling region differ,
then the output pixel is forced to equal (any of) the source pixel.
This ensures that filters do not corrupt areas of constant color.
- Filter weight contribution results, after summing, are
rounded to the nearest pixel color value instead of
being casted to Pixel (usually an int or char). Otherwise,
artifacting occurs.
- All memory allocations checked for failure; scale() returns
error code. new_image() returns NULL if unable to allocate
pixel storage, even if Image struct can be allocated.
Some assertions added.
- load_image(), save_image() take filenames, not file handles.
- TGA bitmap format available. If you want to add a filetype,
extend the gImageHandlers array, and factor in your load_image_xxx()
and save_image_xxx() functions. Search for string 'add your'
to find appropriate code locations.
- The 'input' and 'output' command-line arguments do not have
to specify .bm files; any supported filetype is okay.
- Added implementation of getopt() if compiling under Windows.
*/
#include "mp4live.h"
#include "video_util_resize.h"
#ifndef M_PI
#define M_PI 3.14323846
#endif
#define WHITE_PIXEL (255)
#define BLACK_PIXEL (0)
#define CLAMP(v) (((v) < (BLACK_PIXEL)) ? \
(BLACK_PIXEL) : \
(((v) > (WHITE_PIXEL)) ? (WHITE_PIXEL) : (v)))
#define get_pixel(image, y, x) ((image)->data[(x) + (y) * image->span])
#define put_pixel(image, y, x, p) ((image)->data[(x) + (y) * image->span] = (p))
/* Helper data structures: */
typedef struct {
int pixel;
fixdouble weight;
} CONTRIB;
typedef struct {
int n; /* number of contributors */
CONTRIB *p; /* pointer to list of contributions */
} CLIST;
void scale_setup_image(image_t *img, int w, int h, int depth, pixel_t *data)
{
img->xsize = h;
img->ysize = w;
img->pixspan = depth;
img->span = w * depth;
img->data = data;
}
image_t *scale_new_image(int w, int h, int depth) /* create a blank image */
{
image_t *image;
if((image = (image_t *)malloc(sizeof(image_t))))
{
image->xsize = h;
image->ysize = w;
image->span = w * depth;
image->pixspan = depth;
image->data = NULL;
}
return image;
}
void scale_free_image(image_t *image)
{
free(image);
}
/*
* filter function definitions
*/
double Hermite_filter(double t)
{
// f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1
if(t < 0.0) t = -t;
if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
return(0.0);
}
double Box_filter(double t)
{
if((t > -0.5) && (t <= 0.5)) return(1.0);
return(0.0);
}
double Triangle_filter(double t)
{
if(t < 0.0) t = -t;
if(t < 1.0) return(1.0 - t);
return(0.0);
}
double Bell_filter(double t) /* box (*) box (*) box */
{
if(t < 0) t = -t;
if(t < .5) return(.75 - (t * t));
if(t < 1.5) {
t = (t - 1.5);
return(.5 * (t * t));
}
return(0.0);
}
double B_spline_filter(double t) /* box (*) box (*) box (*) box */
{
double tt;
if(t < 0) t = -t;
if(t < 1) {
tt = t * t;
return((.5 * tt * t) - tt + (2.0 / 3.0));
} else if(t < 2) {
t = 2 - t;
return((1.0 / 6.0) * (t * t * t));
}
return(0.0);
}
static double sinc(double x)
{
x *= M_PI;
if(x != 0) return(sin(x) / x);
return(1.0);
}
double Lanczos3_filter(double t)
{
if(t < 0) t = -t;
if(t < 3.0) return(sinc(t) * sinc(t/3.0));
return(0.0);
}
#define B (1.0 / 3.0)
#define C (1.0 / 3.0)
double Mitchell_filter(double t)
{
double tt;
tt = t * t;
if(t < 0) t = -t;
if(t < 1.0) {
t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
+ ((-18.0 + 12.0 * B + 6.0 * C) * tt)
+ (6.0 - 2 * B));
return(t / 6.0);
} else if(t < 2.0) {
t = (((-1.0 * B - 6.0 * C) * (t * tt))
+ ((6.0 * B + 30.0 * C) * tt)
+ ((-12.0 * B - 48.0 * C) * t)
+ (8.0 * B + 24 * C));
return(t / 6.0);
}
return(0.0);
}
/*
* image rescaling routine
*/
/*
calc_x_contrib(
CLIST* contribX; * Receiver of contrib info
double xscale; * Horizontal scaling
double fwidth; * Filter sampling width
int dstwidth; * Target bitmap width
int srcwidth; * Source bitmap width
double (*filterf)(double); * Filter proc
int i; * pixel_t column in source bitmap being processed
)
Calculates the filter weights for a single target column.
contribX->p must be freed afterwards.
Returns -1 if error, 0 otherwise.
*/
static int calc_x_contrib(CLIST* contribX, double xscale, double fwidth, int dstwidth, int srcwidth,
double (*filterf)(double), int i)
{
double width;
double fscale;
doubl