From: Hans de Goede <j.w.r.degoede@hhs.nl>
To: Thierry Merle <thierry.merle@free.fr>
Cc: video4linux-list@redhat.com
Subject: PATCH: Add support for sonix (sn9c10x) bayer compression to libv4lconvert
Date: Thu, 03 Jul 2008 14:26:42 +0200 [thread overview]
Message-ID: <486CC582.1070705@hhs.nl> (raw)
[-- Attachment #1: Type: text/plain, Size: 101 bytes --]
Hi,
This patch adds support for sonix (sn9c10x) bayer compression to libv4lconvert.
Regards,
Hans
[-- Attachment #2: libv4l-sn9c10x.patch --]
[-- Type: text/plain, Size: 8101 bytes --]
Add support for sonix (sn9c10x) bayer compression to libv4lconvert
Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
diff -r e90ac66913c6 v4l2-apps/lib/libv4l/libv4lconvert/Makefile
--- a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile Thu Jul 03 13:54:53 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile Thu Jul 03 14:19:49 2008 +0200
@@ -9,7 +9,7 @@
LDFLAGS = -shared
CONVERT_LIB = libv4lconvert.so
-CONVERT_OBJS = libv4lconvert.o tinyjpeg.o \
+CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o \
jidctflt.o spca561-decompress.o rgbyuv.o spca501.o bayer.o
TARGETS = $(CONVERT_LIB)
INCLUDES = ../include/libv4lconvert.h
diff -r e90ac66913c6 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h Thu Jul 03 13:54:53 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h Thu Jul 03 14:19:49 2008 +0200
@@ -71,6 +71,9 @@
void v4lconvert_decode_spca561(const unsigned char *src, unsigned char *dst,
int width, int height);
+void v4lconvert_decode_sn9c10x(const unsigned char *src, unsigned char *dst,
+ int width, int height);
+
void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
unsigned char *rgb, int width, int height, unsigned int pixfmt);
diff -r e90ac66913c6 v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c
--- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c Thu Jul 03 13:54:53 2008 +0200
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c Thu Jul 03 14:19:49 2008 +0200
@@ -37,6 +37,7 @@
V4L2_PIX_FMT_SRGGB8,
V4L2_PIX_FMT_SPCA501,
V4L2_PIX_FMT_SPCA561,
+ V4L2_PIX_FMT_SN9C10X,
-1
};
@@ -314,23 +315,40 @@
dest_fmt->fmt.pix.height);
break;
+ /* compressed bayer formats */
case V4L2_PIX_FMT_SPCA561:
+ case V4L2_PIX_FMT_SN9C10X:
{
- static unsigned char tmpbuf[640 * 480];
- v4lconvert_decode_spca561(src, tmpbuf, dest_fmt->fmt.pix.width,
- dest_fmt->fmt.pix.height);
+ unsigned char tmpbuf[dest_fmt->fmt.pix.width*dest_fmt->fmt.pix.height];
+ unsigned int bayer_fmt;
+
+ switch (src_fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SPCA561:
+ v4lconvert_decode_spca561(src, tmpbuf, dest_fmt->fmt.pix.width,
+ dest_fmt->fmt.pix.height);
+ bayer_fmt = V4L2_PIX_FMT_SGBRG8;
+ break;
+ case V4L2_PIX_FMT_SN9C10X:
+ v4lconvert_decode_sn9c10x(src, tmpbuf, dest_fmt->fmt.pix.width,
+ dest_fmt->fmt.pix.height);
+ bayer_fmt = V4L2_PIX_FMT_SGBRG8;
+ break;
+ }
+
if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
v4lconvert_bayer_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width,
- dest_fmt->fmt.pix.height, V4L2_PIX_FMT_SGBRG8);
+ dest_fmt->fmt.pix.height, bayer_fmt);
else
v4lconvert_bayer_to_yuv420(tmpbuf, dest, dest_fmt->fmt.pix.width,
- dest_fmt->fmt.pix.height, V4L2_PIX_FMT_SGBRG8);
+ dest_fmt->fmt.pix.height, bayer_fmt);
break;
}
+
case V4L2_PIX_FMT_BGR24:
/* dest must be V4L2_PIX_FMT_YUV420 then */
printf("FIXME add bgr24 -> yuv420 conversion\n");
break;
+
case V4L2_PIX_FMT_YUV420:
/* dest must be V4L2_PIX_FMT_BGR24 then */
v4lconvert_yuv420_to_bgr24(src, dest, dest_fmt->fmt.pix.width,
diff -r e90ac66913c6 v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c Thu Jul 03 14:19:49 2008 +0200
@@ -0,0 +1,199 @@
+/*
+# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "libv4lconvert-priv.h"
+
+/* FIXME FIXME FIXME add permission notice from Bertrik Sikken to release
+ this code (which is his) under the LGPL */
+
+#define CLAMP(x) ((x)<0?0:((x)>255)?255:(x))
+
+typedef struct {
+ int is_abs;
+ int len;
+ int val;
+ int unk;
+} code_table_t;
+
+
+/* local storage */
+/* FIXME not thread safe !! */
+static code_table_t table[256];
+static int init_done = 0;
+
+/* global variable */
+static int sonix_unknown = 0;
+
+/*
+ sonix_decompress_init
+ =====================
+ pre-calculates a locally stored table for efficient huffman-decoding.
+
+ Each entry at index x in the table represents the codeword
+ present at the MSB of byte x.
+
+*/
+void sonix_decompress_init(void)
+{
+ int i;
+ int is_abs, val, len, unk;
+
+ for (i = 0; i < 256; i++) {
+ is_abs = 0;
+ val = 0;
+ len = 0;
+ unk = 0;
+ if ((i & 0x80) == 0) {
+ /* code 0 */
+ val = 0;
+ len = 1;
+ }
+ else if ((i & 0xE0) == 0x80) {
+ /* code 100 */
+ val = +4;
+ len = 3;
+ }
+ else if ((i & 0xE0) == 0xA0) {
+ /* code 101 */
+ val = -4;
+ len = 3;
+ }
+ else if ((i & 0xF0) == 0xD0) {
+ /* code 1101 */
+ val = +11;
+ len = 4;
+ }
+ else if ((i & 0xF0) == 0xF0) {
+ /* code 1111 */
+ val = -11;
+ len = 4;
+ }
+ else if ((i & 0xF8) == 0xC8) {
+ /* code 11001 */
+ val = +20;
+ len = 5;
+ }
+ else if ((i & 0xFC) == 0xC0) {
+ /* code 110000 */
+ val = -20;
+ len = 6;
+ }
+ else if ((i & 0xFC) == 0xC4) {
+ /* code 110001xx: unknown */
+ val = 0;
+ len = 8;
+ unk = 1;
+ }
+ else if ((i & 0xF0) == 0xE0) {
+ /* code 1110xxxx */
+ is_abs = 1;
+ val = (i & 0x0F) << 4;
+ len = 8;
+ }
+ table[i].is_abs = is_abs;
+ table[i].val = val;
+ table[i].len = len;
+ table[i].unk = unk;
+ }
+
+ sonix_unknown = 0;
+ init_done = 1;
+}
+
+
+/*
+ sonix_decompress
+ ================
+ decompresses an image encoded by a SN9C101 camera controller chip.
+
+ IN width
+ height
+ inp pointer to compressed frame (with header already stripped)
+ OUT outp pointer to decompressed frame
+
+ Returns 0 if the operation was successful.
+ Returns <0 if operation failed.
+
+*/
+void v4lconvert_decode_sn9c10x(const unsigned char *inp, unsigned char *outp,
+ int width, int height)
+{
+ int row, col;
+ int val;
+ int bitpos;
+ unsigned char code;
+ unsigned char *addr;
+
+ if (!init_done)
+ sonix_decompress_init();
+
+ bitpos = 0;
+ for (row = 0; row < height; row++) {
+
+ col = 0;
+
+ /* first two pixels in first two rows are stored as raw 8-bit */
+ if (row < 2) {
+ addr = inp + (bitpos >> 3);
+ code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
+ bitpos += 8;
+ *outp++ = code;
+
+ addr = inp + (bitpos >> 3);
+ code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
+ bitpos += 8;
+ *outp++ = code;
+
+ col += 2;
+ }
+
+ while (col < width) {
+ /* get bitcode from bitstream */
+ addr = inp + (bitpos >> 3);
+ code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
+
+ /* update bit position */
+ bitpos += table[code].len;
+
+ /* update code statistics */
+ sonix_unknown += table[code].unk;
+
+ /* calculate pixel value */
+ val = table[code].val;
+ if (!table[code].is_abs) {
+ /* value is relative to top and left pixel */
+ if (col < 2) {
+ /* left column: relative to top pixel */
+ val += outp[-2*width];
+ }
+ else if (row < 2) {
+ /* top row: relative to left pixel */
+ val += outp[-2];
+ }
+ else {
+ /* main area: average of left pixel and top pixel */
+ val += (outp[-2] + outp[-2*width]) / 2;
+ }
+ }
+
+ /* store pixel */
+ *outp++ = CLAMP(val);
+ col++;
+ }
+ }
+}
[-- Attachment #3: Type: text/plain, Size: 164 bytes --]
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list
next reply other threads:[~2008-07-03 12:27 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-03 12:26 Hans de Goede [this message]
2008-07-03 19:06 ` PATCH: Add support for sonix (sn9c10x) bayer compression to libv4lconvert Thierry Merle
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=486CC582.1070705@hhs.nl \
--to=j.w.r.degoede@hhs.nl \
--cc=thierry.merle@free.fr \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.