diff options
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/flip.c')
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/flip.c | 158 |
1 files changed, 141 insertions, 17 deletions
diff --git a/v4l2-apps/libv4l/libv4lconvert/flip.c b/v4l2-apps/libv4l/libv4lconvert/flip.c index f47afde72..8c4d8233c 100644 --- a/v4l2-apps/libv4l/libv4lconvert/flip.c +++ b/v4l2-apps/libv4l/libv4lconvert/flip.c @@ -20,8 +20,100 @@ */ +#include <string.h> #include "libv4lconvert-priv.h" +static void v4lconvert_vflip_rgbbgr24(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int y; + + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline; + for (y = 0; y < fmt->fmt.pix.height; y++) { + src -= fmt->fmt.pix.bytesperline; + memcpy(dest, src, fmt->fmt.pix.width * 3); + dest += fmt->fmt.pix.width * 3; + } +} + +static void v4lconvert_vflip_yuv420(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int y; + + /* First flip the Y plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline; + for (y = 0; y < fmt->fmt.pix.height; y++) { + src -= fmt->fmt.pix.bytesperline; + memcpy(dest, src, fmt->fmt.pix.width); + dest += fmt->fmt.pix.width; + } + + /* Now flip the U plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline * 5 / 4; + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src -= fmt->fmt.pix.bytesperline / 2; + memcpy(dest, src, fmt->fmt.pix.width / 2); + dest += fmt->fmt.pix.width / 2; + } + + /* Last flip the V plane */ + src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline / 2; + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src -= fmt->fmt.pix.bytesperline / 2; + memcpy(dest, src, fmt->fmt.pix.width / 2); + dest += fmt->fmt.pix.width / 2; + } +} + +static void v4lconvert_hflip_rgbbgr24(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int x, y; + + for (y = 0; y < fmt->fmt.pix.height; y++) { + src += fmt->fmt.pix.width * 3; + for (x = 0; x < fmt->fmt.pix.width; x++) { + src -= 3; + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest += 3; + } + src += fmt->fmt.pix.bytesperline; + } +} + +static void v4lconvert_hflip_yuv420(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int x, y; + + /* First flip the Y plane */ + for (y = 0; y < fmt->fmt.pix.height; y++) { + src += fmt->fmt.pix.width; + for (x = 0; x < fmt->fmt.pix.width; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline; + } + + /* Now flip the U plane */ + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src += fmt->fmt.pix.width / 2; + for (x = 0; x < fmt->fmt.pix.width / 2; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline / 2; + } + + /* Last flip the V plane */ + for (y = 0; y < fmt->fmt.pix.height / 2; y++) { + src += fmt->fmt.pix.width / 2; + for (x = 0; x < fmt->fmt.pix.width / 2; x++) + *dest++ = *--src; + src += fmt->fmt.pix.bytesperline / 2; + } +} + static void v4lconvert_rotate180_rgbbgr24(const unsigned char *src, unsigned char *dst, int width, int height) { @@ -106,37 +198,69 @@ static void v4lconvert_rotate90_yuv420(const unsigned char *src, } } -void v4lconvert_rotate(unsigned char *src, unsigned char *dest, - int width, int height, unsigned int pix_fmt, int rotate) +void v4lconvert_rotate90(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt) +{ + int tmp; + + tmp = fmt->fmt.pix.width; + fmt->fmt.pix.width = fmt->fmt.pix.height; + fmt->fmt.pix.height = tmp; + + switch (fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + v4lconvert_rotate90_rgbbgr24(src, dest, fmt->fmt.pix.width, + fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + v4lconvert_rotate90_yuv420(src, dest, fmt->fmt.pix.width, + fmt->fmt.pix.height); + break; + } +} + +void v4lconvert_flip(unsigned char *src, unsigned char *dest, + struct v4l2_format *fmt, int hflip, int vflip) { - switch (rotate) { - case 0: - break; - case 90: - switch (pix_fmt) { + if (vflip && hflip) { + switch (fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + v4lconvert_rotate180_rgbbgr24(src, dest, fmt->fmt.pix.width, + fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + v4lconvert_rotate180_yuv420(src, dest, fmt->fmt.pix.width, + fmt->fmt.pix.height); + break; + } + } else if (hflip) { + switch (fmt->fmt.pix.pixelformat) { case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: - v4lconvert_rotate90_rgbbgr24(src, dest, width, height); + v4lconvert_hflip_rgbbgr24(src, dest, fmt); break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: - v4lconvert_rotate90_yuv420(src, dest, width, height); + v4lconvert_hflip_yuv420(src, dest, fmt); break; } - break; - case 180: - switch (pix_fmt) { + } else if (vflip) { + switch (fmt->fmt.pix.pixelformat) { case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: - v4lconvert_rotate180_rgbbgr24(src, dest, width, height); + v4lconvert_vflip_rgbbgr24(src, dest, fmt); break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: - v4lconvert_rotate180_yuv420(src, dest, width, height); + v4lconvert_vflip_yuv420(src, dest, fmt); break; } - break; - default: - printf("FIXME add %d degrees rotation\n", rotate); } + + /* Our newly written data has no padding */ + v4lconvert_fixup_fmt(fmt); } |