Added conversion routines to sv module.

This commit is contained in:
Sjoerd Mullender 1993-03-16 12:25:30 +00:00
parent e537240c25
commit 6b517fdc95
3 changed files with 259 additions and 10 deletions

View File

@ -31,6 +31,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "modsupport.h"
#include "compile.h"
#include "ceval.h"
#include "yuv.h" /* for YUV conversion functions */
typedef struct {
OB_HEAD
@ -63,7 +64,7 @@ svc_conversion(self, args, function, factor)
captureobject *self;
object *args;
void (*function)();
int factor;
float factor;
{
object *output;
int invert;
@ -71,7 +72,7 @@ svc_conversion(self, args, function, factor)
if (!getargs(args, "i", &invert))
return NULL;
output = newsizedstringobject(NULL, self->ob_info.width * self->ob_info.height * factor);
output = newsizedstringobject(NULL, (int) (self->ob_info.width * self->ob_info.height * factor));
if (output == NULL)
return NULL;
@ -81,6 +82,46 @@ svc_conversion(self, args, function, factor)
return output;
}
/*
* 3 functions to convert from Starter Video YUV 4:1:1 format to
* Compression Library 4:2:2 Duplicate Chroma format.
*/
static object *
svc_YUVtoYUV422DC(self, args)
captureobject *self;
object *args;
{
if (self->ob_info.format != SV_YUV411_FRAMES) {
err_setstr(SvError, "data has bad format");
return NULL;
}
return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}
static object *
svc_YUVtoYUV422DC_quarter(self, args)
captureobject *self;
object *args;
{
if (self->ob_info.format != SV_YUV411_FRAMES) {
err_setstr(SvError, "data has bad format");
return NULL;
}
return svc_conversion(self, args, yuv_sv411_to_cl422dc_quartersize, 0.5);
}
static object *
svc_YUVtoYUV422DC_sixteenth(self, args)
captureobject *self;
object *args;
{
if (self->ob_info.format != SV_YUV411_FRAMES) {
err_setstr(SvError, "data has bad format");
return NULL;
}
return svc_conversion(self, args, yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}
static object *
svc_YUVtoRGB(self, args)
captureobject *self;
@ -94,7 +135,7 @@ svc_YUVtoRGB(self, args)
err_setstr(SvError, "data had bad format");
return NULL;
}
return svc_conversion(self, args, svYUVtoRGB, sizeof(long));
return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}
static object *
@ -106,7 +147,7 @@ svc_RGB8toRGB32(self, args)
err_setstr(SvError, "data has bad format");
return NULL;
}
return svc_conversion(self, args, svRGB8toRGB32, sizeof(long));
return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}
static object *
@ -118,7 +159,7 @@ svc_InterleaveFields(self, args)
err_setstr(SvError, "data has bad format");
return NULL;
}
return svc_conversion(self, args, svInterleaveFields, 1);
return svc_conversion(self, args, svInterleaveFields, 1.0);
}
static object *
@ -241,6 +282,9 @@ static struct methodlist capture_methods[] = {
{"UnlockCaptureData", svc_UnlockCaptureData},
{"FindVisibleRegion", svc_FindVisibleRegion},
{"GetFields", svc_GetFields},
{"YUVtoYUV422DC", svc_YUVtoYUV422DC},
{"YUVtoYUV422DC_quarter",svc_YUVtoYUV422DC_quarter},
{"YUVtoYUV422DC_sixteenth",svc_YUVtoYUV422DC_sixteenth},
#ifdef USE_GL
{"lrectwrite", svc_lrectwrite},
#endif
@ -817,7 +861,8 @@ static object *
sv_conversion(self, args, function, inputfactor, factor)
object *self, *args;
void (*function)();
int inputfactor, factor;
int inputfactor;
float factor;
{
int invert, width, height, inputlength;
char *input;
@ -831,7 +876,7 @@ sv_conversion(self, args, function, inputfactor, factor)
return NULL;
}
output = newsizedstringobject(NULL, width * height * factor);
output = newsizedstringobject(NULL, (int) (width * height * factor));
if (output == NULL)
return NULL;
@ -844,21 +889,21 @@ static object *
sv_InterleaveFields(self, args)
object *self, *args;
{
return sv_conversion(self, args, svInterleaveFields, 1, 1);
return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}
static object *
sv_RGB8toRGB32(self, args)
object *self, *args;
{
return sv_conversion(self, args, svRGB8toRGB32, 1, sizeof(long));
return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}
static object *
sv_YUVtoRGB(self, args)
object *self, *args;
{
return sv_conversion(self, args, svYUVtoRGB, 2, sizeof(long));
return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}
static void

87
Modules/yuv.h Normal file
View File

@ -0,0 +1,87 @@
/*
* SVideo YUV 4:1:1 format.
*
* 4 consecutive quadwords describe 8 pixels on 2 lines, as depicted
* below. An array of (width/4) of the below structure describes 2
* scan lines.
*
* +-------------------+
* | 00 | 01 | 02 | 03 | . . .
* +-------------------+
* | 10 | 11 | 12 | 13 | . . .
* +-------------------+
*/
struct yuv411 {
struct {
unsigned int dummy:8;
unsigned int y0:8;
unsigned int u0:2;
unsigned int v0:2;
unsigned int y1:8;
unsigned int u1:2;
unsigned int v1:2;
} v[4];
};
#define YUV411_Y00(y) (y).v[0].y0
#define YUV411_Y01(y) (y).v[1].y0
#define YUV411_Y02(y) (y).v[2].y0
#define YUV411_Y03(y) (y).v[3].y0
#define YUV411_Y10(y) (y).v[0].y1
#define YUV411_Y11(y) (y).v[1].y1
#define YUV411_Y12(y) (y).v[2].y1
#define YUV411_Y13(y) (y).v[3].y1
#define YUV411_U00(y) ((y).v[0].u0<<6|(y).v[1].u0<<4|(y).v[2].u0<<2|(y).v[3].u0)
#define YUV411_U01(y) YUV411_U00(y)
#define YUV411_U02(y) YUV411_U00(y)
#define YUV411_U03(y) YUV411_U00(y)
#define YUV411_U10(y) ((y).v[0].u1<<6|(y).v[1].u1<<4|(y).v[2].u1<<2|(y).v[3].u1)
#define YUV411_U11(y) YUV411_U10(y)
#define YUV411_U12(y) YUV411_U10(y)
#define YUV411_U13(y) YUV411_U10(y)
#define YUV411_V00(y) ((y).v[0].v0<<6|(y).v[1].v0<<4|(y).v[2].v0<<2|(y).v[3].v0)
#define YUV411_V01(y) YUV411_V00(y)
#define YUV411_V02(y) YUV411_V00(y)
#define YUV411_V03(y) YUV411_V00(y)
#define YUV411_V10(y) ((y).v[0].v1<<6|(y).v[1].v1<<4|(y).v[2].v1<<2|(y).v[3].v1)
#define YUV411_V11(y) YUV411_V10(y)
#define YUV411_V12(y) YUV411_V10(y)
#define YUV411_V13(y) YUV411_V10(y)
/*
* Compression Library YUV 4:2:2 format.
*
* 1 longword describes 2 pixels.
*
* +-------+
* | 0 | 1 |
* +-------+
*/
struct yuv422 {
unsigned int u:8;
unsigned int y0:8;
unsigned int v:8;
unsigned int y1:8;
};
#define YUV422_Y0(y) (y).y0
#define YUV422_Y1(y) (y).y1
#define YUV422_U0(y) (y).u
#define YUV422_U1(y) (y).u
#define YUV422_V0(y) (y).v
#define YUV422_V1(y) (y).v
/*
* Compression library YUV 4:2:2 Duplicate Chroma format.
*
* This is like the previous format, but the U and V values are
* duplicated vertically (and hence there is some redundancy in the
* data). With other words, lines 2*n and 2*n+1 have the same U and V
* values but different Y values.
*/
/*
* Conversion functions.
*/
void yuv_sv411_to_cl422dc(int, void *, void *, int, int);
void yuv_sv411_to_cl422dc_quartersize(int, void *, void *, int, int);
void yuv_sv411_to_cl422dc_sixteenthsize(int, void *, void *, int, int);

117
Modules/yuvconvert.c Normal file
View File

@ -0,0 +1,117 @@
#include "yuv.h"
void
yuv_sv411_to_cl422dc(int invert, void *data, void *yuv, int width, int height)
{
struct yuv411 *in = data;
struct yuv422 *out_even = yuv;
struct yuv422 *out_odd = out_even + width / 2;
int i, j; /* counters */
for (i = height / 2; i--; ) {
for (j = width / 4; j--; ) {
YUV422_Y0(*out_even) = YUV411_Y00(*in);
YUV422_U0(*out_even) = YUV411_U00(*in);
YUV422_V0(*out_even) = YUV411_V00(*in);
YUV422_Y1(*out_even) = YUV411_Y01(*in);
out_even++;
YUV422_Y0(*out_even) = YUV411_Y02(*in);
YUV422_U0(*out_even) = YUV411_U02(*in);
YUV422_V0(*out_even) = YUV411_V02(*in);
YUV422_Y1(*out_even) = YUV411_Y03(*in);
out_even++;
YUV422_Y0(*out_odd) = YUV411_Y10(*in);
YUV422_U0(*out_odd) = YUV411_U10(*in);
YUV422_V0(*out_odd) = YUV411_V10(*in);
YUV422_Y1(*out_odd) = YUV411_Y11(*in);
out_odd++;
YUV422_Y0(*out_odd) = YUV411_Y12(*in);
YUV422_U0(*out_odd) = YUV411_U12(*in);
YUV422_V0(*out_odd) = YUV411_V12(*in);
YUV422_Y1(*out_odd) = YUV411_Y13(*in);
out_odd++;
in++;
}
out_even += width / 2;
out_odd += width / 2;
}
}
void
yuv_sv411_to_cl422dc_quartersize(int invert, void *data, void *yuv,
int width, int height)
{
int w4 = width / 4; /* quarter of width is used often */
struct yuv411 *in_even = data;
struct yuv411 *in_odd = in_even + w4;
struct yuv422 *out_even = yuv;
struct yuv422 *out_odd = out_even + w4;
int i, j; /* counters */
int u, v; /* U and V values */
for (i = height / 4; i--; ) {
for (j = w4; j--; ) {
u = YUV411_U00(*in_even);
v = YUV411_V00(*in_even);
YUV422_Y0(*out_even) = YUV411_Y00(*in_even);
YUV422_U0(*out_even) = u;
YUV422_V0(*out_even) = v;
YUV422_Y1(*out_even) = YUV411_Y02(*in_even);
YUV422_Y0(*out_odd) = YUV411_Y10(*in_odd);
YUV422_U0(*out_odd) = u;
YUV422_V0(*out_odd) = v;
YUV422_Y1(*out_odd) = YUV411_Y12(*in_odd);
in_even++;
in_odd++;
out_even++;
out_odd++;
}
in_even += w4;
in_odd += w4;
out_even += w4;
out_odd += w4;
}
}
void
yuv_sv411_to_cl422dc_sixteenthsize(int invert, void *data, void *yuv,
int width, int height)
{
int w4_3 = 3 * width / 4; /* three quarters of width is used often */
int w8 = width / 8; /* and so is one eighth */
struct yuv411 *in_even = data;
struct yuv411 *in_odd = in_even + width / 2;
struct yuv422 *out_even = yuv;
struct yuv422 *out_odd = out_even + w8;
int i, j; /* counters */
int u, v; /* U and V values */
for (i = height / 8; i--; ) {
for (j = w8; j--; ) {
u = YUV411_U00(in_even[0]);
v = YUV411_V00(in_even[0]);
YUV422_Y0(*out_even) = YUV411_Y00(in_even[0]);
YUV422_U0(*out_even) = u;
YUV422_V0(*out_even) = v;
YUV422_Y1(*out_even) = YUV411_Y00(in_even[1]);
YUV422_Y0(*out_odd) = YUV411_Y00(in_odd[0]);
YUV422_U0(*out_odd) = u;
YUV422_V0(*out_odd) = v;
YUV422_Y1(*out_odd) = YUV411_Y00(in_even[1]);
in_even += 2;
in_odd += 2;
out_even++;
out_odd++;
}
in_even += w4_3;
in_odd += w4_3;
out_even += w8;
out_odd += w8;
}
}