public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Jean-Francois Moine <moinejf@free.fr>
To: Hans de Goede <j.w.r.degoede@hhs.nl>
Cc: Video 4 Linux <video4linux-list@redhat.com>
Subject: [PATCH] libv4l decoding to rgb24
Date: Fri, 01 Aug 2008 20:09:03 +0200	[thread overview]
Message-ID: <1217614143.1686.12.camel@localhost> (raw)

The RGB24 pixel format is often used in X11 applications.
This patch adds it to the V4L library.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>

--

diff -r cfa0097c9e85 v4l2-apps/lib/libv4l/libv4lconvert/bayer.c
--- a/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c	Fri Aug 01 18:23:15 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c	Fri Aug 01 19:57:00 2008 +0200
@@ -163,14 +163,10 @@
 }
 
 /* From libdc1394, which on turn was based on OpenCV's Bayer decoding */
-void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
-  unsigned char *bgr, int width, int height, unsigned int pixfmt)
+static void bayer_to_rgbbgr24(const unsigned char *bayer,
+  unsigned char *bgr, int width, int height, unsigned int pixfmt,
+	int start_with_green, int blue_line)
 {
-    int blue_line = pixfmt == V4L2_PIX_FMT_SBGGR8
-	|| pixfmt == V4L2_PIX_FMT_SGBRG8;
-    int start_with_green = pixfmt == V4L2_PIX_FMT_SGBRG8
-	|| pixfmt == V4L2_PIX_FMT_SGRBG8;
-
     /* render the first line */
     v4lconvert_border_bayer_line_to_bgr24(bayer, bayer + width, bgr, width,
       start_with_green, blue_line);
@@ -315,6 +311,26 @@
     /* render the last line */
     v4lconvert_border_bayer_line_to_bgr24(bayer + width, bayer, bgr, width,
       !start_with_green, !blue_line);
+}
+
+void v4lconvert_bayer_to_rgb24(const unsigned char *bayer,
+  unsigned char *bgr, int width, int height, unsigned int pixfmt)
+{
+	bayer_to_rgbbgr24(bayer, bgr, width, height, pixfmt,
+		pixfmt == V4L2_PIX_FMT_SGBRG8		/* start with green */
+			|| pixfmt == V4L2_PIX_FMT_SGRBG8,
+		pixfmt != V4L2_PIX_FMT_SBGGR8		/* blue line */
+			&& pixfmt != V4L2_PIX_FMT_SGBRG8);
+}
+
+void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
+  unsigned char *bgr, int width, int height, unsigned int pixfmt)
+{
+	bayer_to_rgbbgr24(bayer, bgr, width, height, pixfmt,
+		pixfmt == V4L2_PIX_FMT_SGBRG8		/* start with green */
+			|| pixfmt == V4L2_PIX_FMT_SGRBG8,
+		pixfmt == V4L2_PIX_FMT_SBGGR8		/* blue line */
+			|| pixfmt == V4L2_PIX_FMT_SGBRG8);
 }
 
 static void v4lconvert_border_bayer_line_to_y(
diff -r cfa0097c9e85 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h	Fri Aug 01 18:23:15 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h	Fri Aug 01 19:57:00 2008 +0200
@@ -71,6 +71,9 @@
 };
 
 
+void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dst,
+  int width, int height);
+
 void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dst,
   int width, int height);
 
@@ -92,6 +95,9 @@
 void v4lconvert_decode_pac207(const unsigned char *src, unsigned char *dst,
   int width, int height);
 
+void v4lconvert_bayer_to_rgb24(const unsigned char *bayer,
+  unsigned char *rgb, int width, int height, unsigned int pixfmt);
+
 void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
   unsigned char *rgb, int width, int height, unsigned int pixfmt);
 
diff -r cfa0097c9e85 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c	Fri Aug 01 18:23:15 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c	Fri Aug 01 19:57:00 2008 +0200
@@ -30,6 +30,7 @@
 /* Note for proper functioning of v4lconvert_enum_fmt the first entries in
   supported_src_pixfmts must match with the entries in supported_dst_pixfmts */
 #define SUPPORTED_DST_PIXFMTS \
+  V4L2_PIX_FMT_RGB24, \
   V4L2_PIX_FMT_BGR24, \
   V4L2_PIX_FMT_YUV420
 
@@ -191,6 +192,7 @@
   if (closest_fmt.fmt.pix.pixelformat != desired_pixfmt) {
     dest_fmt->fmt.pix.pixelformat = desired_pixfmt;
     switch (dest_fmt->fmt.pix.pixelformat) {
+      case V4L2_PIX_FMT_RGB24:
       case V4L2_PIX_FMT_BGR24:
 	dest_fmt->fmt.pix.bytesperline = dest_fmt->fmt.pix.width * 3;
 	dest_fmt->fmt.pix.sizeimage = dest_fmt->fmt.pix.width *
@@ -228,6 +230,7 @@
 
   /* sanity check, is the dest buffer large enough? */
   switch (dest_fmt->fmt.pix.pixelformat) {
+    case V4L2_PIX_FMT_RGB24:
     case V4L2_PIX_FMT_BGR24:
       needed = dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3;
       break;
@@ -283,12 +286,19 @@
       components[2] = components[1] + (dest_fmt->fmt.pix.width *
 				       dest_fmt->fmt.pix.height) / 4;
 
-      if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) {
+      switch (dest_fmt->fmt.pix.pixelformat) {
+      case V4L2_PIX_FMT_RGB24:
+	tinyjpeg_set_components(data->jdec, components, 1);
+	result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_RGB24);
+	break;
+      case V4L2_PIX_FMT_BGR24:
 	tinyjpeg_set_components(data->jdec, components, 1);
 	result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_BGR24);
-      } else {
+	break;
+      default:
 	tinyjpeg_set_components(data->jdec, components, 3);
 	result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_YUV420P);
+	break;
       }
 
       /* If the JPEG header checked out ok and we get an error during actual
@@ -304,12 +314,20 @@
     case V4L2_PIX_FMT_SGBRG8:
     case V4L2_PIX_FMT_SGRBG8:
     case V4L2_PIX_FMT_SRGGB8:
-      if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
+      switch (dest_fmt->fmt.pix.pixelformat) {
+      case V4L2_PIX_FMT_RGB24:
+	v4lconvert_bayer_to_rgb24(src, dest, dest_fmt->fmt.pix.width,
+		    dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat);
+        break;
+      case V4L2_PIX_FMT_BGR24:
 	v4lconvert_bayer_to_bgr24(src, dest, dest_fmt->fmt.pix.width,
 		    dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat);
-      else
+        break;
+      default:
 	v4lconvert_bayer_to_yuv420(src, dest, dest_fmt->fmt.pix.width,
 		    dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat);
+        break;
+      }
       break;
 
     /* YUYV line by line formats */
@@ -319,8 +337,8 @@
     {
       unsigned char tmpbuf[dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height *
 			   3 / 2];
-      unsigned char *my_dst = (dest_fmt->fmt.pix.pixelformat ==
-			       V4L2_PIX_FMT_BGR24) ? tmpbuf : dest;
+      unsigned char *my_dst = (dest_fmt->fmt.pix.pixelformat !=
+			       V4L2_PIX_FMT_YUV420) ? tmpbuf : dest;
 
       switch (src_fmt->fmt.pix.pixelformat) {
 	case V4L2_PIX_FMT_SPCA501:
@@ -337,10 +355,16 @@
 	  break;
       }
 
-      if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
+      switch (dest_fmt->fmt.pix.pixelformat) {
+      case V4L2_PIX_FMT_RGB24:
+	v4lconvert_yuv420_to_rgb24(tmpbuf, dest, dest_fmt->fmt.pix.width,
+				   dest_fmt->fmt.pix.height);
+	break;
+      case V4L2_PIX_FMT_BGR24:
 	v4lconvert_yuv420_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width,
 				   dest_fmt->fmt.pix.height);
-
+	break;
+      }
       break;
     }
 
@@ -370,12 +394,20 @@
 	  break;
       }
 
-      if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
+      switch (dest_fmt->fmt.pix.pixelformat) {
+      case V4L2_PIX_FMT_RGB24:
+	v4lconvert_bayer_to_rgb24(tmpbuf, dest, dest_fmt->fmt.pix.width,
+		    dest_fmt->fmt.pix.height, bayer_fmt);
+        break;
+      case V4L2_PIX_FMT_BGR24:
 	v4lconvert_bayer_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width,
 		    dest_fmt->fmt.pix.height, bayer_fmt);
-      else
+        break;
+      default:
 	v4lconvert_bayer_to_yuv420(tmpbuf, dest, dest_fmt->fmt.pix.width,
 		    dest_fmt->fmt.pix.height, bayer_fmt);
+        break;
+      }
       break;
     }
 
diff -r cfa0097c9e85 v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c
--- a/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c	Fri Aug 01 18:23:15 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c	Fri Aug 01 19:57:00 2008 +0200
@@ -34,14 +34,24 @@
 
 #define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color)))
 
-void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dest,
-  int width, int height)
+static void yuv420_to_rgbbgr24(const unsigned char *src,
+				unsigned char *dest,
+				int width, int height,
+				int bgr)
 {
   int i,j;
 
   const unsigned char *ysrc = src;
-  const unsigned char *usrc = src + width * height;
-  const unsigned char *vsrc = usrc + (width * height) / 4;
+  const unsigned char *usrc;
+  const unsigned char *vsrc;
+
+	if (bgr) {
+		vsrc = src + width * height;
+		usrc = vsrc + (width * height) / 4;
+	} else {
+		usrc = src + width * height;
+		vsrc = usrc + (width * height) / 4;
+	}
 
   for (i = 0; i < height; i++) {
     for (j = 0; j < width; j += 2) {
@@ -80,3 +90,15 @@
     }
   }
 }
+
+void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dest,
+  int width, int height)
+{
+	yuv420_to_rgbbgr24(src, dest, width, height, 0);
+}
+
+void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dest,
+  int width, int height)
+{
+	yuv420_to_rgbbgr24(src, dest, width, height, 1);
+}


-- 
Ken ar c'hentañ |             ** Breizh ha Linux atav! **
Jef             |               http://moinejf.free.fr/


--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

             reply	other threads:[~2008-08-01 18:47 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-01 18:09 Jean-Francois Moine [this message]
2008-08-01 20:02 ` [PATCH] libv4l decoding to rgb24 Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1217614143.1686.12.camel@localhost \
    --to=moinejf@free.fr \
    --cc=j.w.r.degoede@hhs.nl \
    --cc=video4linux-list@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox