From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m63J4kOq021580 for ; Thu, 3 Jul 2008 15:04:46 -0400 Received: from smtp4-g19.free.fr (smtp4-g19.free.fr [212.27.42.30]) by mx3.redhat.com (8.13.8/8.13.8) with ESMTP id m63J4XdF020418 for ; Thu, 3 Jul 2008 15:04:34 -0400 Message-ID: <486D2338.50205@free.fr> Date: Thu, 03 Jul 2008 21:06:32 +0200 From: Thierry Merle MIME-Version: 1.0 To: Hans de Goede References: <486CC582.1070705@hhs.nl> In-Reply-To: <486CC582.1070705@hhs.nl> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Cc: video4linux-list@redhat.com, v4l2 library Subject: Re: PATCH: Add support for sonix (sn9c10x) bayer compression to libv4lconvert List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: video4linux-list-bounces@redhat.com Errors-To: video4linux-list-bounces@redhat.com List-ID: Hans de Goede a écrit : > Hi, > > This patch adds support for sonix (sn9c10x) bayer compression to > libv4lconvert. > > Regards, > > Hans > Add support for sonix (sn9c10x) bayer compression to libv4lconvert > > Signed-off-by: Hans de Goede > 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 > + > +# 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++; > + } > + } > +} > Applied on http://www.linuxtv.org/hg/~tmerle/v4l2-library Cheers, Thierry -- video4linux-list mailing list Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe https://www.redhat.com/mailman/listinfo/video4linux-list