Added point sampling interpolation.

Original commit message from CVS:
Added point sampling interpolation.
This commit is contained in:
Wim Taymans 2000-08-14 10:06:54 +00:00
parent 08b4e78a53
commit 82acefa7b0
2 changed files with 73 additions and 12 deletions

View file

@ -24,7 +24,6 @@
#include <gstvideoscale.h> #include <gstvideoscale.h>
#include <gst/meta/videoraw.h> #include <gst/meta/videoraw.h>
#include <libs/colorspace/gstcolorspace.h>
static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, unsigned char *dest); static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, unsigned char *dest);
static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, unsigned char *dest); static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, unsigned char *dest);
@ -33,15 +32,16 @@ static void gst_videoscale_scale_rgb(GstVideoScale *scale, unsigned char *src, u
static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int bpp); static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int bpp);
static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh); static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
static void gst_videoscale_scale_plane_slow(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh); static void gst_videoscale_scale_plane_slow(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
static void gst_videoscale_scale_point_sample(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh);
/* filters */ /* filters */
static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, double y, int sw, int sh); static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, double y, int sw, int sh);
static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double y, int sw, int sh); static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double y, int sw, int sh);
GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, GstVideoScaleMethod method) GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSpaceType format, GstVideoScaleMethod method)
{ {
GstVideoScale *new = g_malloc(sizeof(GstVideoScale)); GstVideoScale *new = g_malloc(sizeof(GstVideoScale));
int scale_bytes; gint scale_bytes;
new->source_width = sw; new->source_width = sw;
new->source_height = sh; new->source_height = sh;
@ -63,9 +63,17 @@ GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, Gs
new->scale = gst_videoscale_scale_rgb; new->scale = gst_videoscale_scale_rgb;
scale_bytes = 2; scale_bytes = 2;
break; break;
default:
g_print("videoscale: unsupported video format %d\n", format);
g_free(new);
return NULL;
} }
switch (method) { switch (method) {
case GST_VIDEOSCALE_POINT_SAMPLE:
new->scaler = gst_videoscale_scale_point_sample;
DEBUG("videoscale: scaling method POINT_SAMPLE\n");
break;
case GST_VIDEOSCALE_NEAREST: case GST_VIDEOSCALE_NEAREST:
generate_rowbytes(new->copy_row, sw, dw, scale_bytes); generate_rowbytes(new->copy_row, sw, dw, scale_bytes);
new->scaler = gst_videoscale_scale_nearest; new->scaler = gst_videoscale_scale_nearest;
@ -83,7 +91,8 @@ GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, Gs
break; break;
default: default:
g_print("videoscale: unsupported scaling method %d\n", method); g_print("videoscale: unsupported scaling method %d\n", method);
break; g_free(new);
return NULL;
} }
return new; return new;
@ -115,7 +124,7 @@ static void gst_videoscale_scale_yuv(GstVideoScale *scale, unsigned char *src, u
int dw = scale->dest_width; int dw = scale->dest_width;
int dh = scale->dest_height; int dh = scale->dest_height;
DEBUG("videoscale: scaling YUV420 %dx%d to %dx%d\n", sw, sh, dw, dh); DEBUG("videoscale: scaling YUV420P %dx%d to %dx%d\n", sw, sh, dw, dh);
scale->scaler(scale, src, dest, sw, sh, dw, dh); scale->scaler(scale, src, dest, sw, sh, dw, dh);
@ -145,7 +154,7 @@ static unsigned char gst_videoscale_bilinear(unsigned char *src, double x, doubl
double dest; double dest;
int color; int color;
DEBUG("videoscale: scaling bilinear %dx%d\n", sw, sh); printf("videoscale: scaling bilinear %f %f %dx%d\n", x, y, sw, sh);
dest=(1-a)*(1-b)*RC(j,k)+ dest=(1-a)*(1-b)*RC(j,k)+
a*(1-b)*RC(j+1,k); a*(1-b)*RC(j+1,k);
@ -172,6 +181,8 @@ static unsigned char gst_videoscale_bicubic(unsigned char *src, double x, double
double t1, t2, t3, t4; double t1, t2, t3, t4;
double a1, a2, a3, a4; double a1, a2, a3, a4;
DEBUG("videoscale: scaling bicubic %dx%d\n", sw, sh);
a1 = -a*(1-a)*(1-a); a1 = -a*(1-a)*(1-a);
a2 = (1-2*a*a+a*a*a); a2 = (1-2*a*a+a*a*a);
a3 = a*(1+a-a*a); a3 = a*(1+a-a*a);
@ -274,6 +285,53 @@ static void generate_rowbytes(unsigned char *copy_row, int src_w, int dst_w, int
} }
static void gst_videoscale_scale_point_sample(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh)
{
int ypos, yinc, y;
int xpos, xinc, x;
int sum, xcount, ycount, loop;
unsigned char *srcp, *srcp2;
DEBUG("videoscale: scaling nearest %p %p %d\n", src, dest, dw);
ypos = 0x10000;
yinc = (sh<<16)/dh;
xinc = (sw<<16)/dw;
for (y = dh; y; y--) {
ycount = 1;
srcp = src;
while (ypos >0x10000) {
ycount++;
ypos-=0x10000;
src += sw;
}
xpos = 0x10000;
for ( x=dw; x; x-- ) {
xcount = 0;
sum=0;
while ( xpos >= 0x10000L ) {
loop = ycount;
srcp2 = srcp;
while (loop--) {
sum += *srcp2;
srcp2 += sw;
}
srcp++;
xcount++;
xpos -= 0x10000L;
}
*dest++ = sum/(xcount*ycount);
xpos += xinc;
}
ypos += yinc;
}
}
static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh) static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh)
{ {
int pos, inc, y; int pos, inc, y;
@ -303,7 +361,6 @@ static void gst_videoscale_scale_nearest(GstVideoScale *scale, unsigned char *sr
: "memory" ); : "memory" );
//g_print("videoscale: scaling nearest %d\n", y);
dest+= dw; dest+= dw;
pos += inc; pos += inc;

View file

@ -22,31 +22,35 @@
#define __GST_VIDEOSCALE_H__ #define __GST_VIDEOSCALE_H__
#include <gst/gst.h> #include <gst/gst.h>
#include <libs/colorspace/gstcolorspace.h>
typedef enum { typedef enum {
GST_VIDEOSCALE_POINT_SAMPLE,
GST_VIDEOSCALE_NEAREST, GST_VIDEOSCALE_NEAREST,
GST_VIDEOSCALE_BILINEAR, GST_VIDEOSCALE_BILINEAR,
GST_VIDEOSCALE_BICUBIC GST_VIDEOSCALE_BICUBIC
} GstVideoScaleMethod; } GstVideoScaleMethod;
typedef struct _GstVideoScale GstVideoScale; typedef struct _GstVideoScale GstVideoScale;
typedef void (*GstVideoScaleScaler) (GstVideoScale *scale, guchar *src, guchar *dest);
struct _GstVideoScale { struct _GstVideoScale {
guint source_width; guint source_width;
guint source_height; guint source_height;
guint dest_width; guint dest_width;
guint dest_height; guint dest_height;
guint format; GstColorSpaceType format;
GstVideoScaleMethod method; GstVideoScaleMethod method;
/* private */ /* private */
guchar copy_row[8192]; guchar copy_row[8192];
guchar *temp; guchar *temp;
void (*scale) (GstVideoScale *scale, unsigned char *src, unsigned char *dest); GstVideoScaleScaler scale;
void (*scaler) (GstVideoScale *scale, unsigned char *src, unsigned char *dest, int sw, int sh, int dw, int dh); void (*scaler) (GstVideoScale *scale, guchar *src, guchar *dest, gint sw, gint sh, gint dw, gint dh);
unsigned char (*filter) (unsigned char *src, double x, double y, int sw, int sh); guchar (*filter) (guchar *src, gdouble x, gdouble y, gint sw, gint sh);
}; };
GstVideoScale *gst_videoscale_new(int sw, int sh, int dw, int dh, int format, GstVideoScaleMethod method); GstVideoScale *gst_videoscale_new(gint sw, gint sh, gint dw, gint dh, GstColorSpaceType format, GstVideoScaleMethod method);
#define gst_videoscale_scale(scaler, src, dest) (scaler)->scale((scaler), (src), (dest))
void gst_videoscale_destroy(GstVideoScale *scale); void gst_videoscale_destroy(GstVideoScale *scale);
#endif /* __GST_VIDEOSCALE_H__ */ #endif /* __GST_VIDEOSCALE_H__ */