summaryrefslogtreecommitdiff
path: root/v4l2-apps/libv4l/libv4lconvert/flip.c
diff options
context:
space:
mode:
Diffstat (limited to 'v4l2-apps/libv4l/libv4lconvert/flip.c')
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/flip.c158
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);
}