|
From: Luc S. <lu...@sa...> - 2006-03-01 17:43:40
|
> Maybe try this one, I have set in luvcview to resize the gui part . In
> luvcview i only resize the xaxis as y is a constant, this one may resize the
> two axis.
Thanks for the tip, i've used your method, but didn't give good result when
converting YUYV to YUV420P with resize in one pass. So i keep the idea to
keep the last known good value, but discarding it sometimes. I'll add this
algorithm in ekiga to convert palete (firewire UYVY and YUYV) without using a
temp buffer.
I've test this algo with a 1280x960 image to 320x240, 512x384, 640x480, 960x720.
#define FIX_FLOAT 12
unsigned int dx = (in->width<<FIX_FLOAT)/out->width;
unsigned int dy = (in->height<<FIX_FLOAT)/out->height;
unsigned int fy, fx;
for (fy=0, h=0; h<out->height; h+=2, fy+=dy*2)
{
/* Copy the first line with U&V */
unsigned int yy = fy>>FIX_FLOAT;
unsigned int yy2 = (fy+dy)>>FIX_FLOAT;
const unsigned char *line1, *line2;
unsigned char lastU, lastV;
line1 = in->data[0] + (yy*2*in->width);
line2 = in->data[0] + (yy2*2*in->width);
lastU = line1[1];
lastV = line1[3];
for (fx=0, x=0; x<out->width; x+=2, fx+=dx*2)
{
unsigned int xx = (fx>>FIX_FLOAT)*2;
*y++ = line1[xx];
if ( (xx&2) == 0)
{
*u++ = lastU = (line1[xx+1] + line2[xx+1])/2;
*v++ = lastV = (line1[xx+3] + line2[xx+3])/2;
}
else
{
*u++ = lastU;
*v++ = lastV = (line1[xx+1] + line2[xx+1])/2;
}
xx = ((fx+dx)>>FIX_FLOAT)*2;
*y++ = line1[xx];
if ( (xx&2) == 0)
lastU = (line1[xx+1] + line2[xx+1])/2;
else
lastV = (line1[xx+1] + line2[xx+1])/2;
}
/* Copy the second line without U&V */
for (fx=0, x=0; x<out->width; x++, fx+=dx)
{
unsigned int xx = (fx>>FIX_FLOAT)*2;
*y++ = line2[xx];
}
}
|