diff options
Diffstat (limited to 'v4l2-apps/lib/libv4l/libv4lconvert')
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/Makefile | 70 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/bayer.c | 613 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/flip.c | 107 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c | 286 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h | 166 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c | 737 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/pac207.c | 418 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c | 316 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c | 287 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/spca501.c | 126 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c | 1003 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h | 121 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c | 2463 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h | 74 |
14 files changed, 0 insertions, 6787 deletions
diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile deleted file mode 100644 index 641d19d6e..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -override CPPFLAGS += -I../include -I../../../include -fvisibility=hidden - -CFLAGS := -g -O1 -CFLAGS += -Wall -Wno-unused -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes - -ifeq ($(LINKTYPE),static) -CONVERT_LIB = libv4lconvert.a -else -CONVERT_LIB = libv4lconvert.so -override CPPFLAGS += -fPIC -endif - -CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o pac207.o flip.o \ - jidctflt.o spca561-decompress.o rgbyuv.o spca501.o bayer.o -TARGETS = $(CONVERT_LIB) libv4lconvert.pc -INCLUDES = ../include/libv4lconvert.h - -ifeq ($(LIB_RELEASE),) -LIB_RELEASE = 0 -endif - -ifeq ($(PREFIX),) -PREFIX = /usr/local -endif - -ifeq ($(LIBDIR),) -LIBDIR = $(PREFIX)/lib -endif - -all: $(TARGETS) - -$(CONVERT_LIB): $(CONVERT_OBJS) - -libv4lconvert.pc: - @echo prefix=$(PREFIX) > libv4lconvert.pc - @echo libdir=$(LIBDIR) >> libv4lconvert.pc - @echo >> libv4lconvert.pc - @echo 'Name: libv4lconvert' >> libv4lconvert.pc - @echo 'Description: v4l format conversion library' >> libv4lconvert.pc - @echo 'Version: '$(V4L2_LIB_VERSION) >> libv4lconvert.pc - @echo 'Libs: -L$${libdir} -lv4lconvert' >> libv4lconvert.pc - @echo 'Cflags: -I$${prefix}/include' >> libv4lconvert.pc - -install: all - mkdir -p $(DESTDIR)$(PREFIX)/include - install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include - mkdir -p $(DESTDIR)$(LIBDIR) -ifeq ($(LINKTYPE),static) - mkdir -p $(DESTDIR)$(LIBDIR) - install -m 644 $(CONVERT_LIB) $(DESTDIR)$(LIBDIR) -else - install -m 755 $(CONVERT_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) - cd $(DESTDIR)$(LIBDIR) && \ - ln -f -s $(CONVERT_LIB).$(LIB_RELEASE) $(CONVERT_LIB) -endif - mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig - install -m 644 libv4lconvert.pc $(DESTDIR)$(LIBDIR)/pkgconfig - -clean:: - rm -f *.a *.so* *.o *.d libv4lconvert.pc log *~ - -%.o: %.c - $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< - -%.so: - $(CC) -shared $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ - ln -f -s $@.$(LIB_RELEASE) $@ - -%.a: - $(AR) cqs $@ $^ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c b/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c deleted file mode 100644 index ca7bb486f..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/bayer.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * lib4lconvert, video4linux2 format conversion lib - * (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - * - * This library 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 library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Note: original bayer_to_bgr24 code from : - * 1394-Based Digital Camera Control Library - * - * Bayer pattern decoding functions - * - * Written by Damien Douxchamps and Frederic Devernay - * - * Note that the original bayer.c in libdc1394 supports many different - * bayer decode algorithms, for lib4lconvert the one in this file has been - * chosen (and optimized a bit) and the other algorithm's have been removed, - * see bayer.c from libdc1394 for all supported algorithms - */ - -#include <string.h> -#include "libv4lconvert-priv.h" - -/************************************************************** - * Color conversion functions for cameras that can * - * output raw-Bayer pattern images, such as some Basler and * - * Point Grey camera. Most of the algos presented here come * - * from http://www-ise.stanford.edu/~tingchen/ and have been * - * converted from Matlab to C and extended to all elementary * - * patterns. * - **************************************************************/ - -/* insprired by OpenCV's Bayer decoding */ -static void v4lconvert_border_bayer_line_to_bgr24( - const unsigned char* bayer, const unsigned char* adjacent_bayer, - unsigned char *bgr, int width, int start_with_green, int blue_line) -{ - int t0, t1; - - if (start_with_green) { - /* First pixel */ - if (blue_line) { - *bgr++ = bayer[1]; - *bgr++ = bayer[0]; - *bgr++ = adjacent_bayer[0]; - } else { - *bgr++ = adjacent_bayer[0]; - *bgr++ = bayer[0]; - *bgr++ = bayer[1]; - } - /* Second pixel */ - t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; - t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; - if (blue_line) { - *bgr++ = bayer[1]; - *bgr++ = t0; - *bgr++ = t1; - } else { - *bgr++ = t1; - *bgr++ = t0; - *bgr++ = bayer[1]; - } - bayer++; - adjacent_bayer++; - width -= 2; - } else { - /* First pixel */ - t0 = (bayer[1] + adjacent_bayer[0] + 1) >> 1; - if (blue_line) { - *bgr++ = bayer[0]; - *bgr++ = t0; - *bgr++ = adjacent_bayer[1]; - } else { - *bgr++ = adjacent_bayer[1]; - *bgr++ = t0; - *bgr++ = bayer[0]; - } - width--; - } - - if (blue_line) { - for ( ; width > 2; width -= 2) { - t0 = (bayer[0] + bayer[2] + 1) >> 1; - *bgr++ = t0; - *bgr++ = bayer[1]; - *bgr++ = adjacent_bayer[1]; - bayer++; - adjacent_bayer++; - - t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; - t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; - *bgr++ = bayer[1]; - *bgr++ = t0; - *bgr++ = t1; - bayer++; - adjacent_bayer++; - } - } else { - for ( ; width > 2; width -= 2) { - t0 = (bayer[0] + bayer[2] + 1) >> 1; - *bgr++ = adjacent_bayer[1]; - *bgr++ = bayer[1]; - *bgr++ = t0; - bayer++; - adjacent_bayer++; - - t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; - t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; - *bgr++ = t1; - *bgr++ = t0; - *bgr++ = bayer[1]; - bayer++; - adjacent_bayer++; - } - } - - if (width == 2) { - /* Second to last pixel */ - t0 = (bayer[0] + bayer[2] + 1) >> 1; - if (blue_line) { - *bgr++ = t0; - *bgr++ = bayer[1]; - *bgr++ = adjacent_bayer[1]; - } else { - *bgr++ = adjacent_bayer[1]; - *bgr++ = bayer[1]; - *bgr++ = t0; - } - /* Last pixel */ - t0 = (bayer[1] + adjacent_bayer[2] + 1) >> 1; - if (blue_line) { - *bgr++ = bayer[2]; - *bgr++ = t0; - *bgr++ = adjacent_bayer[1]; - } else { - *bgr++ = adjacent_bayer[1]; - *bgr++ = t0; - *bgr++ = bayer[2]; - } - } else { - /* Last pixel */ - if (blue_line) { - *bgr++ = bayer[0]; - *bgr++ = bayer[1]; - *bgr++ = adjacent_bayer[1]; - } else { - *bgr++ = adjacent_bayer[1]; - *bgr++ = bayer[1]; - *bgr++ = bayer[0]; - } - } -} - -/* From libdc1394, which on turn was based on OpenCV's Bayer decoding */ -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) -{ - /* render the first line */ - v4lconvert_border_bayer_line_to_bgr24(bayer, bayer + width, bgr, width, - start_with_green, blue_line); - bgr += width * 3; - - /* reduce height by 2 because of the special case top/bottom line */ - for (height -= 2; height; height--) { - int t0, t1; - /* (width - 2) because of the border */ - const unsigned char *bayerEnd = bayer + (width - 2); - - if (start_with_green) { - /* OpenCV has a bug in the next line, which was - t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; */ - t0 = (bayer[1] + bayer[width * 2 + 1] + 1) >> 1; - /* Write first pixel */ - t1 = (bayer[0] + bayer[width * 2] + bayer[width + 1] + 1) / 3; - if (blue_line) { - *bgr++ = t0; - *bgr++ = t1; - *bgr++ = bayer[width]; - } else { - *bgr++ = bayer[width]; - *bgr++ = t1; - *bgr++ = t0; - } - - /* Write second pixel */ - t1 = (bayer[width] + bayer[width + 2] + 1) >> 1; - if (blue_line) { - *bgr++ = t0; - *bgr++ = bayer[width + 1]; - *bgr++ = t1; - } else { - *bgr++ = t1; - *bgr++ = bayer[width + 1]; - *bgr++ = t0; - } - bayer++; - } else { - /* Write first pixel */ - t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; - if (blue_line) { - *bgr++ = t0; - *bgr++ = bayer[width]; - *bgr++ = bayer[width + 1]; - } else { - *bgr++ = bayer[width + 1]; - *bgr++ = bayer[width]; - *bgr++ = t0; - } - } - - if (blue_line) { - for (; bayer <= bayerEnd - 2; bayer += 2) { - t0 = (bayer[0] + bayer[2] + bayer[width * 2] + - bayer[width * 2 + 2] + 2) >> 2; - t1 = (bayer[1] + bayer[width] + - bayer[width + 2] + bayer[width * 2 + 1] + - 2) >> 2; - *bgr++ = t0; - *bgr++ = t1; - *bgr++ = bayer[width + 1]; - - t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; - t1 = (bayer[width + 1] + bayer[width + 3] + - 1) >> 1; - *bgr++ = t0; - *bgr++ = bayer[width + 2]; - *bgr++ = t1; - } - } else { - for (; bayer <= bayerEnd - 2; bayer += 2) { - t0 = (bayer[0] + bayer[2] + bayer[width * 2] + - bayer[width * 2 + 2] + 2) >> 2; - t1 = (bayer[1] + bayer[width] + - bayer[width + 2] + bayer[width * 2 + 1] + - 2) >> 2; - *bgr++ = bayer[width + 1]; - *bgr++ = t1; - *bgr++ = t0; - - t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; - t1 = (bayer[width + 1] + bayer[width + 3] + - 1) >> 1; - *bgr++ = t1; - *bgr++ = bayer[width + 2]; - *bgr++ = t0; - } - } - - if (bayer < bayerEnd) { - /* write second to last pixel */ - t0 = (bayer[0] + bayer[2] + bayer[width * 2] + - bayer[width * 2 + 2] + 2) >> 2; - t1 = (bayer[1] + bayer[width] + - bayer[width + 2] + bayer[width * 2 + 1] + - 2) >> 2; - if (blue_line) { - *bgr++ = t0; - *bgr++ = t1; - *bgr++ = bayer[width + 1]; - } else { - *bgr++ = bayer[width + 1]; - *bgr++ = t1; - *bgr++ = t0; - } - /* write last pixel */ - t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; - if (blue_line) { - *bgr++ = t0; - *bgr++ = bayer[width + 2]; - *bgr++ = bayer[width + 1]; - } else { - *bgr++ = bayer[width + 1]; - *bgr++ = bayer[width + 2]; - *bgr++ = t0; - } - bayer++; - } else { - /* write last pixel */ - t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; - t1 = (bayer[1] + bayer[width * 2 + 1] + bayer[width] + 1) / 3; - if (blue_line) { - *bgr++ = t0; - *bgr++ = t1; - *bgr++ = bayer[width + 1]; - } else { - *bgr++ = bayer[width + 1]; - *bgr++ = t1; - *bgr++ = t0; - } - } - - /* skip 2 border pixels */ - bayer += 2; - - blue_line = !blue_line; - start_with_green = !start_with_green; - } - - /* 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( - const unsigned char* bayer, const unsigned char* adjacent_bayer, - unsigned char *y, int width, int start_with_green, int blue_line) -{ - int t0, t1; - - if (start_with_green) { - /* First pixel */ - if (blue_line) { - *y++ = (8453*adjacent_bayer[0] + 16594*bayer[0] + 3223*bayer[1] + 524288) - >> 15; - } else { - *y++ = (8453*bayer[1] + 16594*bayer[0] + 3223*adjacent_bayer[0] + 524288) - >> 15; - } - /* Second pixel */ - t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; - t1 = adjacent_bayer[0] + adjacent_bayer[2]; - if (blue_line) { - *y++ = (4226*t1 + 5531*t0 + 3223*bayer[1] + 524288) >> 15; - } else { - *y++ = (8453*bayer[1] + 5531*t0 + 1611*t1 + 524288) >> 15; - } - bayer++; - adjacent_bayer++; - width -= 2; - } else { - /* First pixel */ - t0 = bayer[1] + adjacent_bayer[0]; - if (blue_line) { - *y++ = (8453*adjacent_bayer[1] + 8297*t0 + 3223*bayer[0] + 524288) - >> 15; - } else { - *y++ = (8453*bayer[0] + 8297*t0 + 3223*adjacent_bayer[1] + 524288) - >> 15; - } - width--; - } - - if (blue_line) { - for ( ; width > 2; width -= 2) { - t0 = bayer[0] + bayer[2]; - *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 1611*t0 + 524288) - >> 15; - bayer++; - adjacent_bayer++; - - t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; - t1 = adjacent_bayer[0] + adjacent_bayer[2]; - *y++ = (4226*t1 + 5531*t0 + 3223*bayer[1] + 524288) >> 15; - bayer++; - adjacent_bayer++; - } - } else { - for ( ; width > 2; width -= 2) { - t0 = bayer[0] + bayer[2]; - *y++ = (4226*t0 + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) - >> 15; - bayer++; - adjacent_bayer++; - - t0 = bayer[0] + bayer[2] + adjacent_bayer[1]; - t1 = adjacent_bayer[0] + adjacent_bayer[2]; - *y++ = (8453*bayer[1] + 5531*t0 + 1611*t1 + 524288) >> 15; - bayer++; - adjacent_bayer++; - } - } - - if (width == 2) { - /* Second to last pixel */ - t0 = bayer[0] + bayer[2]; - if (blue_line) { - *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 1611*t0 + 524288) - >> 15; - } else { - *y++ = (4226*t0 + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) - >> 15; - } - /* Last pixel */ - t0 = bayer[1] + adjacent_bayer[2]; - if (blue_line) { - *y++ = (8453*adjacent_bayer[1] + 8297*t0 + 3223*bayer[2] + 524288) - >> 15; - } else { - *y++ = (8453*bayer[2] + 8297*t0 + 3223*adjacent_bayer[1] + 524288) - >> 15; - } - } else { - /* Last pixel */ - if (blue_line) { - *y++ = (8453*adjacent_bayer[1] + 16594*bayer[1] + 3223*bayer[0] + 524288) - >> 15; - } else { - *y++ = (8453*bayer[0] + 16594*bayer[1] + 3223*adjacent_bayer[1] + 524288) - >> 15; - } - } -} - -void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, - unsigned char *yuv, int width, int height, unsigned int pixfmt) -{ - int blue_line = 0, start_with_green = 0, x, y; - unsigned char *ydst = yuv; - unsigned char *udst = yuv + width * height; - unsigned char *vdst = udst + width * height / 4; - - /* First calculate the u and v planes 2x2 pixels at a time */ - switch (pixfmt) { - case V4L2_PIX_FMT_SBGGR8: - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { - int b, g, r; - b = bayer[x]; - g = bayer[x+1]; - g += bayer[x+width]; - r = bayer[x+width+1]; - *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; - *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; - } - bayer += 2 * width; - } - blue_line = 1; - break; - - case V4L2_PIX_FMT_SRGGB8: - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { - int b, g, r; - r = bayer[x]; - g = bayer[x+1]; - g += bayer[x+width]; - b = bayer[x+width+1]; - *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; - *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; - } - bayer += 2 * width; - } - break; - - case V4L2_PIX_FMT_SGBRG8: - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { - int b, g, r; - g = bayer[x]; - b = bayer[x+1]; - r = bayer[x+width]; - g += bayer[x+width+1]; - *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; - *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; - } - bayer += 2 * width; - } - blue_line = 1; - start_with_green = 1; - break; - - case V4L2_PIX_FMT_SGRBG8: - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { - int b, g, r; - g = bayer[x]; - r = bayer[x+1]; - b = bayer[x+width]; - g += bayer[x+width+1]; - *udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15; - *vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15; - } - bayer += 2 * width; - } - start_with_green = 1; - break; - } - - bayer -= width * height; - - /* render the first line */ - v4lconvert_border_bayer_line_to_y(bayer, bayer + width, ydst, width, - start_with_green, blue_line); - ydst += width; - - /* reduce height by 2 because of the border */ - for (height -= 2; height; height--) { - int t0, t1; - /* (width - 2) because of the border */ - const unsigned char *bayerEnd = bayer + (width - 2); - - if (start_with_green) { - t0 = bayer[1] + bayer[width * 2 + 1]; - /* Write first pixel */ - t1 = bayer[0] + bayer[width * 2] + bayer[width + 1]; - if (blue_line) - *ydst++ = (8453*bayer[width] + 5516*t1 + 1661*t0 + 524288) >> 15; - else - *ydst++ = (4226*t0 + 5516*t1 + 3223*bayer[width] + 524288) >> 15; - - /* Write second pixel */ - t1 = bayer[width] + bayer[width + 2]; - if (blue_line) - *ydst++ = (4226*t1 + 16594*bayer[width+1] + 1611*t0 + 524288) >> 15; - else - *ydst++ = (4226*t0 + 16594*bayer[width+1] + 1611*t1 + 524288) >> 15; - bayer++; - } else { - /* Write first pixel */ - t0 = bayer[0] + bayer[width * 2]; - if (blue_line) { - *ydst++ = (8453*bayer[width+1] + 16594*bayer[width] + 1661*t0 + - 524288) >> 15; - } else { - *ydst++ = (4226*t0 + 16594*bayer[width] + 3223*bayer[width+1] + - 524288) >> 15; - } - } - - if (blue_line) { - for (; bayer <= bayerEnd - 2; bayer += 2) { - t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; - t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; - *ydst++ = (8453*bayer[width+1] + 4148*t1 + 806*t0 + 524288) >> 15; - - t0 = bayer[2] + bayer[width * 2 + 2]; - t1 = bayer[width + 1] + bayer[width + 3]; - *ydst++ = (4226*t1 + 16594*bayer[width+2] + 1611*t0 + 524288) >> 15; - } - } else { - for (; bayer <= bayerEnd - 2; bayer += 2) { - t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; - t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; - *ydst++ = (2113*t0 + 4148*t1 + 3223*bayer[width+1] + 524288) >> 15; - - t0 = bayer[2] + bayer[width * 2 + 2]; - t1 = bayer[width + 1] + bayer[width + 3]; - *ydst++ = (4226*t0 + 16594*bayer[width+2] + 1611*t1 + 524288) >> 15; - } - } - - if (bayer < bayerEnd) { - /* Write second to last pixel */ - t0 = bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2]; - t1 = bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1]; - if (blue_line) - *ydst++ = (8453*bayer[width+1] + 4148*t1 + 806*t0 + 524288) >> 15; - else - *ydst++ = (2113*t0 + 4148*t1 + 3223*bayer[width+1] + 524288) >> 15; - - /* write last pixel */ - t0 = bayer[2] + bayer[width * 2 + 2]; - if (blue_line) { - *ydst++ = (8453*bayer[width+1] + 16594*bayer[width+2] + 1661*t0 + - 524288) >> 15; - } else { - *ydst++ = (4226*t0 + 16594*bayer[width+2] + 3223*bayer[width+1] + - 524288) >> 15; - } - bayer++; - } else { - /* write last pixel */ - t0 = bayer[0] + bayer[width * 2]; - t1 = bayer[1] + bayer[width * 2 + 1] + bayer[width]; - if (blue_line) - *ydst++ = (8453*bayer[width+1] + 5516*t1 + 1661*t0 + 524288) >> 15; - else - *ydst++ = (4226*t0 + 5516*t1 + 3223*bayer[width+1] + 524288) >> 15; - } - - /* skip 2 border pixels */ - bayer += 2; - - blue_line = !blue_line; - start_with_green = !start_with_green; - } - - /* render the last line */ - v4lconvert_border_bayer_line_to_y(bayer + width, bayer, ydst, width, - !start_with_green, !blue_line); -} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/flip.c b/v4l2-apps/lib/libv4l/libv4lconvert/flip.c deleted file mode 100644 index cd3468a89..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/flip.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - -# RGB / YUV flip/rotate routines - -# (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 Lesser 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" - -void v4lconvert_rotate180_rgbbgr24(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i; - - src += 3 * width * height - 3; - - for (i = 0; i < width * height; i++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst += 3; - src -= 3; - } -} - -void v4lconvert_rotate180_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i; - - /* First flip x and y of the Y plane */ - src += width * height - 1; - for (i = 0; i < width * height; i++) - *dst++ = *src--; - - /* Now flip the U plane */ - src += width * height * 5 / 4; - for (i = 0; i < width * height / 4; i++) - *dst++ = *src--; - - /* Last flip the V plane */ - src += width * height / 2; - for (i = 0; i < width * height / 4; i++) - *dst++ = *src--; -} - -void v4lconvert_rotate90_rgbbgr24(const unsigned char *src, unsigned char *dst, - int destwidth, int destheight) -{ - int x, y; -#define srcwidth destheight -#define srcheight destwidth - - for (y = 0; y < destheight; y++) - for (x = 0; x < destwidth; x++) { - int offset = ((srcheight - x - 1) * srcwidth + y) * 3; - *dst++ = src[offset++]; - *dst++ = src[offset++]; - *dst++ = src[offset]; - } -} - -void v4lconvert_rotate90_yuv420(const unsigned char *src, unsigned char *dst, - int destwidth, int destheight) -{ - int x, y; - - /* Y-plane */ - for (y = 0; y < destheight; y++) - for (x = 0; x < destwidth; x++) { - int offset = (srcheight - x - 1) * srcwidth + y; - *dst++ = src[offset]; - } - - /* U-plane */ - src += srcwidth * srcheight; - destwidth /= 2; - destheight /= 2; - for (y = 0; y < destheight; y++) - for (x = 0; x < destwidth; x++) { - int offset = (srcheight - x - 1) * srcwidth + y; - *dst++ = src[offset]; - } - - /* V-plane */ - src += srcwidth * srcheight; - for (y = 0; y < destheight; y++) - for (x = 0; x < destwidth; x++) { - int offset = (srcheight - x - 1) * srcwidth + y; - *dst++ = src[offset]; - } -} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c b/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c deleted file mode 100644 index 532abc7ea..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/jidctflt.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * jidctflt.c - * - * Copyright (C) 1994-1998, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and you, - * its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1991-1998, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to these - * conditions: - * (1) If any part of the source code for this software is distributed, then this - * README file must be included, with this copyright and no-warranty notice - * unaltered; and any additions, deletions, or changes to the original files - * must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work of - * the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG code, - * not just to the unmodified library. If you use our work, you ought to - * acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company name - * in advertising or publicity relating to this software or products derived from - * it. This software may be referred to only as "the Independent JPEG Group's - * software". - * - * We specifically permit and encourage the use of this software as the basis of - * commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * - * This file contains a floating-point implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * This implementation should be more accurate than either of the integer - * IDCT implementations. However, it may not give the same results on all - * machines because of differences in roundoff behavior. Speed will depend - * on the hardware's floating point capacity. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with a fixed-point - * implementation, accuracy is lost due to imprecise representation of the - * scaled quantization values. However, that problem does not arise if - * we use floating point arithmetic. - */ - -#include <stdint.h> -#include "tinyjpeg-internal.h" - -#define FAST_FLOAT float -#define DCTSIZE 8 -#define DCTSIZE2 (DCTSIZE*DCTSIZE) - -#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) - -#if defined(__GNUC__) && (defined(__i686__) || defined(__x86_64__)) - -static inline unsigned char descale_and_clamp(int x, int shift) -{ - __asm__ ( - "add %3,%1\n" - "\tsar %2,%1\n" - "\tsub $-128,%1\n" - "\tcmovl %5,%1\n" /* Use the sub to compare to 0 */ - "\tcmpl %4,%1\n" - "\tcmovg %4,%1\n" - : "=r"(x) - : "0"(x), "Ic"((unsigned char)shift), "ir"(1U<<(shift-1)), "r" (0xff), "r" (0) - ); - return x; -} - -#else -static inline unsigned char descale_and_clamp(int x, int shift) -{ - x += (1UL<<(shift-1)); - if (x<0) - x = (x >> shift) | ((~(0UL)) << (32-(shift))); - else - x >>= shift; - x += 128; - if (x>255) - return 255; - else if (x<0) - return 0; - else - return x; -} -#endif - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - */ - -void -tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride) -{ - FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - FAST_FLOAT tmp10, tmp11, tmp12, tmp13; - FAST_FLOAT z5, z10, z11, z12, z13; - int16_t *inptr; - FAST_FLOAT *quantptr; - FAST_FLOAT *wsptr; - uint8_t *outptr; - int ctr; - FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ - - /* Pass 1: process columns from input, store into work array. */ - - inptr = compptr->DCT; - quantptr = compptr->Q_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = tmp0 + tmp2; /* phase 3 */ - tmp11 = tmp0 - tmp2; - - tmp13 = tmp1 + tmp3; /* phases 5-3 */ - tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; /* phase 2 */ - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z13 = tmp6 + tmp5; /* phase 6 */ - z10 = tmp6 - tmp5; - z11 = tmp4 + tmp7; - z12 = tmp4 - tmp7; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ - tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - wsptr[DCTSIZE*0] = tmp0 + tmp7; - wsptr[DCTSIZE*7] = tmp0 - tmp7; - wsptr[DCTSIZE*1] = tmp1 + tmp6; - wsptr[DCTSIZE*6] = tmp1 - tmp6; - wsptr[DCTSIZE*2] = tmp2 + tmp5; - wsptr[DCTSIZE*5] = tmp2 - tmp5; - wsptr[DCTSIZE*4] = tmp3 + tmp4; - wsptr[DCTSIZE*3] = tmp3 - tmp4; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. */ - /* Note that we must descale the results by a factor of 8 == 2**3. */ - - wsptr = workspace; - outptr = output_buf; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * And testing floats for zero is relatively expensive, so we don't bother. - */ - - /* Even part */ - - tmp10 = wsptr[0] + wsptr[4]; - tmp11 = wsptr[0] - wsptr[4]; - - tmp13 = wsptr[2] + wsptr[6]; - tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - z13 = wsptr[5] + wsptr[3]; - z10 = wsptr[5] - wsptr[3]; - z11 = wsptr[1] + wsptr[7]; - z12 = wsptr[1] - wsptr[7]; - - tmp7 = z11 + z13; - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ - tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - /* Final output stage: scale down by a factor of 8 and range-limit */ - - outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3); - outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3); - outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3); - outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3); - outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3); - outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3); - outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3); - outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3); - - - wsptr += DCTSIZE; /* advance pointer to next row */ - outptr += stride; - } -} - diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h deleted file mode 100644 index 0c4eff6ce..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert-priv.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -# (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 Lesser 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 -*/ - -#ifndef __LIBV4LCONVERT_PRIV_H -#define __LIBV4LCONVERT_PRIV_H - -#include <stdio.h> -#include "libv4lconvert.h" -#include "tinyjpeg.h" - -#ifndef V4L2_PIX_FMT_SPCA501 -#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S','5','0','1') /* YUYV per line */ -#endif - -#ifndef V4L2_PIX_FMT_SPCA505 -#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S','5','0','5') /* YYUV per line */ -#endif - -#ifndef V4L2_PIX_FMT_SPCA508 -#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S','5','0','8') /* YUVY per line */ -#endif - -#ifndef V4L2_PIX_FMT_SPCA561 -#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S','5','6','1') -#endif - -#ifndef V4L2_PIX_FMT_PAC207 -#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P','2','0','7') -#endif - -#ifndef V4L2_PIX_FMT_PJPG -#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') -#endif - -#ifndef V4L2_PIX_FMT_SGBRG8 -#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G','B','R','G') -#endif - -#ifndef V4L2_PIX_FMT_SGRBG8 -#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G','R','B','G') -#endif - -#ifndef V4L2_PIX_FMT_SRGGB8 -#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R','G','G','B') -#endif - -#ifndef V4L2_PIX_FMT_YVYU -#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') -#endif - -#define V4LCONVERT_ERROR_MSG_SIZE 256 -#define V4LCONVERT_MAX_FRAMESIZES 16 - -#define V4LCONVERT_ERR(...) \ - snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \ - "v4l-convert: error " __VA_ARGS__) - -/* Card flags */ -#define V4LCONVERT_UPSIDE_DOWN 0x01 - -/* Pixformat flags */ -#define V4LCONVERT_COMPRESSED 0x01 - -struct v4lconvert_data { - int fd; - int flags; /* bitfield */ - int supported_src_formats; /* bitfield */ - unsigned int no_formats; - char error_msg[V4LCONVERT_ERROR_MSG_SIZE]; - struct jdec_private *jdec; - struct v4l2_frmsizeenum framesizes[V4LCONVERT_MAX_FRAMESIZES]; - unsigned int no_framesizes; -}; - -struct v4lconvert_flags_info { - const char *card; - int flags; -}; - -struct v4lconvert_pixfmt { - unsigned int fmt; - int flags; -}; - -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); - -void v4lconvert_yuyv_to_rgb24(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_yuyv_to_bgr24(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_yvyu_to_rgb24(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_yvyu_to_bgr24(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_yvyu_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_spca505_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -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_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); - -void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, - unsigned char *yuv, int width, int height, unsigned int pixfmt); - -void v4lconvert_rotate90_rgbbgr24(const unsigned char *src, unsigned char *dst, - int destwidth, int destheight); - -void v4lconvert_rotate90_yuv420(const unsigned char *src, unsigned char *dst, - int destwidth, int destheight); - -void v4lconvert_rotate180_rgbbgr24(const unsigned char *src, unsigned char *dst, - int width, int height); - -void v4lconvert_rotate180_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height); - -#endif diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c deleted file mode 100644 index 93bc67c7e..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c +++ /dev/null @@ -1,737 +0,0 @@ -/* -# (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 Lesser 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 <errno.h> -#include <string.h> -#include <stdlib.h> -#include <syscall.h> -#include <unistd.h> -#include "libv4lconvert.h" -#include "libv4lconvert-priv.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0])) - -/* 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, 0 }, \ - { V4L2_PIX_FMT_BGR24, 0 }, \ - { V4L2_PIX_FMT_YUV420, 0 } - -static void v4lconvert_get_framesizes(struct v4lconvert_data *data, - unsigned int pixelformat); - -/* Note uncompressed formats must go first so that they are prefered by - v4lconvert_try_format for low resolutions */ -static const struct v4lconvert_pixfmt supported_src_pixfmts[] = { - SUPPORTED_DST_PIXFMTS, - { V4L2_PIX_FMT_YUYV, 0 }, - { V4L2_PIX_FMT_YVYU, 0 }, - { V4L2_PIX_FMT_SBGGR8, 0 }, - { V4L2_PIX_FMT_SGBRG8, 0 }, - { V4L2_PIX_FMT_SGRBG8, 0 }, - { V4L2_PIX_FMT_SRGGB8, 0 }, - { V4L2_PIX_FMT_SPCA501, 0 }, - { V4L2_PIX_FMT_SPCA505, 0 }, - { V4L2_PIX_FMT_SPCA508, 0 }, - { V4L2_PIX_FMT_MJPEG, V4LCONVERT_COMPRESSED }, - { V4L2_PIX_FMT_JPEG, V4LCONVERT_COMPRESSED }, - { V4L2_PIX_FMT_SPCA561, V4LCONVERT_COMPRESSED }, - { V4L2_PIX_FMT_SN9C10X, V4LCONVERT_COMPRESSED }, - { V4L2_PIX_FMT_PAC207, V4LCONVERT_COMPRESSED }, - { V4L2_PIX_FMT_PJPG, V4LCONVERT_COMPRESSED }, -}; - -static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = { - SUPPORTED_DST_PIXFMTS -}; - -/* List of cams which need special flags */ -static const struct v4lconvert_flags_info v4lconvert_flags[] = { - { "SPC 200NC ", V4LCONVERT_UPSIDE_DOWN }, - { "SPC 300NC ", V4LCONVERT_UPSIDE_DOWN }, - { "USB Camera (0471:0325)", V4LCONVERT_UPSIDE_DOWN }, /* SPC200NC */ - { "USB Camera (0471:0326)", V4LCONVERT_UPSIDE_DOWN }, /* SPC300NC */ - { "USB Camera (093a:2476)", V4LCONVERT_UPSIDE_DOWN }, /* Genius E-M 112 */ -}; - -struct v4lconvert_data *v4lconvert_create(int fd) -{ - int i, j; - struct v4lconvert_data *data = calloc(1, sizeof(struct v4lconvert_data)); - struct v4l2_capability cap; - - if (!data) - return NULL; - - data->fd = fd; - data->jdec = NULL; - - /* Check supported formats */ - for (i = 0; ; i++) { - struct v4l2_fmtdesc fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; - - fmt.index = i; - - if (syscall(SYS_ioctl, fd, VIDIOC_ENUM_FMT, &fmt)) - break; - - for (j = 0; j < ARRAY_SIZE(supported_src_pixfmts); j++) - if (fmt.pixelformat == supported_src_pixfmts[j].fmt) { - data->supported_src_formats |= 1 << j; - break; - } - - v4lconvert_get_framesizes(data, fmt.pixelformat); - } - - data->no_formats = i; - - /* Check if this cam has any special flags */ - if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap) == 0) { - for (i = 0; i < ARRAY_SIZE(v4lconvert_flags); i++) - if (!strcmp((const char *)v4lconvert_flags[i].card, (char *)cap.card)) { - data->flags = v4lconvert_flags[i].flags; - break; - } - } - - return data; -} - -void v4lconvert_destroy(struct v4lconvert_data *data) -{ - if (data->jdec) { - unsigned char *comps[3] = { NULL, NULL, NULL }; - tinyjpeg_set_components(data->jdec, comps, 3); - tinyjpeg_free(data->jdec); - } - free(data); -} - -static int v4lconvert_supported_dst_format(unsigned int pixelformat) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) - if (supported_dst_pixfmts[i].fmt == pixelformat) - break; - - return i != ARRAY_SIZE(supported_dst_pixfmts); -} - -/* See libv4lconvert.h for description of in / out parameters */ -int v4lconvert_enum_fmt(struct v4lconvert_data *data, struct v4l2_fmtdesc *fmt) -{ - int i, no_faked_fmts = 0; - unsigned int faked_fmts[ARRAY_SIZE(supported_dst_pixfmts)]; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fmt->index < data->no_formats || - !data->supported_src_formats) - return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FMT, fmt); - - for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) - if (!(data->supported_src_formats & (1 << i))) { - faked_fmts[no_faked_fmts] = supported_dst_pixfmts[i].fmt; - no_faked_fmts++; - } - - i = fmt->index - data->no_formats; - if (i >= no_faked_fmts) { - errno = EINVAL; - return -1; - } - - fmt->flags = 0; - fmt->pixelformat = faked_fmts[i]; - fmt->description[0] = faked_fmts[i] & 0xff; - fmt->description[1] = (faked_fmts[i] >> 8) & 0xff; - fmt->description[2] = (faked_fmts[i] >> 16) & 0xff; - fmt->description[3] = faked_fmts[i] >> 24; - fmt->description[4] = '\0'; - memset(fmt->reserved, 0, 4); - - return 0; -} - -/* See libv4lconvert.h for description of in / out parameters */ -int v4lconvert_try_format(struct v4lconvert_data *data, - struct v4l2_format *dest_fmt, struct v4l2_format *src_fmt) -{ - int i; - unsigned int closest_fmt_size_diff = -1; - unsigned int desired_pixfmt = dest_fmt->fmt.pix.pixelformat; - struct v4l2_format try_fmt, closest_fmt = { .type = 0 }; - - /* Can we do conversion to the requested format & type? */ - if (!v4lconvert_supported_dst_format(desired_pixfmt) || - dest_fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt); - if (src_fmt) - *src_fmt = *dest_fmt; - return ret; - } - - for (i = 0; i < ARRAY_SIZE(supported_src_pixfmts); i++) { - /* is this format supported? */ - if (!(data->supported_src_formats & (1 << i))) - continue; - - try_fmt = *dest_fmt; - try_fmt.fmt.pix.pixelformat = supported_src_pixfmts[i].fmt; - - if (!syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, &try_fmt)) - { - if (try_fmt.fmt.pix.pixelformat == supported_src_pixfmts[i].fmt) { - int size_x_diff = abs((int)try_fmt.fmt.pix.width - - (int)dest_fmt->fmt.pix.width); - int size_y_diff = abs((int)try_fmt.fmt.pix.height - - (int)dest_fmt->fmt.pix.height); - unsigned int size_diff = size_x_diff * size_x_diff + - size_y_diff * size_y_diff; - if (size_diff < closest_fmt_size_diff || - (size_diff == closest_fmt_size_diff && - (supported_src_pixfmts[i].fmt == desired_pixfmt || - ((try_fmt.fmt.pix.width > 176 || try_fmt.fmt.pix.height > 144) && - (supported_src_pixfmts[i].flags & V4LCONVERT_COMPRESSED))))) { - closest_fmt_size_diff = size_diff; - closest_fmt = try_fmt; - } - } - } - } - - if (closest_fmt.type == 0) { - int ret = syscall(SYS_ioctl, data->fd, VIDIOC_TRY_FMT, dest_fmt); - if (src_fmt) - *src_fmt = *dest_fmt; - return ret; - } - - *dest_fmt = closest_fmt; - - /* Are we converting? */ - 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 * - dest_fmt->fmt.pix.height * 3; - break; - case V4L2_PIX_FMT_YUV420: - dest_fmt->fmt.pix.bytesperline = dest_fmt->fmt.pix.width; - dest_fmt->fmt.pix.sizeimage = (dest_fmt->fmt.pix.width * - dest_fmt->fmt.pix.height * 3) / 2; - break; - } - } - - if (src_fmt) - *src_fmt = closest_fmt; - - return 0; -} - -/* Is conversion necessary ? */ -int v4lconvert_needs_conversion(struct v4lconvert_data *data, - const struct v4l2_format *src_fmt, /* in */ - const struct v4l2_format *dest_fmt) /* in */ -{ - if(memcmp(src_fmt, dest_fmt, sizeof(*src_fmt))) - return 1; /* Formats differ */ - - if (!(data->flags & V4LCONVERT_UPSIDE_DOWN)) - return 0; /* Formats identical and we don't need flip */ - - /* Formats are identical, but we need flip, do we support the dest_fmt? */ - if (!v4lconvert_supported_dst_format(dest_fmt->fmt.pix.pixelformat)) - return 0; /* Needs flip but we cannot do it :( */ - else - return 1; /* Needs flip and thus conversion */ -} - -int v4lconvert_convert(struct v4lconvert_data *data, - const struct v4l2_format *src_fmt, /* in */ - const struct v4l2_format *dest_fmt, /* in */ - unsigned char *src, int src_size, unsigned char *_dest, int dest_size) -{ - unsigned int header_width, header_height; - int result, needed, rotate = 0, jpeg_flags = TINYJPEG_FLAGS_MJPEG_TABLE; - unsigned char *components[3]; - unsigned char *dest = _dest; - - /* Special case when no conversion is needed */ - if (!v4lconvert_needs_conversion(data, src_fmt, dest_fmt)) { - int to_copy = MIN(dest_size, src_size); - memcpy(dest, src, to_copy); - return to_copy; - } - - /* 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; - case V4L2_PIX_FMT_YUV420: - needed = (dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3) / 2; - break; - default: - V4LCONVERT_ERR("Unknown dest format in conversion\n"); - errno = EINVAL; - return -1; - } - - if (dest_size < needed) { - V4LCONVERT_ERR("destination buffer too small\n"); - errno = EFAULT; - return -1; - } - - if (data->flags & V4LCONVERT_UPSIDE_DOWN) { - rotate = 180; - dest = alloca(needed); - } - - switch (src_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_PJPG: - jpeg_flags |= TINYJPEG_FLAGS_PIXART_JPEG; - /* Fall through */ - case V4L2_PIX_FMT_MJPEG: - case V4L2_PIX_FMT_JPEG: - if (!data->jdec) { - data->jdec = tinyjpeg_init(); - if (!data->jdec) { - V4LCONVERT_ERR("out of memory!\n"); - errno = ENOMEM; - return -1; - } - } - tinyjpeg_set_flags(data->jdec, jpeg_flags); - if (tinyjpeg_parse_header(data->jdec, src, src_size)) { - V4LCONVERT_ERR("parsing JPEG header: %s\n", - tinyjpeg_get_errorstring(data->jdec)); - errno = EIO; - return -1; - } - tinyjpeg_get_size(data->jdec, &header_width, &header_height); - - if (header_width != dest_fmt->fmt.pix.width || - header_height != dest_fmt->fmt.pix.height) { - /* Check for (pixart) rotated JPEG */ - if (header_width == dest_fmt->fmt.pix.height || - header_height == dest_fmt->fmt.pix.width) { - if (!rotate) - dest = alloca(needed); - rotate += 90; - } else { - V4LCONVERT_ERR("unexpected width / height in JPEG header" - "expected: %ux%u, header: %ux%u\n", - dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, - header_width, header_height); - errno = EIO; - return -1; - } - } - - components[0] = dest; - components[1] = components[0] + dest_fmt->fmt.pix.width * - dest_fmt->fmt.pix.height; - components[2] = components[1] + (dest_fmt->fmt.pix.width * - dest_fmt->fmt.pix.height) / 4; - - 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); - break; - default: - tinyjpeg_set_components(data->jdec, components, 3); - result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_YUV420P); - break; - } - - if (result) { - /* Pixart webcam's seem to regulary generate corrupt frames, which - are best thrown away to avoid flashes in the video stream. Tell - the upper layer this is an intermediate fault and it should try - again with a new buffer by setting errno to EAGAIN */ - if (src_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_PJPG) { - V4LCONVERT_ERR("Error decompressing JPEG: %s", - tinyjpeg_get_errorstring(data->jdec)); - errno = EAGAIN; - return -1; - } else { - /* If the JPEG header checked out ok and we get an error during actual - decompression, log the error, but don't return an errorcode to the - application, so that the user gets what we managed to decompress */ - fprintf(stderr, "libv4lconvert: Error decompressing JPEG: %s", - tinyjpeg_get_errorstring(data->jdec)); - } - } - break; - - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - 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); - 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 */ - case V4L2_PIX_FMT_SPCA501: - case V4L2_PIX_FMT_SPCA505: - case V4L2_PIX_FMT_SPCA508: - { - 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_YUV420) ? tmpbuf : dest; - - switch (src_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_SPCA501: - v4lconvert_spca501_to_yuv420(src, my_dst, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_SPCA505: - v4lconvert_spca505_to_yuv420(src, my_dst, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_SPCA508: - v4lconvert_spca508_to_yuv420(src, my_dst, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - - 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; - } - - /* compressed bayer formats */ - case V4L2_PIX_FMT_SPCA561: - case V4L2_PIX_FMT_SN9C10X: - case V4L2_PIX_FMT_PAC207: - { - unsigned char tmpbuf[dest_fmt->fmt.pix.width*dest_fmt->fmt.pix.height]; - unsigned int bayer_fmt = 0; - - 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_SBGGR8; - break; - case V4L2_PIX_FMT_PAC207: - v4lconvert_decode_pac207(src, tmpbuf, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - bayer_fmt = V4L2_PIX_FMT_SBGGR8; - break; - } - - 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); - break; - default: - v4lconvert_bayer_to_yuv420(tmpbuf, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height, bayer_fmt); - break; - } - break; - } - - case V4L2_PIX_FMT_RGB24: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_BGR24: - v4lconvert_swap_rgb(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_YUV420: - printf("FIXME add rgb24 -> yuv420 conversion\n"); - break; - } - break; - case V4L2_PIX_FMT_BGR24: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - v4lconvert_swap_rgb(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_YUV420: - printf("FIXME add bgr24 -> yuv420 conversion\n"); - break; - } - break; - - case V4L2_PIX_FMT_YUV420: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - v4lconvert_yuv420_to_rgb24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_BGR24: - v4lconvert_yuv420_to_bgr24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - break; - - case V4L2_PIX_FMT_YUYV: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - v4lconvert_yuyv_to_rgb24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_BGR24: - v4lconvert_yuyv_to_bgr24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - default: - v4lconvert_yuyv_to_yuv420(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - break; - - case V4L2_PIX_FMT_YVYU: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - v4lconvert_yvyu_to_rgb24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_BGR24: - v4lconvert_yvyu_to_bgr24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - default: - v4lconvert_yvyu_to_yuv420(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - break; - - default: - V4LCONVERT_ERR("Unknown src format in conversion\n"); - errno = EINVAL; - return -1; - } - - /* Note when rotating dest is our temporary buffer to which our conversion - was done and _dest is the real dest! If the formats are identical no - conversion has been done! */ - if (rotate && dest_fmt->fmt.pix.pixelformat == src_fmt->fmt.pix.pixelformat) - dest = src; - - switch (rotate) { - case 0: - break; - case 90: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - v4lconvert_rotate90_rgbbgr24(dest, _dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_YUV420: - v4lconvert_rotate90_yuv420(dest, _dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - break; - case 180: - switch (dest_fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - v4lconvert_rotate180_rgbbgr24(dest, _dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - case V4L2_PIX_FMT_YUV420: - v4lconvert_rotate180_yuv420(dest, _dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); - break; - } - break; - default: - printf("FIXME add %d degrees rotation\n", rotate); - } - - return needed; -} - -const char *v4lconvert_get_error_message(struct v4lconvert_data *data) -{ - return data->error_msg; -} - -static void v4lconvert_get_framesizes(struct v4lconvert_data *data, - unsigned int pixelformat) -{ - int i, j, match; - struct v4l2_frmsizeenum frmsize = { .pixel_format = pixelformat }; - - for (i = 0; ; i++) { - frmsize.index = i; - if (syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize)) - break; - - /* We got a framesize, check we don't have the same one already */ - match = 0; - for (j = 0; j < data->no_framesizes && !match; j++) { - if (frmsize.type != data->framesizes[j].type) - continue; - - switch(frmsize.type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - if(!memcmp(&frmsize.discrete, &data->framesizes[j].discrete, - sizeof(frmsize.discrete))) - match = 1; - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - case V4L2_FRMSIZE_TYPE_STEPWISE: - if(!memcmp(&frmsize.stepwise, &data->framesizes[j].stepwise, - sizeof(frmsize.stepwise))) - match = 1; - break; - } - } - /* Add this framesize if it is not already in our list */ - if (!match) { - if (data->no_framesizes == V4LCONVERT_MAX_FRAMESIZES) { - fprintf(stderr, - "libv4lconvert: warning more framesizes then I can handle!\n"); - return; - } - data->framesizes[data->no_framesizes].type = frmsize.type; - switch(frmsize.type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - data->framesizes[data->no_framesizes].discrete = frmsize.discrete; - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - case V4L2_FRMSIZE_TYPE_STEPWISE: - data->framesizes[data->no_framesizes].stepwise = frmsize.stepwise; - break; - } - data->no_framesizes++; - } - } -} - -int v4lconvert_enum_framesizes(struct v4lconvert_data *data, - struct v4l2_frmsizeenum *frmsize) -{ - if (!v4lconvert_supported_dst_format(frmsize->pixel_format)) - return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMESIZES, frmsize); - - if (frmsize->index >= data->no_framesizes) { - errno = EINVAL; - return -1; - } - - frmsize->type = data->framesizes[frmsize->index].type; - switch(frmsize->type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - frmsize->discrete = data->framesizes[frmsize->index].discrete; - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - case V4L2_FRMSIZE_TYPE_STEPWISE: - frmsize->stepwise = data->framesizes[frmsize->index].stepwise; - break; - } - - return 0; -} - -int v4lconvert_enum_frameintervals(struct v4lconvert_data *data, - struct v4l2_frmivalenum *frmival) -{ - int res; - struct v4l2_format src_fmt, dest_fmt; - - if (!v4lconvert_supported_dst_format(frmival->pixel_format)) - return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival); - - /* Check which format we will be using to convert to frmival->pixel_format */ - memset(&dest_fmt, 0, sizeof(dest_fmt)); - dest_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dest_fmt.fmt.pix.pixelformat = frmival->pixel_format; - dest_fmt.fmt.pix.width = frmival->width; - dest_fmt.fmt.pix.height = frmival->height; - if ((res = v4lconvert_try_format(data, &dest_fmt, &src_fmt))) - return res; - - /* Check the requested format is supported exactly as requested */ - if (dest_fmt.fmt.pix.pixelformat != frmival->pixel_format || - dest_fmt.fmt.pix.width != frmival->width || - dest_fmt.fmt.pix.height != frmival->height) { - errno = EINVAL; - return -1; - } - - /* Enumerate the frameintervals of the source format we will be using */ - frmival->pixel_format = src_fmt.fmt.pix.pixelformat; - frmival->width = src_fmt.fmt.pix.width; - frmival->height = src_fmt.fmt.pix.height; - res = syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival); - - /* Restore the requested format in the frmival struct */ - frmival->pixel_format = dest_fmt.fmt.pix.pixelformat; - frmival->width = dest_fmt.fmt.pix.width; - frmival->height = dest_fmt.fmt.pix.height; - - return res; -} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c b/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c deleted file mode 100644 index 97ef4ebc0..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/pac207.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - -# PAC207 decoder -# Bertrik.Sikken. Thomas Kaiser (C) 2005 -# Copyright (C) 2003 2004 2005 Michel Xhaard - -# 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 Lesser 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 - -# Note this code was originally licensed under the GNU GPL instead of the -# GNU LGPL, its license has been changed with permission, see the permission -# mails at the end of this file. - -*/ - -#include <string.h> -#include "libv4lconvert-priv.h" - -#define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color))) - -/* FIXME not threadsafe */ -static int decoder_initialized = 0; - -static struct { - unsigned char is_abs; - unsigned char len; - signed char val; -} table[256]; - -static void init_pixart_decoder(void) -{ - int i; - int is_abs, val, len; - for (i = 0; i < 256; i++) { - is_abs = 0; - val = 0; - len = 0; - if ((i & 0xC0) == 0) { - /* code 00 */ - val = 0; - len = 2; - } else if ((i & 0xC0) == 0x40) { - /* code 01 */ - val = -5; - len = 2; - } else if ((i & 0xC0) == 0x80) { - /* code 10 */ - val = +5; - len = 2; - } else if ((i & 0xF0) == 0xC0) { - /* code 1100 */ - val = -10; - len = 4; - } else if ((i & 0xF0) == 0xD0) { - /* code 1101 */ - val = +10; - len = 4; - } else if ((i & 0xF8) == 0xE0) { - /* code 11100 */ - val = -15; - len = 5; - } else if ((i & 0xF8) == 0xE8) { - /* code 11101 */ - val = +15; - len = 5; - } else if ((i & 0xFC) == 0xF0) { - /* code 111100 */ - val = -20; - len = 6; - } else if ((i & 0xFC) == 0xF4) { - /* code 111101 */ - val = +20; - len = 6; - } else if ((i & 0xF8) == 0xF8) { - /* code 11111xxxxxx */ - is_abs = 1; - val = 0; - len = 5; - } - table[i].is_abs = is_abs; - table[i].val = val; - table[i].len = len; - } - decoder_initialized = 1; -} - -static inline unsigned char getByte(const unsigned char *inp, - unsigned int bitpos) -{ - const unsigned char *addr; - addr = inp + (bitpos >> 3); - return (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7))); -} - -static inline unsigned short getShort(const unsigned char *pt) -{ - return ((pt[0] << 8) | pt[1]); -} - -static int -pac_decompress_row(const unsigned char *inp, unsigned char *outp, int width) -{ - int col; - int val; - int bitpos; - unsigned char code; - - if (!decoder_initialized) - init_pixart_decoder(); - - /* first two pixels are stored as raw 8-bit */ - *outp++ = inp[2]; - *outp++ = inp[3]; - bitpos = 32; - - /* main decoding loop */ - for (col = 2; col < width; col++) { - /* get bitcode */ - - code = getByte(inp, bitpos); - bitpos += table[code].len; - - /* calculate pixel value */ - if (table[code].is_abs) { - /* absolute value: get 6 more bits */ - code = getByte(inp, bitpos); - bitpos += 6; - *outp++ = code & 0xFC; - } else { - /* relative to left pixel */ - val = outp[-2] + table[code].val; - *outp++ = CLIP(val); - } - } - - /* return line length, rounded up to next 16-bit word */ - return 2 * ((bitpos + 15) / 16); -} - -void v4lconvert_decode_pac207(const unsigned char *inp, unsigned char *outp, - int width, int height) -{ -/* we should received a whole frame with header and EOL marker -in myframe->data and return a GBRG pattern in frame->tmpbuffer -remove the header then copy line by line EOL is set with 0x0f 0xf0 marker -or 0x1e 0xe1 for compressed line*/ - unsigned short word; - int row; - - /* iterate over all rows */ - for (row = 0; row < height; row++) { - word = getShort(inp); - switch (word) { - case 0x0FF0: - memcpy(outp, inp + 2, width); - inp += (2 + width); - break; - case 0x1EE1: - inp += pac_decompress_row(inp, outp, width); - break; - - case 0x2DD2: /* prefix for "stronger" compressed lines, currently the - kernel driver programs the cam so that we should not - get any of these */ - - default: /* corrupt frame */ - /* FIXME add error reporting */ - return; - } - outp += width; - } - - return; -} - - - - -/* -Return-Path: <thomas@kaiser-linux.li> -Received: from koko.hhs.nl ([145.52.2.16] verified) - by hhs.nl (CommuniGate Pro SMTP 4.3.6) - with ESMTP id 88906346 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 -Received: from exim (helo=koko) - by koko.hhs.nl with local-smtp (Exim 4.62) - (envelope-from <thomas@kaiser-linux.li>) - id 1KBeEW-0001qu-H6 - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 -Received: from [192.87.102.74] (port=41049 helo=filter6-ams.mf.surf.net) - by koko.hhs.nl with esmtp (Exim 4.62) - (envelope-from <thomas@kaiser-linux.li>) - id 1KBeEV-0001qn-2T - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200 -Received: from smtp0.lie-comtel.li (smtp0.lie-comtel.li [217.173.238.80]) - by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5PNGwSF007539 - for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 01:16:58 +0200 -Received: from localhost (localhost.lie-comtel.li [127.0.0.1]) - by smtp0.lie-comtel.li (Postfix) with ESMTP id DDB609FEC1D; - Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1) -X-Virus-Scanned: Virus scanned by amavis at smtp.lie-comtel.li -Received: from [192.168.0.16] (217-173-228-198.cmts.powersurf.li [217.173.228.198]) - by smtp0.lie-comtel.li (Postfix) with ESMTP id 80B589FEC19; - Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1) -Message-ID: <4862D211.3000802@kaiser-linux.li> -Date: Thu, 26 Jun 2008 01:17:37 +0200 -From: Thomas Kaiser <thomas@kaiser-linux.li> -User-Agent: Thunderbird 2.0.0.14 (X11/20080505) -MIME-Version: 1.0 -To: Hans de Goede <j.w.r.degoede@hhs.nl> -CC: Thomas Kaiser <spca5xx@kaiser-linux.li>, bertrik@zonnet.nl, - mxhaard@magic.fr -Subject: Re: pac207 bayer decompression algorithm license question -References: <4862C0A4.3060003@hhs.nl> -In-Reply-To: <4862C0A4.3060003@hhs.nl> -Content-Type: text/plain; charset=ISO-8859-1; format=flowed -Content-Transfer-Encoding: 7bit -X-Canit-CHI2: 0.00 -X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) -X-Spam-Score: 0.00 () [Tag at 8.00] -X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) -X-Canit-Stats-ID: 88604132 - 38b3b44cd798 -X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74 -X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 25062008 #787666, status: clean - -Hello Hans - -Hans de Goede wrote: -> Hi, -> -> As you may have seen on the mailinglist, I've created a userspace -> library to handle cam specific format handling in userspace where it -> belongs, see: -> http://hansdegoede.livejournal.com/ -Yes, I saw it on the mail list and I think it is a good idea :-) -> -> I would like to also add support for decompressing the pac207's -> compressed bayer to this lib (and remove it from the kernel driver) -> for this I need permission to relicense the decompress code under the -> LGPL (version 2 or later). -Actually, this was done by Bertrik Sikken (bertrik@zonnet.nl), Michel -Xhaard (mxhaard@magic.fr) and me. But Bertrik was the one who found out -how to decode the lines :-) -> -> Can you give me permission for this, or if the code is not yours put -> me in contact with someone who can? -For me it's no problem to release it with LGPL. Maybe you have to ask -the other one's also. -> -> Thanks & Regards, -> -> Hans - -Rgeards, Thomas -*/ - -/* -Return-Path: <mxhaard@magic.fr> -Received: from koko.hhs.nl ([145.52.2.16] verified) - by hhs.nl (CommuniGate Pro SMTP 4.3.6) - with ESMTP id 88910192 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 -Received: from exim (helo=koko) - by koko.hhs.nl with local-smtp (Exim 4.62) - (envelope-from <mxhaard@magic.fr>) - id 1KBlhh-0006Fi-Oe - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 -Received: from [194.171.167.220] (port=54180 helo=filter4-til.mf.surf.net) - by koko.hhs.nl with esmtp (Exim 4.62) - (envelope-from <mxhaard@magic.fr>) - id 1KBlhh-0006Fd-FY - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200 -Received: from smtp4-g19.free.fr (smtp4-g19.free.fr [212.27.42.30]) - by filter4-til.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5Q7FY1I006360 - for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 09:15:34 +0200 -Received: from smtp4-g19.free.fr (localhost.localdomain [127.0.0.1]) - by smtp4-g19.free.fr (Postfix) with ESMTP id 51C683EA0E7; - Thu, 26 Jun 2008 09:15:34 +0200 (CEST) -Received: from [192.168.1.11] (lns-bzn-54-82-251-105-53.adsl.proxad.net [82.251.105.53]) - by smtp4-g19.free.fr (Postfix) with ESMTP id 1149E3EA0C7; - Thu, 26 Jun 2008 09:15:34 +0200 (CEST) -From: Michel Xhaard <mxhaard@magic.fr> -To: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: Re: pac207 bayer decompression algorithm license question -Date: Thu, 26 Jun 2008 11:15:32 +0200 -User-Agent: KMail/1.9.5 -Cc: bertrik@zonnet.nl, spca5xx@kaiser-linux.li, - "Jean-Francois Moine" <moinejf@free.fr> -References: <48633F02.3040108@hhs.nl> -In-Reply-To: <48633F02.3040108@hhs.nl> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: inline -Message-Id: <200806261115.32909.mxhaard@magic.fr> -X-Canit-CHI2: 0.00 -X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) -X-Spam-Score: 0.00 () [Tag at 8.00] -X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) -X-Canit-Stats-ID: 88656338 - 0dde233cb8b5 -X-Scanned-By: CanIt (www . roaringpenguin . com) on 194.171.167.220 -X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787720, status: clean - -Le jeudi 26 juin 2008 09:02, Hans de Goede a =E9crit=A0: -> Hi, -> -> As you may have seen on the mailinglist, I've created a userspace library -> to handle cam specific format handling in userspace, see: -> http://hansdegoede.livejournal.com/ -> -> I would like to also add support for decompressing the pac207's compressed -> bayer to this lib (and remove it from the kernel driver) and I've heard -> from Thomas Kaiser that you are a co-author of the decompression code. In -> order to add support for decompressing pac207 compressed bayer to libv4l I -> need permission to relicense the decompression code under the LGPL (versi= -on -> 2 or later). -> -> Can you give me permission for this? -> -> Thanks & Regards, -> -> Hans -> -> -> -> p.s. -> -> Thomas has already given permission. - -=46or me it is ok and a good idea for all free world familly ;-). -Bests regards -=2D-=20 -Michel Xhaard -http://mxhaard.free.fr -*/ - -/* -Return-Path: <bertrik@sikken.nl> -Received: from koko.hhs.nl ([145.52.2.16] verified) - by hhs.nl (CommuniGate Pro SMTP 4.3.6) - with ESMTP id 88940205 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 -Received: from exim (helo=koko) - by koko.hhs.nl with local-smtp (Exim 4.62) - (envelope-from <bertrik@sikken.nl>) - id 1KBxgo-0003Dj-ET - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 -Received: from [192.87.102.69] (port=51992 helo=filter1-ams.mf.surf.net) - by koko.hhs.nl with esmtp (Exim 4.62) - (envelope-from <bertrik@sikken.nl>) - id 1KBxgo-0003Dd-5i - for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200 -Received: from pelian.kabelfoon.nl (pelian3.kabelfoon.nl [62.45.45.106]) - by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5QK3ThE007720 - for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200 -Received: from [192.168.1.1] (062-015-045-062.dynamic.caiway.nl [62.45.15.62]) - by pelian.kabelfoon.nl (Postfix) with ESMTP id 9239B428100 - for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200 (CEST) -Message-ID: <4863F611.80104@sikken.nl> -Date: Thu, 26 Jun 2008 22:03:29 +0200 -From: Bertrik Sikken <bertrik@sikken.nl> -User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) -MIME-Version: 1.0 -To: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: Re: pac207 bayer decompression algorithm license question -References: <48633F02.3040108@hhs.nl> -In-Reply-To: <48633F02.3040108@hhs.nl> -X-Enigmail-Version: 0.95.6 -Content-Type: text/plain; charset=ISO-8859-1; format=flowed -Content-Transfer-Encoding: 7bit -X-Canit-CHI2: 0.00 -X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) -X-Spam-Score: 0.00 () [Tag at 8.00] -X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) -X-Canit-Stats-ID: 88938005 - ef1f0836ffc7 -X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.69 -X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787877, status: clean - -Hallo Hans, - -Hans de Goede wrote: -> Hi, -> -> As you may have seen on the mailinglist, I've created a userspace -> library to -> handle cam specific format handling in userspace, see: -> http://hansdegoede.livejournal.com/ - -O leuk, zoiets is naar mijn idee precies wat er nodig is voor webcam -support onder linux. Ik ben een jaar of 3 geleden heel actief geweest -met een aantal webcams, maar doe er tegenwoordig helemaal niets meer -aan. - -> I would like to also add support for decompressing the pac207's compressed -> bayer to this lib (and remove it from the kernel driver) and I've heard -> from Thomas Kaiser that you are a co-author of the decompression code. -> In order to add support for decompressing pac207 compressed bayer to -> libv4l I need -> permission to relicense the decompression code under the LGPL (version 2 -> or later). -> -> Can you give me permission for this? - -Ja, vind ik goed. - -Vriendelijke groet, -Bertrik -*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c b/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c deleted file mode 100644 index 0f26b227a..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/rgbyuv.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - -# RGB <-> YUV conversion routines - -# (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 Lesser 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" - -#define RGB2YUV(r,g,b,y,u,v) \ - (y) = (( 8453*(r) + 16594*(g) + 3223*(b) + 524288) >> 15); \ - (u) = (( -4878*(r) - 9578*(g) + 14456*(b) + 4210688) >> 15); \ - (v) = (( 14456*(r) - 12105*(g) - 2351*(b) + 4210688) >> 15) - -#define YUV2R(y, u, v) ({ \ - int r = (y) + ((((v)-128)*1436) >> 10); r > 255 ? 255 : r < 0 ? 0 : r; }) -#define YUV2G(y, u, v) ({ \ - int g = (y) - ((((u)-128)*352 + ((v)-128)*731) >> 10); g > 255 ? 255 : g < 0 ? 0 : g; }) -#define YUV2B(y, u, v) ({ \ - int b = (y) + ((((u)-128)*1814) >> 10); b > 255 ? 255 : b < 0 ? 0 : b; }) - -#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) -{ - int i,j; - - const unsigned char *ysrc = src; - const unsigned char *usrc = src + width * height; - const unsigned char *vsrc = usrc + (width * height) / 4; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j += 2) { -#if 1 /* fast slightly less accurate multiplication free code */ - int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6; - int rg = (((*usrc - 128) << 1) + (*usrc - 128) + - ((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3; - int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1; - - *dest++ = CLIP(*ysrc + u1); - *dest++ = CLIP(*ysrc - rg); - *dest++ = CLIP(*ysrc + v1); - ysrc++; - - *dest++ = CLIP(*ysrc + u1); - *dest++ = CLIP(*ysrc - rg); - *dest++ = CLIP(*ysrc + v1); -#else - *dest++ = YUV2B(*ysrc, *usrc, *vsrc); - *dest++ = YUV2G(*ysrc, *usrc, *vsrc); - *dest++ = YUV2R(*ysrc, *usrc, *vsrc); - ysrc++; - - *dest++ = YUV2B(*ysrc, *usrc, *vsrc); - *dest++ = YUV2G(*ysrc, *usrc, *vsrc); - *dest++ = YUV2R(*ysrc, *usrc, *vsrc); -#endif - ysrc++; - usrc++; - vsrc++; - } - /* Rewind u and v for next line */ - if (i&1) { - usrc -= width / 2; - vsrc -= width / 2; - } - } -} - -void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int i,j; - - const unsigned char *ysrc = src; - const unsigned char *usrc = src + width * height; - const unsigned char *vsrc = usrc + (width * height) / 4; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j += 2) { -#if 1 /* fast slightly less accurate multiplication free code */ - int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6; - int rg = (((*usrc - 128) << 1) + (*usrc - 128) + - ((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3; - int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1; - - *dest++ = CLIP(*ysrc + v1); - *dest++ = CLIP(*ysrc - rg); - *dest++ = CLIP(*ysrc + u1); - ysrc++; - - *dest++ = CLIP(*ysrc + v1); - *dest++ = CLIP(*ysrc - rg); - *dest++ = CLIP(*ysrc + u1); -#else - *dest++ = YUV2R(*ysrc, *usrc, *vsrc); - *dest++ = YUV2G(*ysrc, *usrc, *vsrc); - *dest++ = YUV2B(*ysrc, *usrc, *vsrc); - ysrc++; - - *dest++ = YUV2R(*ysrc, *usrc, *vsrc); - *dest++ = YUV2G(*ysrc, *usrc, *vsrc); - *dest++ = YUV2B(*ysrc, *usrc, *vsrc); -#endif - ysrc++; - usrc++; - vsrc++; - } - /* Rewind u and v for next line */ - if (i&1) { - usrc -= width / 2; - vsrc -= width / 2; - } - } -} - -void v4lconvert_yuyv_to_bgr24(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int j; - - while (--height >= 0) { - for (j = 0; j < width; j += 2) { - int u = src[1]; - int v = src[3]; - int u1 = (((u - 128) << 7) + (u - 128)) >> 6; - int rg = (((u - 128) << 1) + (u - 128) + - ((v - 128) << 2) + ((v - 128) << 1)) >> 3; - int v1 = (((v - 128) << 1) + (v - 128)) >> 1; - - *dest++ = CLIP(src[0] + u1); - *dest++ = CLIP(src[0] - rg); - *dest++ = CLIP(src[0] + v1); - - *dest++ = CLIP(src[2] + u1); - *dest++ = CLIP(src[2] - rg); - *dest++ = CLIP(src[2] + v1); - src += 4; - } - } -} - -void v4lconvert_yuyv_to_rgb24(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int j; - - while (--height >= 0) { - for (j = 0; j < width; j += 2) { - int u = src[1]; - int v = src[3]; - int u1 = (((u - 128) << 7) + (u - 128)) >> 6; - int rg = (((u - 128) << 1) + (u - 128) + - ((v - 128) << 2) + ((v - 128) << 1)) >> 3; - int v1 = (((v - 128) << 1) + (v - 128)) >> 1; - - *dest++ = CLIP(src[0] + v1); - *dest++ = CLIP(src[0] - rg); - *dest++ = CLIP(src[0] + u1); - - *dest++ = CLIP(src[2] + v1); - *dest++ = CLIP(src[2] - rg); - *dest++ = CLIP(src[2] + u1); - src += 4; - } - } -} - -void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int i, j; - const unsigned char *src1; - unsigned char *vdest; - - /* copy the Y values */ - src1 = src; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j += 2) { - *dest++ = src1[0]; - *dest++ = src1[2]; - src1 += 4; - } - } - - /* copy the U and V values */ - src++; /* point to V */ - src1 = src + width * 2; /* next line */ - vdest = dest + width * height / 4; - for (i = 0; i < height; i += 2) { - for (j = 0; j < width; j += 2) { - *dest++ = ((int) src[0] + src1[0]) / 2; /* U */ - *vdest++ = ((int) src[2] + src1[2]) / 2; /* V */ - src += 4; - src1 += 4; - } - src = src1; - src1 += width * 2; - } -} - -void v4lconvert_yvyu_to_bgr24(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int j; - - while (--height >= 0) { - for (j = 0; j < width; j += 2) { - int u = src[3]; - int v = src[1]; - int u1 = (((u - 128) << 7) + (u - 128)) >> 6; - int rg = (((u - 128) << 1) + (u - 128) + - ((v - 128) << 2) + ((v - 128) << 1)) >> 3; - int v1 = (((v - 128) << 1) + (v - 128)) >> 1; - - *dest++ = CLIP(src[0] + u1); - *dest++ = CLIP(src[0] - rg); - *dest++ = CLIP(src[0] + v1); - - *dest++ = CLIP(src[2] + u1); - *dest++ = CLIP(src[2] - rg); - *dest++ = CLIP(src[2] + v1); - src += 4; - } - } -} - -void v4lconvert_yvyu_to_rgb24(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int j; - - while (--height >= 0) { - for (j = 0; j < width; j += 2) { - int u = src[3]; - int v = src[1]; - int u1 = (((u - 128) << 7) + (u - 128)) >> 6; - int rg = (((u - 128) << 1) + (u - 128) + - ((v - 128) << 2) + ((v - 128) << 1)) >> 3; - int v1 = (((v - 128) << 1) + (v - 128)) >> 1; - - *dest++ = CLIP(src[0] + v1); - *dest++ = CLIP(src[0] - rg); - *dest++ = CLIP(src[0] + u1); - - *dest++ = CLIP(src[2] + v1); - *dest++ = CLIP(src[2] - rg); - *dest++ = CLIP(src[2] + u1); - src += 4; - } - } -} - -void v4lconvert_yvyu_to_yuv420(const unsigned char *src, unsigned char *dest, - int width, int height) -{ - int i, j; - const unsigned char *src1; - unsigned char *vdest; - - /* copy the Y values */ - src1 = src; - for (i = 0; i < height; i++) { - for (j = 0; j < width; j += 2) { - *dest++ = src1[0]; - *dest++ = src1[2]; - src1 += 4; - } - } - - /* copy the U and V values */ - src++; /* point to V */ - src1 = src + width * 2; /* next line */ - vdest = dest + width * height / 4; - for (i = 0; i < height; i += 2) { - for (j = 0; j < width; j += 2) { - *dest++ = ((int) src[2] + src1[2]) / 2; /* U */ - *vdest++ = ((int) src[0] + src1[0]) / 2; /* V */ - src += 4; - src1 += 4; - } - src = src1; - src1 += width * 2; - } -} - -void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i; - - for (i = 0; i < (width * height); i++) { - unsigned char tmp0, tmp1; - tmp0 = *src++; - tmp1 = *src++; - *dst++ = *src++; - *dst++ = tmp1; - *dst++ = tmp0; - } -} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c b/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c deleted file mode 100644 index 4ea526d49..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/sn9c10x.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -# sonix decoder -# Bertrik.Sikken. (C) 2005 - -# 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 Lesser 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 - -# Note this code was originally licensed under the GNU GPL instead of the -# GNU LGPL, its license has been changed with permission, see the permission -# mail at the end of this file. -*/ - -#include "libv4lconvert-priv.h" - -#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. - -*/ -static 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; - const 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++; - } - } -} - -/* -Return-Path: <bertrik@sikken.nl> -Received: from koko.hhs.nl ([145.52.2.16] verified) - by hhs.nl (CommuniGate Pro SMTP 4.3.6) - with ESMTP id 89132066 for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 -Received: from exim (helo=koko) - by koko.hhs.nl with local-smtp (Exim 4.62) - (envelope-from <bertrik@sikken.nl>) - id 1KEOj5-0000nq-KR - for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 -Received: from [192.87.102.69] (port=33783 helo=filter1-ams.mf.surf.net) - by koko.hhs.nl with esmtp (Exim 4.62) - (envelope-from <bertrik@sikken.nl>) - id 1KEOj5-0000nj-7r - for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200 -Received: from cardassian.kabelfoon.nl (cardassian3.kabelfoon.nl [62.45.45.105]) - by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m63DJsKW032598 - for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200 -Received: from [192.168.1.1] (044-013-045-062.dynamic.caiway.nl [62.45.13.44]) - by cardassian.kabelfoon.nl (Postfix) with ESMTP id 77761341D9A - for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200 (CEST) -Message-ID: <486CD1F9.8000307@sikken.nl> -Date: Thu, 03 Jul 2008 15:19:53 +0200 -From: Bertrik Sikken <bertrik@sikken.nl> -User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) -MIME-Version: 1.0 -To: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: Re: pac207 bayer decompression algorithm license question -References: <48633F02.3040108@hhs.nl> <4863F611.80104@sikken.nl> <486CC6AF.7050509@hhs.nl> -In-Reply-To: <486CC6AF.7050509@hhs.nl> -X-Enigmail-Version: 0.95.6 -Content-Type: text/plain; charset=ISO-8859-1; format=flowed -Content-Transfer-Encoding: 7bit -X-Canit-CHI2: 0.00 -X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) -X-Spam-Score: 0.00 () [Tag at 8.00] -X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) -X-Canit-Stats-ID: 90943081 - 6a9ff19e8165 -X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.69 -X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 03072008 #811719, status: clean - ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -Hans de Goede wrote: -| Bertrik Sikken wrote: -|> Hallo Hans, -|> -|> Hans de Goede wrote: -|>> I would like to also add support for decompressing the pac207's -|>> compressed -|>> bayer to this lib (and remove it from the kernel driver) and I've -|>> heard from Thomas Kaiser that you are a co-author of the -|>> decompression code. In order to add support for decompressing pac207 -|>> compressed bayer to libv4l I need -|>> permission to relicense the decompression code under the LGPL -|>> (version 2 or later). -|>> -|>> Can you give me permission for this? -|> -|> Ja, vind ik goed. -|> -| -| Thanks! -| -| I'm currently working on adding support for the sn9c10x bayer -| compression to libv4l too, and I noticed this was written by you too. -| -| May I have your permission to relicense the sn9c10x bayer decompression -| code under the LGPL (version 2 or later)? - -I hereby grant you permission to relicense the sn9c10x bayer -decompression code under the LGPL (version 2 or later). - -Kind regards, -Bertrik ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.7 (MingW32) -Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org - -iD8DBQFIbNH5ETD6mlrWxPURAipvAJ9sv1ZpHyb81NMFejr6x0wqHX3i7QCfRDoB -jZi2e5lUjEh5KvS0dqXbi9I= -=KQfR ------END PGP SIGNATURE----- -*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c b/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c deleted file mode 100644 index 9157629e3..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/spca501.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -# (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 Lesser 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" - -/* YUYV per line */ -void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i,j; - unsigned long *lsrc = (unsigned long *)src; - - for (i = 0; i < height; i += 2) { - /* -128 - 127 --> 0 - 255 and copy first line Y */ - unsigned long *ldst = (unsigned long *)(dst + i * width); - for (j = 0; j < width; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line U */ - ldst = (unsigned long *)(dst + width * height + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy second line Y */ - ldst = (unsigned long *)(dst + i * width + width); - for (j = 0; j < width; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line V */ - ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - } -} - -/* YYUV per line */ -void v4lconvert_spca505_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i,j; - unsigned long *lsrc = (unsigned long *)src; - - for (i = 0; i < height; i += 2) { - /* -128 - 127 --> 0 - 255 and copy 2 lines of Y */ - unsigned long *ldst = (unsigned long *)(dst + i * width); - for (j = 0; j < width*2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line U */ - ldst = (unsigned long *)(dst + width * height + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line V */ - ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - } -} - -/* YUVY per line */ -void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char *dst, - int width, int height) -{ - int i,j; - unsigned long *lsrc = (unsigned long *)src; - - for (i = 0; i < height; i += 2) { - /* -128 - 127 --> 0 - 255 and copy first line Y */ - unsigned long *ldst = (unsigned long *)(dst + i * width); - for (j = 0; j < width; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line U */ - ldst = (unsigned long *)(dst + width * height + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy 1 line V */ - ldst = (unsigned long *)(dst + (width * height * 5) / 4 + i * width / 4); - for (j = 0; j < width/2; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - - /* -128 - 127 --> 0 - 255 and copy second line Y */ - ldst = (unsigned long *)(dst + i * width + width); - for (j = 0; j < width; j += sizeof(long)) { - *ldst = *lsrc++; - *ldst++ ^= 0x8080808080808080ULL; - } - } -} diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c b/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c deleted file mode 100644 index 01eed4ec5..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/spca561-decompress.c +++ /dev/null @@ -1,1003 +0,0 @@ -/* - -# Spca561decoder (C) 2005 Andrzej Szombierski [qq@kuku.eu.org] - -# 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 Lesser 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 - -# Note this code was originally licensed under the GNU GPL instead of the -# GNU LGPL, its license has been changed with permission, see the permission -# mail at the end of this file. - -*/ - -/* - * Decoder for compressed spca561 images - * It was developed for "Labtec WebCam Elch 2(SPCA561A)" (046d:0929) - * but it might work with other spca561 cameras - */ -#include <string.h> -#include "libv4lconvert-priv.h" - -/*fixme: not reentrant */ -static unsigned int bit_bucket; -static const unsigned char *input_ptr; - -static inline void refill(int *bitfill) -{ - if (*bitfill < 8) { - bit_bucket = (bit_bucket << 8) | *(input_ptr++); - *bitfill += 8; - } -} - -static inline int nbits(int *bitfill, int n) -{ - bit_bucket = (bit_bucket << 8) | *(input_ptr++); - *bitfill -= n; - return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); -} - -static inline int _nbits(int *bitfill, int n) -{ - *bitfill -= n; - return (bit_bucket >> (*bitfill & 0xff)) & ((1 << n) - 1); -} - -static int fun_A(int *bitfill) -{ - int ret; - static int tab[] = { - 12, 13, 14, 15, 16, 17, 18, 19, -12, -13, -14, -15, - -16, -17, -18, -19, -19 - }; - - ret = tab[nbits(bitfill, 4)]; - - refill(bitfill); - return ret; -} -static int fun_B(int *bitfill) -{ - static int tab1[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 16, 17, - 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 - }; - static int tab[] = - { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -5, - -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, - -18, -19 - }; - unsigned int tmp; - - tmp = nbits(bitfill, 7) - 68; - refill(bitfill); - if (tmp > 47) - return 0xff; - return tab[tab1[tmp]]; -} -static int fun_C(int *bitfill, int gkw) -{ - static int tab1[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 12, 13, - 14, - 15, 16, 17, 18, 19, 20, 21, 22 - }; - static int tab[] = - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -9, -10, -11, - -12, -13, -14, -15, -16, -17, -18, -19 - }; - unsigned int tmp; - - if (gkw == 0xfe) { - if (nbits(bitfill, 1) == 0) - return 7; - else - return -8; - } - - if (gkw != 0xff) - return 0xff; - - tmp = nbits(bitfill, 7) - 72; - if (tmp > 43) - return 0xff; - - refill(bitfill); - return tab[tab1[tmp]]; -} -static int fun_D(int *bitfill, int gkw) -{ - if (gkw == 0xfd) { - if (nbits(bitfill, 1) == 0) - return 12; - return -13; - } - - if (gkw == 0xfc) { - if (nbits(bitfill, 1) == 0) - return 13; - return -14; - } - - if (gkw == 0xfe) { - switch (nbits(bitfill, 2)) { - case 0: - return 14; - case 1: - return -15; - case 2: - return 15; - case 3: - return -16; - } - } - - if (gkw == 0xff) { - switch (nbits(bitfill, 3)) { - case 4: - return 16; - case 5: - return -17; - case 6: - return 17; - case 7: - return -18; - case 2: - return _nbits(bitfill, 1) ? 0xed : 0x12; - case 3: - (*bitfill)--; - return 18; - } - return 0xff; - } - return gkw; -} - -static int fun_E(int cur_byte, int *bitfill) -{ - static int tab0[] = { 0, -1, 1, -2, 2, -3, 3, -4 }; - static int tab1[] = { 4, -5, 5, -6, 6, -7, 7, -8 }; - static int tab2[] = { 8, -9, 9, -10, 10, -11, 11, -12 }; - static int tab3[] = { 12, -13, 13, -14, 14, -15, 15, -16 }; - static int tab4[] = { 16, -17, 17, -18, 18, -19, 19, -19 }; - - if ((cur_byte & 0xf0) >= 0x80) { - *bitfill -= 4; - return tab0[(cur_byte >> 4) & 7]; - } - if ((cur_byte & 0xc0) == 0x40) { - *bitfill -= 5; - return tab1[(cur_byte >> 3) & 7]; - - } - if ((cur_byte & 0xe0) == 0x20) { - *bitfill -= 6; - return tab2[(cur_byte >> 2) & 7]; - - } - if ((cur_byte & 0xf0) == 0x10) { - *bitfill -= 7; - return tab3[(cur_byte >> 1) & 7]; - - } - if ((cur_byte & 0xf8) == 8) { - *bitfill -= 8; - return tab4[cur_byte & 7]; - } - return 0xff; -} - -static int fun_F(int cur_byte, int *bitfill) -{ - *bitfill -= 5; - switch (cur_byte & 0xf8) { - case 0x80: - return 0; - case 0x88: - return -1; - case 0x90: - return 1; - case 0x98: - return -2; - case 0xa0: - return 2; - case 0xa8: - return -3; - case 0xb0: - return 3; - case 0xb8: - return -4; - case 0xc0: - return 4; - case 0xc8: - return -5; - case 0xd0: - return 5; - case 0xd8: - return -6; - case 0xe0: - return 6; - case 0xe8: - return -7; - case 0xf0: - return 7; - case 0xf8: - return -8; - } - - *bitfill -= 1; - switch (cur_byte & 0xfc) { - case 0x40: - return 8; - case 0x44: - return -9; - case 0x48: - return 9; - case 0x4c: - return -10; - case 0x50: - return 10; - case 0x54: - return -11; - case 0x58: - return 11; - case 0x5c: - return -12; - case 0x60: - return 12; - case 0x64: - return -13; - case 0x68: - return 13; - case 0x6c: - return -14; - case 0x70: - return 14; - case 0x74: - return -15; - case 0x78: - return 15; - case 0x7c: - return -16; - } - - *bitfill -= 1; - switch (cur_byte & 0xfe) { - case 0x20: - return 16; - case 0x22: - return -17; - case 0x24: - return 17; - case 0x26: - return -18; - case 0x28: - return 18; - case 0x2a: - return -19; - case 0x2c: - return 19; - } - - *bitfill += 7; - return 0xff; -} - -static int internal_spca561_decode(int width, int height, - const unsigned char *inbuf, - unsigned char *outbuf) -{ - /* buffers */ - static int accum[8 * 8 * 8]; - static int i_hits[8 * 8 * 8]; - - const int nbits_A[] = - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - }; - const int tab_A[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 11, -11, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, - 10, 10, - 255, 254, -4, - -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, -10, -10, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, - 3, 3, 3, - -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3, -3, -3, -3, - -3, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - 1 - }; - - const int nbits_B[] = - { 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }; - const int tab_B[] = - { 0xff, -4, 3, 3, -3, -3, -3, -3, 2, 2, 2, 2, 2, 2, 2, 2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - }; - - const int nbits_C[] = - { 0, 0, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - }; - const int tab_C[] = - { 0xff, 0xfe, 6, -7, 5, 5, -6, -6, 4, 4, 4, 4, -5, -5, -5, -5, - 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, -4, 2, - 2, 2, 2, - 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, - -3, -3, -3, - -3, -3, -3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, - -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, - }; - - const int nbits_D[] = - { 0, 0, 0, 0, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, - 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, - 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; - const int tab_D[] = - { 0xff, 0xfe, 0xfd, 0xfc, 10, -11, 11, -12, 8, 8, -9, -9, 9, 9, - -10, -10, 6, 6, 6, 6, -7, -7, -7, -7, 7, 7, 7, 7, -8, -8, - -8, -8, - 4, 4, 4, 4, - 4, 4, 4, 4, -5, -5, -5, -5, -5, -5, -5, -5, 5, 5, 5, 5, 5, - 5, 5, 5, - -6, -6, - -6, -6, -6, -6, -6, -6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, - 2, 2, -3, - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - 3, 3, - 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -4, -4, -4, -4, -4, -4, -4, - -4, -4, - -4, -4, -4, - -4, -4, -4, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, - -1, -1, - -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, - -2, -2 - }; - - /* a_curve[19 + i] = ... [-19..19] => [-160..160] */ - const int a_curve[] = - { -160, -144, -128, -112, -98, -88, -80, -72, -64, -56, -48, - -40, -32, -24, -18, -12, -8, -5, -2, 0, 2, 5, 8, 12, 18, - 24, 32, - 40, 48, 56, 64, - 72, 80, 88, 98, 112, 128, 144, 160 - }; - /* clamp0_255[256 + i] = min(max(i,255),0) */ - const unsigned char clamp0_255[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, - 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, - 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, - 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, - 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, - 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, - 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, - 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, - 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, - 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, - 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, - 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, - 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, - 255 - }; - /* abs_clamp15[19 + i] = min(abs(i), 15) */ - const int abs_clamp15[] = - { 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 15, 15, - 15 - }; - /* diff_encoding[256 + i] = ... */ - const int diff_encoding[] = - { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, - 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, - 5, 5, - 5, 5, 5, 5, 5, 3, 3, - 3, 3, 1, 1, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, - 6, 6, 6, 6, 6, 6 - }; - - int block; - int bitfill = 0; - int xwidth = width + 6; - int off_up_right = 2 - 2 * xwidth; - int off_up_left = -2 - 2 * xwidth; - int pixel_U = 0, saved_pixel_UR = 0; - int pixel_x = 0, pixel_y = 2; - unsigned char *output_ptr = outbuf; - - memset(i_hits, 0, sizeof(i_hits)); - memset(accum, 0, sizeof(accum)); - - memcpy(outbuf + xwidth * 2 + 3, inbuf + 0x14, width); - memcpy(outbuf + xwidth * 3 + 3, inbuf + 0x14 + width, width); - - input_ptr = inbuf + 0x14 + width * 2; - output_ptr = outbuf + (xwidth) * 4 + 3; - - bit_bucket = 0; - - for (block = 0; block < ((height - 2) * width) / 32; ++block) { - int b_it, var_7 = 0; - int cur_byte; - - refill(&bitfill); - - cur_byte = (bit_bucket >> (bitfill & 7)) & 0xff; - - if ((cur_byte & 0x80) == 0) { - var_7 = 0; - bitfill--; - } else if ((cur_byte & 0xC0) == 0x80) { - var_7 = 1; - bitfill -= 2; - } else if ((cur_byte & 0xc0) == 0xc0) { - var_7 = 2; - bitfill -= 2; - } - - for (b_it = 0; b_it < 32; b_it++) { - int index; - int pixel_L, pixel_UR, pixel_UL; - int multiplier; - int dL, dC, dR; - int gkw; /* God knows what */ - - refill(&bitfill); - cur_byte = bit_bucket >> (bitfill & 7) & 0xff; - - pixel_L = output_ptr[-2]; - pixel_UR = output_ptr[off_up_right]; - pixel_UL = output_ptr[off_up_left]; - - dL = diff_encoding[0x100 + pixel_UL - pixel_L]; - dC = diff_encoding[0x100 + pixel_U - pixel_UL]; - dR = diff_encoding[0x100 + pixel_UR - pixel_U]; - - if (pixel_x < 2) { - pixel_L = pixel_UL = pixel_U = - output_ptr[-xwidth * 2]; - pixel_UR = output_ptr[off_up_right]; - dL = dC = 0; - dR = diff_encoding[0x100 + pixel_UR - - pixel_U]; - } else if (pixel_x > width - 3) - dR = 0; - - multiplier = 4; - index = dR + dC * 8 + dL * 64; - - if (pixel_L + pixel_U * 2 <= 144 - && (pixel_y & 1) == 0 - && (b_it & 3) == 0 && (dR < 5) && (dC < 5) - && (dL < 5)) { - multiplier = 1; - } else if (pixel_L <= 48 - && dL <= 4 && dC <= 4 && dL >= 1 - && dC >= 1) { - multiplier = 2; - } else if (var_7 == 1) { - multiplier = 2; - } else if (dC + dL >= 11 || var_7 == 2) { - multiplier = 8; - } - - if (i_hits[index] < 7) { - bitfill -= nbits_A[cur_byte]; - gkw = tab_A[cur_byte]; - if (gkw == 0xfe) - gkw = fun_A(&bitfill); - } else if (i_hits[index] >= accum[index]) { - bitfill -= nbits_B[cur_byte]; - gkw = tab_B[cur_byte]; - if (cur_byte == 0) - gkw = fun_B(&bitfill); - } else if (i_hits[index] * 2 >= accum[index]) { - bitfill -= nbits_C[cur_byte]; - gkw = tab_C[cur_byte]; - if (cur_byte < 2) - gkw = fun_C(&bitfill, gkw); - } else if (i_hits[index] * 4 >= accum[index]) { - bitfill -= nbits_D[cur_byte]; - gkw = tab_D[cur_byte]; - if (cur_byte < 4) - gkw = fun_D(&bitfill, gkw); - } else if (i_hits[index] * 8 >= accum[index]) { - gkw = fun_E(cur_byte, &bitfill); - } else { - gkw = fun_F(cur_byte, &bitfill); - } - - if (gkw == 0xff) - return -3; - - { - int tmp1, tmp2; - - tmp1 = - (pixel_U + pixel_L) * 3 - pixel_UL * 2; - tmp1 += (tmp1 < 0) ? 3 : 0; - tmp2 = a_curve[19 + gkw] * multiplier; - tmp2 += (tmp2 < 0) ? 1 : 0; - - *(output_ptr++) = - clamp0_255[0x100 + (tmp1 >> 2) - - (tmp2 >> 1)]; - } - pixel_U = saved_pixel_UR; - saved_pixel_UR = pixel_UR; - - if (++pixel_x == width) { - output_ptr += 6; - pixel_x = 0; - pixel_y++; - } - - accum[index] += abs_clamp15[19 + gkw]; - - if (i_hits[index]++ == 15) { - i_hits[index] = 8; - accum[index] /= 2; - } - } - } - return 0; -} - -/* FIXME, change internal_spca561_decode not to need the extra border - around its dest buffer */ -void v4lconvert_decode_spca561(const unsigned char *inbuf, - unsigned char *outbuf, int width, int height) -{ - int i; - static unsigned char tmpbuf[650 * 490]; - if (internal_spca561_decode(width, height, inbuf, tmpbuf) != 0) - return; - for (i = 0; i < height; i++) - memcpy(outbuf + i * width, - tmpbuf + (i + 2) * (width + 6) + 3, width); -} - -/*************** License Change Permission Notice *************** - -Return-Path: <qq@kuku.eu.org> -Received: from koko.hhs.nl ([145.52.2.16] verified) - by hhs.nl (CommuniGate Pro SMTP 4.3.6) - with ESMTP id 88574071 for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200 -Received: from exim (helo=koko) - by koko.hhs.nl with local-smtp (Exim 4.62) - (envelope-from <qq@kuku.eu.org>) - id 1K8Fom-0002iJ-3K - for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:24 +0200 -Received: from [192.87.102.74] (port=41377 helo=filter6-ams.mf.surf.net) - by koko.hhs.nl with esmtp (Exim 4.62) - (envelope-from <qq@kuku.eu.org>) - id 1K8Fol-0002iC-Qo - for j.w.r.degoede@hhs.nl; Mon, 16 Jun 2008 16:36:23 +0200 -Received: from kuku.eu.org (pa90.wielkopole.sdi.tpnet.pl [217.99.123.90]) - by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5GEa55r001787 - for <j.w.r.degoede@hhs.nl>; Mon, 16 Jun 2008 16:36:06 +0200 -Received: (qmail 2243 invoked by uid 500); 16 Jun 2008 14:29:37 -0000 -Date: Mon, 16 Jun 2008 16:29:37 +0200 (CEST) -From: Andrzej Szombierski <qq@kuku.eu.org> -To: Hans de Goede <j.w.r.degoede@hhs.nl> -Subject: Re: spca561 decoder license question -In-Reply-To: <485673B6.4050003@hhs.nl> -Message-ID: <Pine.LNX.4.44L.0806161614560.7665-100000@kuku.eu.org> -References: <485673B6.4050003@hhs.nl> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=iso-8859-2 -Content-Transfer-Encoding: QUOTED-PRINTABLE -X-Canit-CHI2: 0.00 -X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN) -X-Spam-Score: 2.00 (**) [Tag at 6.00] RBL(uceprotect-blacklist.surfnet.nl,2.0) -X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default) -X-Canit-Stats-ID: 85673281 - 37e52c8b07bc -X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74 -X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 16062008 #776409, status: clean - -On Mon, 16 Jun 2008, Hans de Goede wrote: - -> Hi, ->=20 -> I don't know if you're still subscribed to the spca devel mailing list, s= -o let=20 -> me start with a short intro. -> -> I'm a Linux enthusiast / developer currently helping Jean-Fran=E7ois Moin= -e with=20 -> porting gspca to video4linux2 and cleaning up the code to get it ready fo= -r=20 -> mainline kernel inclusion. ->=20 -> As part of this process the decompression code for all supported cams mus= -t be=20 -> moved to userspace, as doing in kernel decompression is considered unwant= -ed by=20 -> the mainline people (I agree) as it should be done in userspace. -> - -Sounds reasonable. -=20 -> As such I'm working on a library which does decompression of custom cam f= -ormats=20 -> in userspace. -> - -Nice. I hope that the library won't be limited to spca-supported webcams,= -=20 -and as an application developer I would be able to just request RGB data=20 -from any /dev/video*, right? - -> I do not want to license this library as GPL (as the current spca code is= -), as=20 -> it should be usable by as much software as possible. Instead I want to li= -cense=20 -> it under the LGPL version 2.1 or later. - -Also sounds reasonable. - ->=20 -> So my question us my I have your permission to relicense your spca561=20 -> decompression code under the LGPL? ->=20 - -Yes, of course.=20 - -> Thanks & Regards, ->=20 -> Hans ->=20 -> - ---=20 -:: Andrzej Szombierski :: qq@kuku.eu.org :: http://kuku.eu.org :: -:: anszom@bezkitu.com :: radio bez kitu :: http://bezkitu.com :: - -*/ diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h deleted file mode 100644 index 26844c28a..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg-internal.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Small jpeg decoder library (Internal header) - * - * Copyright (c) 2006, Luc Saillard <luc@saillard.org> - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the author nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - - -#ifndef __TINYJPEG_INTERNAL_H_ -#define __TINYJPEG_INTERNAL_H_ - -#include <setjmp.h> - -#define SANITY_CHECK 1 - -struct jdec_private; - -#define HUFFMAN_HASH_NBITS 9 -#define HUFFMAN_HASH_SIZE (1UL<<HUFFMAN_HASH_NBITS) -#define HUFFMAN_HASH_MASK (HUFFMAN_HASH_SIZE-1) - -#define HUFFMAN_TABLES 4 -#define COMPONENTS 3 -#define JPEG_MAX_WIDTH 2048 -#define JPEG_MAX_HEIGHT 2048 - -struct huffman_table -{ - /* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol, - * if the symbol is <0, then we need to look into the tree table */ - short int lookup[HUFFMAN_HASH_SIZE]; - /* code size: give the number of bits of a symbol is encoded */ - unsigned char code_size[HUFFMAN_HASH_SIZE]; - /* some place to store value that is not encoded in the lookup table - * IMPROVEME: Calculate if 256 value is enough to store all values - */ - uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256]; -}; - -struct component -{ - unsigned int Hfactor; - unsigned int Vfactor; - float *Q_table; /* Pointer to the quantisation table to use */ - struct huffman_table *AC_table; - struct huffman_table *DC_table; - short int previous_DC; /* Previous DC coefficient */ - short int DCT[64]; /* DCT coef */ -#if SANITY_CHECK - unsigned int cid; -#endif -}; - - -typedef void (*decode_MCU_fct) (struct jdec_private *priv); -typedef void (*convert_colorspace_fct) (struct jdec_private *priv); - -struct jdec_private -{ - /* Public variables */ - uint8_t *components[COMPONENTS]; - unsigned int width, height; /* Size of the image */ - unsigned int flags; - - /* Private variables */ - const unsigned char *stream_begin, *stream_end; - unsigned int stream_length; - - const unsigned char *stream; /* Pointer to the current stream */ - unsigned int reservoir, nbits_in_reservoir; - - struct component component_infos[COMPONENTS]; - float Q_tables[COMPONENTS][64]; /* quantization tables */ - struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */ - struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */ - int default_huffman_table_initialized; - int restart_interval; - int restarts_to_go; /* MCUs left in this restart interval */ - int last_rst_marker_seen; /* Rst marker is incremented each time */ - - /* Temp space used after the IDCT to store each components */ - uint8_t Y[64*4], Cr[64], Cb[64]; - - jmp_buf jump_state; - /* Internal Pointer use for colorspace conversion, do not modify it !!! */ - uint8_t *plane[COMPONENTS]; - - char error_string[256]; -}; - -#define IDCT tinyjpeg_idct_float -void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride); - -#endif - diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c deleted file mode 100644 index fc9efbeb2..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.c +++ /dev/null @@ -1,2463 +0,0 @@ -/* - * Small jpeg decoder library - * - * Copyright (c) 2006, Luc Saillard <luc@saillard.org> - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the author nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <errno.h> - -#include "tinyjpeg.h" -#include "tinyjpeg-internal.h" - -enum std_markers { - DQT = 0xDB, /* Define Quantization Table */ - SOF = 0xC0, /* Start of Frame (size information) */ - DHT = 0xC4, /* Huffman Table */ - SOI = 0xD8, /* Start of Image */ - SOS = 0xDA, /* Start of Scan */ - RST = 0xD0, /* Reset Marker d0 -> .. */ - RST7 = 0xD7, /* Reset Marker .. -> d7 */ - EOI = 0xD9, /* End of Image */ - DRI = 0xDD, /* Define Restart Interval */ - APP0 = 0xE0, -}; - -#define cY 0 -#define cCb 1 -#define cCr 2 - -#define BLACK_Y 0 -#define BLACK_U 127 -#define BLACK_V 127 - -#if DEBUG -#if LOG2FILE - -#define trace(fmt, args...) do { \ - FILE *f = fopen("/tmp/jpeg.log", "a"); \ - fprintf(f, fmt, ## args); \ - fflush(f); \ - fclose(f); \ -} while(0) - -#else - -#define trace(fmt, args...) do { \ - fprintf(stderr, fmt, ## args); \ - fflush(stderr); \ -} while(0) -#endif - -#else -#define trace(fmt, args...) do { } while (0) -#endif - -#define error(fmt, args...) do { \ - snprintf(priv->error_string, sizeof(priv->error_string), fmt, ## args); \ - return -1; \ -} while(0) - - -#if 0 -static char *print_bits(unsigned int value, char *bitstr) -{ - int i, j; - i=31; - while (i>0) - { - if (value & (1UL<<i)) - break; - i--; - } - j=0; - while (i>=0) - { - bitstr[j++] = (value & (1UL<<i))?'1':'0'; - i--; - } - bitstr[j] = 0; - return bitstr; -} - -static void print_next_16bytes(int offset, const unsigned char *stream) -{ - trace("%4.4x: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", - offset, - stream[0], stream[1], stream[2], stream[3], - stream[4], stream[5], stream[6], stream[7], - stream[8], stream[9], stream[10], stream[11], - stream[12], stream[13], stream[14], stream[15]); -} - -#endif - - -static const unsigned char zigzag[64] = -{ - 0, 1, 5, 6, 14, 15, 27, 28, - 2, 4, 7, 13, 16, 26, 29, 42, - 3, 8, 12, 17, 25, 30, 41, 43, - 9, 11, 18, 24, 31, 40, 44, 53, - 10, 19, 23, 32, 39, 45, 52, 54, - 20, 22, 33, 38, 46, 51, 55, 60, - 21, 34, 37, 47, 50, 56, 59, 61, - 35, 36, 48, 49, 57, 58, 62, 63 -}; - -/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ -/* IMPORTANT: these are only valid for 8-bit data precision! */ -static const unsigned char bits_dc_luminance[17] = -{ - 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 -}; -static const unsigned char val_dc_luminance[] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const unsigned char bits_dc_chrominance[17] = -{ - 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 -}; -static const unsigned char val_dc_chrominance[] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -}; - -static const unsigned char bits_ac_luminance[17] = -{ - 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d -}; -static const unsigned char val_ac_luminance[] = -{ - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -static const unsigned char bits_ac_chrominance[17] = -{ - 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 -}; - -static const unsigned char val_ac_chrominance[] = -{ - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -const unsigned char pixart_quantization[][64] = { - { - 0x07, 0x07, 0x08, 0x0a, 0x09, 0x07, 0x0d, 0x0b, - 0x0c, 0x0d, 0x11, 0x10, 0x0f, 0x12, 0x17, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, - }, - { - 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - }, -}; - -/* - * 4 functions to manage the stream - * - * fill_nbits: put at least nbits in the reservoir of bits. - * But convert any 0xff,0x00 into 0xff - * get_nbits: read nbits from the stream, and put it in result, - * bits is removed from the stream and the reservoir is filled - * automaticaly. The result is signed according to the number of - * bits. - * look_nbits: read nbits from the stream without marking as read. - * skip_nbits: read nbits from the stream but do not return the result. - * - * stream: current pointer in the jpeg data (read bytes per bytes) - * nbits_in_reservoir: number of bits filled into the reservoir - * reservoir: register that contains bits information. Only nbits_in_reservoir - * is valid. - * nbits_in_reservoir - * <-- 17 bits --> - * Ex: 0000 0000 1010 0000 1111 0000 <== reservoir - * ^ - * bit 1 - * To get two bits from this example - * result = (reservoir >> 15) & 3 - * - */ -#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ - while (nbits_in_reservoir<nbits_wanted) \ - { \ - unsigned char c; \ - if (stream >= priv->stream_end) { \ - snprintf(priv->error_string, sizeof(priv->error_string), \ - "fill_nbits error: need %u more bits\n", \ - nbits_wanted - nbits_in_reservoir); \ - longjmp(priv->jump_state, -EIO); \ - } \ - c = *stream++; \ - reservoir <<= 8; \ - if (c == 0xff && *stream == 0x00) \ - stream++; \ - reservoir |= c; \ - nbits_in_reservoir+=8; \ - } \ -} while(0); - -/* Signed version !!!! */ -#define get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ - fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ - result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ - nbits_in_reservoir -= (nbits_wanted); \ - reservoir &= ((1U<<nbits_in_reservoir)-1); \ - if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \ - result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \ -} while(0); - -#define look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) do { \ - fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ - result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ -} while(0); - -/* To speed up the decoding, we assume that the reservoir have enough bit - * slow version: - * #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ - * fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ - * nbits_in_reservoir -= (nbits_wanted); \ - * reservoir &= ((1U<<nbits_in_reservoir)-1); \ - * } while(0); - */ -#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ - nbits_in_reservoir -= (nbits_wanted); \ - reservoir &= ((1U<<nbits_in_reservoir)-1); \ -} while(0); - - -/* Special Pixart versions of the *_nbits functions, these remove the special - ff ff ff xx sequences pixart cams insert from the bitstream */ -#define pixart_fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) \ -do { \ - while (nbits_in_reservoir<nbits_wanted) \ - { \ - unsigned char c; \ - if (stream >= priv->stream_end) { \ - snprintf(priv->error_string, sizeof(priv->error_string), \ - "fill_nbits error: need %u more bits\n", \ - nbits_wanted - nbits_in_reservoir); \ - longjmp(priv->jump_state, -EIO); \ - } \ - c = *stream++; \ - reservoir <<= 8; \ - if (c == 0xff) { \ - switch (stream[0]) { \ - case 0x00: \ - stream++; \ - break; \ - case 0xd9: /* EOF marker */ \ - stream++; \ - if (stream != priv->stream_end) { \ - snprintf(priv->error_string, sizeof(priv->error_string), \ - "Pixart JPEG error: premature EOF\n"); \ - longjmp(priv->jump_state, -EIO); \ - } \ - break; \ - case 0xff: \ - if (stream[1] == 0xff && (stream[2] < 7 || stream[2] == 0xff)) { \ - stream += 3; \ - c = *stream++; \ - break; \ - } \ - /* Error fall through */ \ - default: \ - snprintf(priv->error_string, sizeof(priv->error_string), \ - "Pixart JPEG error: invalid JPEG marker: 0xff 0x%02x 0x%02x 0x%02x\n", \ - (unsigned int)stream[0], (unsigned int)stream[1], \ - (unsigned int)stream[2]); \ - longjmp(priv->jump_state, -EIO); \ - } \ - } \ - reservoir |= c; \ - nbits_in_reservoir+=8; \ - } \ -} while(0); - -/* Signed version !!!! */ -#define pixart_get_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) \ -do { \ - pixart_fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ - result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ - nbits_in_reservoir -= (nbits_wanted); \ - reservoir &= ((1U<<nbits_in_reservoir)-1); \ - if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \ - result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \ -} while(0); - -#define pixart_look_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted,result) \ -do { \ - pixart_fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \ - result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \ -} while(0); - -/* Note skip_nbits is identical for both */ - - -#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1]) - -static void resync(struct jdec_private *priv); - -/** - * Get the next (valid) huffman code in the stream. - * - * To speedup the procedure, we look HUFFMAN_HASH_NBITS bits and the code is - * lower than HUFFMAN_HASH_NBITS we have automaticaly the length of the code - * and the value by using two lookup table. - * Else if the value is not found, just search (linear) into an array for each - * bits is the code is present. - * - * If the code is not present for any reason, -1 is return. - */ -static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table *huffman_table) -{ - int value, hcode; - unsigned int extra_nbits, nbits; - uint16_t *slowtable; - - look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode); - value = huffman_table->lookup[hcode]; - if (value >= 0) - { - unsigned int code_size = huffman_table->code_size[value]; - skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size); - return value; - } - - /* Decode more bits each time ... */ - for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++) - { - nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits; - - look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode); - slowtable = huffman_table->slowtable[extra_nbits]; - /* Search if the code is in this array */ - while (slowtable[0]) { - if (slowtable[0] == hcode) { - skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits); - return slowtable[1]; - } - slowtable+=2; - } - } - snprintf(priv->error_string, sizeof(priv->error_string), - "unknown huffman code: %08x\n", (unsigned int)hcode); - longjmp(priv->jump_state, -EIO); - return 0; -} - -/* identical as above but with *_nbits replaced with pixart_*_nbits */ -static int pixart_get_next_huffman_code(struct jdec_private *priv, - struct huffman_table *huffman_table) -{ - int value, hcode; - unsigned int extra_nbits, nbits; - uint16_t *slowtable; - - pixart_look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode); - value = huffman_table->lookup[hcode]; - if (value >= 0) - { - unsigned int code_size = huffman_table->code_size[value]; - skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size); - return value; - } - - /* Decode more bits each time ... */ - for (extra_nbits=0; extra_nbits<16-HUFFMAN_HASH_NBITS; extra_nbits++) - { - nbits = HUFFMAN_HASH_NBITS + 1 + extra_nbits; - - pixart_look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits, hcode); - slowtable = huffman_table->slowtable[extra_nbits]; - /* Search if the code is in this array */ - while (slowtable[0]) { - if (slowtable[0] == hcode) { - skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, nbits); - return slowtable[1]; - } - slowtable+=2; - } - } - snprintf(priv->error_string, sizeof(priv->error_string), - "unknown huffman code: %08x\n", (unsigned int)hcode); - longjmp(priv->jump_state, -EIO); - return 0; -} - - - -/** - * - * Decode a single block that contains the DCT coefficients. - * The table coefficients is already dezigzaged at the end of the operation. - * - */ -static void process_Huffman_data_unit(struct jdec_private *priv, int component) -{ - unsigned char j; - unsigned int huff_code; - unsigned char size_val, count_0; - - struct component *c = &priv->component_infos[component]; - short int DCT[64]; - - /* Initialize the DCT coef table */ - memset(DCT, 0, sizeof(DCT)); - - /* DC coefficient decoding */ - huff_code = get_next_huffman_code(priv, c->DC_table); - if (huff_code) { - get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); - DCT[0] += c->previous_DC; - c->previous_DC = DCT[0]; - } else { - DCT[0] = c->previous_DC; - } - - - /* AC coefficient decoding */ - j = 1; - while (j<64) - { - huff_code = get_next_huffman_code(priv, c->AC_table); - - size_val = huff_code & 0xF; - count_0 = huff_code >> 4; - - if (size_val == 0) - { /* RLE */ - if (count_0 == 0) - break; /* EOB found, go out */ - else if (count_0 == 0xF) - j += 16; /* skip 16 zeros */ - } - else - { - j += count_0; /* skip count_0 zeroes */ - if (j < 64) { - get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); - j++; - } - } - } - - if (j > 64) { - snprintf(priv->error_string, sizeof(priv->error_string), - "error: more then 63 AC components (%d) in huffman unit\n", (int)j); - longjmp(priv->jump_state, -EIO); - } - - for (j = 0; j < 64; j++) - c->DCT[j] = DCT[zigzag[j]]; -} - -/* identical as above both with *_nbits replaced with pixart_*_nbits */ -static void pixart_process_Huffman_data_unit(struct jdec_private *priv, int component) -{ - unsigned char j; - unsigned int huff_code; - unsigned char size_val, count_0; - - struct component *c = &priv->component_infos[component]; - short int DCT[64]; - - /* Initialize the DCT coef table */ - memset(DCT, 0, sizeof(DCT)); - - /* DC coefficient decoding */ - huff_code = pixart_get_next_huffman_code(priv, c->DC_table); - if (huff_code) { - pixart_get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); - DCT[0] += c->previous_DC; - c->previous_DC = DCT[0]; - } else { - DCT[0] = c->previous_DC; - } - - - /* AC coefficient decoding */ - j = 1; - while (j<64) - { - huff_code = pixart_get_next_huffman_code(priv, c->AC_table); - - size_val = huff_code & 0xF; - count_0 = huff_code >> 4; - - if (size_val == 0) - { /* RLE */ - if (count_0 == 0) - break; /* EOB found, go out */ - else if (count_0 == 0xF) - j += 16; /* skip 16 zeros */ - } - else - { - j += count_0; /* skip count_0 zeroes */ - if (j < 64 ) { - pixart_get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); - j++; - } - } - } - - if (j > 64) { - snprintf(priv->error_string, sizeof(priv->error_string), - "error: more then 63 AC components (%d) in huffman unit\n", (int)j); - longjmp(priv->jump_state, -EIO); - } - - for (j = 0; j < 64; j++) - c->DCT[j] = DCT[zigzag[j]]; -} - - -/* - * Takes two array of bits, and build the huffman table for size, and code - * - * lookup will return the symbol if the code is less or equal than HUFFMAN_HASH_NBITS. - * code_size will be used to known how many bits this symbol is encoded. - * slowtable will be used when the first lookup didn't give the result. - */ -static int build_huffman_table(struct jdec_private *priv, const unsigned char *bits, const unsigned char *vals, struct huffman_table *table) -{ - unsigned int i, j, code, code_size, val, nbits; - unsigned char huffsize[257], *hz; - unsigned int huffcode[257], *hc; - int next_free_entry; - int slowtable_used[16-HUFFMAN_HASH_NBITS]; - - /* - * Build a temp array - * huffsize[X] => numbers of bits to write vals[X] - */ - hz = huffsize; - for (i=1; i<=16; i++) - { - for (j=1; j<=bits[i]; j++) - *hz++ = i; - } - *hz = 0; - - memset(table->lookup, 0xff, sizeof(table->lookup)); - for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) - slowtable_used[i] = 0; - - /* Build a temp array - * huffcode[X] => code used to write vals[X] - */ - code = 0; - hc = huffcode; - hz = huffsize; - nbits = *hz; - while (*hz) - { - while (*hz == nbits) { - *hc++ = code++; - hz++; - } - code <<= 1; - nbits++; - } - - /* - * Build the lookup table, and the slowtable if needed. - */ - next_free_entry = -1; - for (i=0; huffsize[i]; i++) - { - val = vals[i]; - code = huffcode[i]; - code_size = huffsize[i]; - - trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size); - - table->code_size[val] = code_size; - if (code_size <= HUFFMAN_HASH_NBITS) - { - /* - * Good: val can be put in the lookup table, so fill all value of this - * column with value val - */ - int repeat = 1UL<<(HUFFMAN_HASH_NBITS - code_size); - code <<= HUFFMAN_HASH_NBITS - code_size; - while ( repeat-- ) - table->lookup[code++] = val; - - } - else - { - /* Perhaps sorting the array will be an optimization */ - int slowtable_index = code_size-HUFFMAN_HASH_NBITS-1; - - if (slowtable_used[slowtable_index] == 254) - error("slow Huffman table overflow\n"); - - table->slowtable[slowtable_index][slowtable_used[slowtable_index]] - = code; - table->slowtable[slowtable_index][slowtable_used[slowtable_index] + 1] - = val; - slowtable_used[slowtable_index] += 2; - } - } - - for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) - table->slowtable[i][slowtable_used[i]] = 0; - - return 0; -} - -static int build_default_huffman_tables(struct jdec_private *priv) -{ - if ( (priv->flags & TINYJPEG_FLAGS_MJPEG_TABLE) - && priv->default_huffman_table_initialized) - return 0; - - if (build_huffman_table(priv, bits_dc_luminance, val_dc_luminance, &priv->HTDC[0])) - return -1; - if (build_huffman_table(priv, bits_ac_luminance, val_ac_luminance, &priv->HTAC[0])) - return -1; - - if (build_huffman_table(priv, bits_dc_chrominance, val_dc_chrominance, &priv->HTDC[1])) - return -1; - if (build_huffman_table(priv, bits_ac_chrominance, val_ac_chrominance, &priv->HTAC[1])) - return -1; - - priv->default_huffman_table_initialized = 1; - return 0; -} - - - -/******************************************************************************* - * - * Colorspace conversion routine - * - * - * Note: - * YCbCr is defined per CCIR 601-1, except that Cb and Cr are - * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. - * The conversion equations to be implemented are therefore - * R = Y + 1.40200 * Cr - * G = Y - 0.34414 * Cb - 0.71414 * Cr - * B = Y + 1.77200 * Cb - * - ******************************************************************************/ - -static unsigned char clamp(int i) -{ - if (i<0) - return 0; - else if (i>255) - return 255; - else - return i; -} - - -/** - * YCrCb -> YUV420P (1x1) - * .---. - * | 1 | - * `---' - */ -static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv) -{ - const unsigned char *s, *y; - unsigned char *p; - int i,j; - - p = priv->plane[0]; - y = priv->Y; - for (i=0; i<8; i++) - { - memcpy(p, y, 8); - p+=priv->width; - y+=8; - } - - p = priv->plane[1]; - s = priv->Cb; - for (i=0; i<8; i+=2) - { - for (j=0; j<8; j+=2, s+=2) - *p++ = *s; - s += 8; /* Skip one line */ - p += priv->width/2 - 4; - } - - p = priv->plane[2]; - s = priv->Cr; - for (i=0; i<8; i+=2) - { - for (j=0; j<8; j+=2, s+=2) - *p++ = *s; - s += 8; /* Skip one line */ - p += priv->width/2 - 4; - } -} - -/** - * YCrCb -> YUV420P (2x1) - * .-------. - * | 1 | 2 | - * `-------' - */ -static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv) -{ - unsigned char *p; - const unsigned char *s, *y1; - unsigned int i; - - p = priv->plane[0]; - y1 = priv->Y; - for (i=0; i<8; i++) - { - memcpy(p, y1, 16); - p += priv->width; - y1 += 16; - } - - p = priv->plane[1]; - s = priv->Cb; - for (i=0; i<8; i+=2) - { - memcpy(p, s, 8); - s += 16; /* Skip one line */ - p += priv->width/2; - } - - p = priv->plane[2]; - s = priv->Cr; - for (i=0; i<8; i+=2) - { - memcpy(p, s, 8); - s += 16; /* Skip one line */ - p += priv->width/2; - } -} - - -/** - * YCrCb -> YUV420P (1x2) - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv) -{ - const unsigned char *s, *y; - unsigned char *p; - int i,j; - - p = priv->plane[0]; - y = priv->Y; - for (i=0; i<16; i++) - { - memcpy(p, y, 8); - p+=priv->width; - y+=8; - } - - p = priv->plane[1]; - s = priv->Cb; - for (i=0; i<8; i++) - { - for (j=0; j<8; j+=2, s+=2) - *p++ = *s; - p += priv->width/2 - 4; - } - - p = priv->plane[2]; - s = priv->Cr; - for (i=0; i<8; i++) - { - for (j=0; j<8; j+=2, s+=2) - *p++ = *s; - p += priv->width/2 - 4; - } -} - -/** - * YCrCb -> YUV420P (2x2) - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv) -{ - unsigned char *p; - const unsigned char *s, *y1; - unsigned int i; - - p = priv->plane[0]; - y1 = priv->Y; - for (i=0; i<16; i++) - { - memcpy(p, y1, 16); - p += priv->width; - y1 += 16; - } - - p = priv->plane[1]; - s = priv->Cb; - for (i=0; i<8; i++) - { - memcpy(p, s, 8); - s += 8; - p += priv->width/2; - } - - p = priv->plane[2]; - s = priv->Cr; - for (i=0; i<8; i++) - { - memcpy(p, s, 8); - s += 8; - p += priv->width/2; - } -} - -/** - * YCrCb -> RGB24 (1x1) - * .---. - * | 1 | - * `---' - */ -static void YCrCB_to_RGB24_1x1(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = priv->width*3 - 8*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - y = (*Y++) << SCALEBITS; - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - } - - p += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - -/** - * YCrCb -> BGR24 (1x1) - * .---. - * | 1 | - * `---' - */ -static void YCrCB_to_BGR24_1x1(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = priv->width*3 - 8*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - y = (*Y++) << SCALEBITS; - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - } - - p += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - - -/** - * YCrCb -> RGB24 (2x1) - * .-------. - * | 1 | 2 | - * `-------' - */ -static void YCrCB_to_RGB24_2x1(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = priv->width*3 - 16*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - y = (*Y++) << SCALEBITS; - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - y = (*Y++) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - } - - p += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - -/* - * YCrCb -> BGR24 (2x1) - * .-------. - * | 1 | 2 | - * `-------' - */ -static void YCrCB_to_BGR24_2x1(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = priv->width*3 - 16*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - y = (*Y++) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - y = (*Y++) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - } - - p += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - -/** - * YCrCb -> RGB24 (1x2) - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void YCrCB_to_RGB24_1x2(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p, *p2; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - p2 = priv->plane[0] + priv->width*3; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = 2*priv->width*3 - 8*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - y = (*Y++) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - y = (Y[8-1]) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - - } - Y += 8; - p += offset_to_next_row; - p2 += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - -/* - * YCrCb -> BGR24 (1x2) - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void YCrCB_to_BGR24_1x2(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p, *p2; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - p2 = priv->plane[0] + priv->width*3; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = 2*priv->width*3 - 8*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - y = (*Y++) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - y = (Y[8-1]) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - - } - Y += 8; - p += offset_to_next_row; - p2 += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - - -/** - * YCrCb -> RGB24 (2x2) - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void YCrCB_to_RGB24_2x2(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p, *p2; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - p2 = priv->plane[0] + priv->width*3; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = (priv->width*3*2) - 16*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - y = (*Y++) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - y = (*Y++) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - - y = (Y[16-2]) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - - y = (Y[16-1]) << SCALEBITS; - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - } - Y += 16; - p += offset_to_next_row; - p2 += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - - -/* - * YCrCb -> BGR24 (2x2) - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void YCrCB_to_BGR24_2x2(struct jdec_private *priv) -{ - const unsigned char *Y, *Cb, *Cr; - unsigned char *p, *p2; - int i,j; - int offset_to_next_row; - -#define SCALEBITS 10 -#define ONE_HALF (1UL << (SCALEBITS-1)) -#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) - - p = priv->plane[0]; - p2 = priv->plane[0] + priv->width*3; - Y = priv->Y; - Cb = priv->Cb; - Cr = priv->Cr; - offset_to_next_row = (priv->width*3*2) - 16*3; - for (i=0; i<8; i++) { - - for (j=0; j<8; j++) { - - int y, cb, cr; - int add_r, add_g, add_b; - int r, g , b; - - cb = *Cb++ - 128; - cr = *Cr++ - 128; - add_r = FIX(1.40200) * cr + ONE_HALF; - add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; - add_b = FIX(1.77200) * cb + ONE_HALF; - - y = (*Y++) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - y = (*Y++) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p++ = clamp(r); - - y = (Y[16-2]) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - - y = (Y[16-1]) << SCALEBITS; - b = (y + add_b) >> SCALEBITS; - *p2++ = clamp(b); - g = (y + add_g) >> SCALEBITS; - *p2++ = clamp(g); - r = (y + add_r) >> SCALEBITS; - *p2++ = clamp(r); - } - Y += 16; - p += offset_to_next_row; - p2 += offset_to_next_row; - } - -#undef SCALEBITS -#undef ONE_HALF -#undef FIX - -} - - - -/** - * YCrCb -> Grey (1x1) - * .---. - * | 1 | - * `---' - */ -static void YCrCB_to_Grey_1x1(struct jdec_private *priv) -{ - const unsigned char *y; - unsigned char *p; - unsigned int i; - int offset_to_next_row; - - p = priv->plane[0]; - y = priv->Y; - offset_to_next_row = priv->width; - - for (i=0; i<8; i++) { - memcpy(p, y, 8); - y+=8; - p += offset_to_next_row; - } -} - -/** - * YCrCb -> Grey (2x1) - * .-------. - * | 1 | 2 | - * `-------' - */ -static void YCrCB_to_Grey_2x1(struct jdec_private *priv) -{ - const unsigned char *y; - unsigned char *p; - unsigned int i; - - p = priv->plane[0]; - y = priv->Y; - - for (i=0; i<8; i++) { - memcpy(p, y, 16); - y += 16; - p += priv->width; - } -} - - -/** - * YCrCb -> Grey (1x2) - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void YCrCB_to_Grey_1x2(struct jdec_private *priv) -{ - const unsigned char *y; - unsigned char *p; - unsigned int i; - - p = priv->plane[0]; - y = priv->Y; - - for (i=0; i<16; i++) { - memcpy(p, y, 8); - y += 8; - p += priv->width; - } -} - -/** - * YCrCb -> Grey (2x2) - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void YCrCB_to_Grey_2x2(struct jdec_private *priv) -{ - const unsigned char *y; - unsigned char *p; - unsigned int i; - - p = priv->plane[0]; - y = priv->Y; - - for (i=0; i<16; i++) { - memcpy(p, y, 16); - y += 16; - p += priv->width; - } -} - - -/* - * Decode all the 3 components for 1x1 - */ -static void decode_MCU_1x1_3planes(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 8); - - // Cb - process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - -/* - * Decode a 1x1 directly in 1 color - */ -static void decode_MCU_1x1_1plane(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 8); - - // Cb - process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - - -/* - * Decode a 2x1 - * .-------. - * | 1 | 2 | - * `-------' - */ -static void decode_MCU_2x1_3planes(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+8, 16); - - // Cb - process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - -static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv) -{ - unsigned char marker; - - pixart_look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, - 8, marker); - /* I think the marker indicates which quantization table to use, iow - a Pixart JPEG may have a different quantization table per MCU, most - MCU's have 0x44 as marker for which our special Pixart quantization - tables are correct. Unfortunately with a 7302 some blocks also have 0x48, - and sometimes even other values. As 0x48 is quite common too, we really - need to find out the correct table for that, as currently the blocks - with a 0x48 marker look wrong. During normal operation the marker stays - within the range below, if it gets out of this range we're most likely - decoding garbage */ - if (marker < 0x20 || marker > 0x7f) { - snprintf(priv->error_string, sizeof(priv->error_string), - "Pixart JPEG error: invalid MCU marker: 0x%02x\n", - (unsigned int)marker); - longjmp(priv->jump_state, -EIO); - } - skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, 8); - - // Y - pixart_process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 16); - pixart_process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+8, 16); - - // Cb - pixart_process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - pixart_process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - -/* - * Decode a 2x1 - * .-------. - * | 1 | 2 | - * `-------' - */ -static void decode_MCU_2x1_1plane(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+8, 16); - - // Cb - process_Huffman_data_unit(priv, cCb); - - // Cr - process_Huffman_data_unit(priv, cCr); -} - - -/* - * Decode a 2x2 - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void decode_MCU_2x2_3planes(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+8, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); - - // Cb - process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - -/* - * Decode a 2x2 directly in GREY format (8bits) - * .-------. - * | 1 | 2 | - * |---+---| - * | 3 | 4 | - * `-------' - */ -static void decode_MCU_2x2_1plane(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+8, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); - - // Cb - process_Huffman_data_unit(priv, cCb); - - // Cr - process_Huffman_data_unit(priv, cCr); -} - -/* - * Decode a 1x2 mcu - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void decode_MCU_1x2_3planes(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 8); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64, 8); - - // Cb - process_Huffman_data_unit(priv, cCb); - IDCT(&priv->component_infos[cCb], priv->Cb, 8); - - // Cr - process_Huffman_data_unit(priv, cCr); - IDCT(&priv->component_infos[cCr], priv->Cr, 8); -} - -/* - * Decode a 1x2 mcu - * .---. - * | 1 | - * |---| - * | 2 | - * `---' - */ -static void decode_MCU_1x2_1plane(struct jdec_private *priv) -{ - // Y - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y, 8); - process_Huffman_data_unit(priv, cY); - IDCT(&priv->component_infos[cY], priv->Y+64, 8); - - // Cb - process_Huffman_data_unit(priv, cCb); - - // Cr - process_Huffman_data_unit(priv, cCr); -} - -static void print_SOF(const unsigned char *stream) -{ - int width, height, nr_components, precision; -#if DEBUG - const char *nr_components_to_string[] = { - "????", - "Grayscale", - "????", - "YCbCr", - "CYMK" - }; -#endif - - precision = stream[2]; - height = be16_to_cpu(stream+3); - width = be16_to_cpu(stream+5); - nr_components = stream[7]; - - trace("> SOF marker\n"); - trace("Size:%dx%d nr_components:%d (%s) precision:%d\n", - width, height, - nr_components, nr_components_to_string[nr_components], - precision); -} - -/******************************************************************************* - * - * JPEG/JFIF Parsing functions - * - * Note: only a small subset of the jpeg file format is supported. No markers, - * nor progressive stream is supported. - * - ******************************************************************************/ - -static void build_quantization_table(float *qtable, const unsigned char *ref_table) -{ - /* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct. - * For float AA&N IDCT method, divisors are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * We apply a further scale factor of 8. - * What's actually stored is 1/divisor so that the inner loop can - * use a multiplication rather than a division. - */ - int i, j; - static const double aanscalefactor[8] = { - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - }; - const unsigned char *zz = zigzag; - - for (i=0; i<8; i++) { - for (j=0; j<8; j++) { - *qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j]; - } - } - -} - -static int parse_DQT(struct jdec_private *priv, const unsigned char *stream) -{ - int qi; - float *table; - const unsigned char *dqt_block_end; - - trace("> DQT marker\n"); - dqt_block_end = stream + be16_to_cpu(stream); - stream += 2; /* Skip length */ - - while (stream < dqt_block_end) - { - qi = *stream++; -#if SANITY_CHECK - if (qi>>4) - error("16 bits quantization table is not supported\n"); - if (qi >= COMPONENTS) - error("No more than %d quantization tables supported (got %d)\n", - COMPONENTS, qi + 1); -#endif - table = priv->Q_tables[qi]; - build_quantization_table(table, stream); - stream += 64; - } - trace("< DQT marker\n"); - return 0; -} - -static int parse_SOF(struct jdec_private *priv, const unsigned char *stream) -{ - int i, width, height, nr_components, cid, sampling_factor; - int Q_table; - struct component *c; - - trace("> SOF marker\n"); - print_SOF(stream); - - height = be16_to_cpu(stream+3); - width = be16_to_cpu(stream+5); - nr_components = stream[7]; -#if SANITY_CHECK - if (stream[2] != 8) - error("Precision other than 8 is not supported\n"); - if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT) - error("Width and Height (%dx%d) seems suspicious\n", width, height); - if (nr_components != 3) - error("We only support YUV images\n"); - if (height%8) - error("Height need to be a multiple of 8 (current height is %d)\n", height); - if (width%16) - error("Width need to be a multiple of 16 (current Width is %d)\n", width); -#endif - stream += 8; - for (i=0; i<nr_components; i++) { - cid = *stream++; - sampling_factor = *stream++; - Q_table = *stream++; - c = &priv->component_infos[i]; -#if SANITY_CHECK - c->cid = cid; -#endif - c->Vfactor = sampling_factor&0xf; - c->Hfactor = sampling_factor>>4; - c->Q_table = priv->Q_tables[Q_table]; - trace("Component:%d factor:%dx%d Quantization table:%d\n", - cid, c->Hfactor, c->Hfactor, Q_table ); - - } - priv->width = width; - priv->height = height; - - trace("< SOF marker\n"); - - return 0; -} - -static int parse_SOS(struct jdec_private *priv, const unsigned char *stream) -{ - unsigned int i, cid, table; - unsigned int nr_components = stream[2]; - - trace("> SOS marker\n"); - -#if SANITY_CHECK - if (nr_components != 3) - error("We only support YCbCr image\n"); -#endif - - stream += 3; - for (i=0;i<nr_components;i++) { - cid = *stream++; - table = *stream++; -#if SANITY_CHECK - if ((table&0xf) >= HUFFMAN_TABLES) - error("We do not support more than %d AC Huffman table\n", - HUFFMAN_TABLES); - if ((table>>4) >= HUFFMAN_TABLES) - error("We do not support more than %d DC Huffman table\n", - HUFFMAN_TABLES); - if (cid != priv->component_infos[i].cid) - error("SOS cid order (%u:%u) isn't compatible with the SOF marker (%u:%u)\n", - i, cid, i, priv->component_infos[i].cid); - trace("ComponentId:%u tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4); -#endif - priv->component_infos[i].AC_table = &priv->HTAC[table&0xf]; - priv->component_infos[i].DC_table = &priv->HTDC[table>>4]; - } - priv->stream = stream+3; - - /* ITU-T T.81 (9/92) chapter E.1.3 clearly states that RSTm is to be set to 0 at the beginning of each scan */ - priv->last_rst_marker_seen = 0; - - trace("< SOS marker\n"); - - return 0; -} - -static int parse_DHT(struct jdec_private *priv, const unsigned char *stream) -{ - unsigned int count, i; - unsigned char huff_bits[17]; - int length, index; - - length = be16_to_cpu(stream) - 2; - stream += 2; /* Skip length */ - - trace("> DHT marker (length=%d)\n", length); - - while (length>0) { - index = *stream++; - - /* We need to calculate the number of bytes 'vals' will takes */ - huff_bits[0] = 0; - count = 0; - for (i=1; i<17; i++) { - huff_bits[i] = *stream++; - count += huff_bits[i]; - } -#if SANITY_CHECK - if (count > 1024) - error("No more than 1024 bytes is allowed to describe a huffman table\n"); - if ( (index &0xf) >= HUFFMAN_TABLES) - error("No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES); - trace("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf); - trace("Length of the table: %d\n", count); -#endif - - if (index & 0xf0 ) { - if (build_huffman_table(priv, huff_bits, stream, &priv->HTAC[index&0xf])) - return -1; - } else { - if (build_huffman_table(priv, huff_bits, stream, &priv->HTDC[index&0xf])) - return -1; - } - - length -= 1; - length -= 16; - length -= count; - stream += count; - } - trace("< DHT marker\n"); - return 0; -} - -static int parse_DRI(struct jdec_private *priv, const unsigned char *stream) -{ - unsigned int length; - - trace("> DRI marker\n"); - - length = be16_to_cpu(stream); - -#if SANITY_CHECK - if (length != 4) - error("Length of DRI marker need to be 4\n"); -#endif - - priv->restart_interval = be16_to_cpu(stream+2); - -#if DEBUG - trace("Restart interval = %d\n", priv->restart_interval); -#endif - - trace("< DRI marker\n"); - - return 0; -} - - - -static void resync(struct jdec_private *priv) -{ - int i; - - /* Init DC coefficients */ - for (i=0; i<COMPONENTS; i++) - priv->component_infos[i].previous_DC = 0; - - priv->reservoir = 0; - priv->nbits_in_reservoir = 0; - if (priv->restart_interval > 0) - priv->restarts_to_go = priv->restart_interval; - else - priv->restarts_to_go = -1; -} - -static int find_next_rst_marker(struct jdec_private *priv) -{ - int rst_marker_found = 0; - int marker; - const unsigned char *stream = priv->stream; - - /* Parse marker */ - while (!rst_marker_found) - { - while (*stream++ != 0xff) - { - if (stream >= priv->stream_end) - error("EOF while search for a RST marker.\n"); - } - /* Skip any padding ff byte (this is normal) */ - while (*stream == 0xff) - stream++; - - marker = *stream++; - if ((RST+priv->last_rst_marker_seen) == marker) - rst_marker_found = 1; - else if (marker >= RST && marker <= RST7) - error("Wrong Reset marker found, abording\n"); - else if (marker == EOI) - return 0; - } - - priv->stream = stream; - priv->last_rst_marker_seen++; - priv->last_rst_marker_seen &= 7; - - return 0; -} - -static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream) -{ - int chuck_len; - int marker; - int sof_marker_found = 0; - int dqt_marker_found = 0; - int sos_marker_found = 0; - int dht_marker_found = 0; - const unsigned char *next_chunck; - - /* Parse marker */ - while (!sos_marker_found) - { - if (*stream++ != 0xff) - goto bogus_jpeg_format; - /* Skip any padding ff byte (this is normal) */ - while (*stream == 0xff) - stream++; - - marker = *stream++; - chuck_len = be16_to_cpu(stream); - next_chunck = stream + chuck_len; - switch (marker) - { - case SOF: - if (parse_SOF(priv, stream) < 0) - return -1; - sof_marker_found = 1; - break; - case DQT: - if (parse_DQT(priv, stream) < 0) - return -1; - dqt_marker_found = 1; - break; - case SOS: - if (parse_SOS(priv, stream) < 0) - return -1; - sos_marker_found = 1; - break; - case DHT: - if (parse_DHT(priv, stream) < 0) - return -1; - dht_marker_found = 1; - break; - case DRI: - if (parse_DRI(priv, stream) < 0) - return -1; - break; - default: - trace("> Unknown marker %2.2x\n", marker); - break; - } - - stream = next_chunck; - } - - if ( !sof_marker_found || - (!dqt_marker_found && !(priv->flags & TINYJPEG_FLAGS_PIXART_JPEG))) - goto bogus_jpeg_format; - - if (priv->flags & TINYJPEG_FLAGS_PIXART_JPEG) { - if (!priv->default_huffman_table_initialized) { - build_quantization_table(priv->Q_tables[0], pixart_quantization[0]); - build_quantization_table(priv->Q_tables[1], pixart_quantization[1]); - } - - /* Pixart JPEG data starts with one unknown / unused byte */ - priv->stream++; - } - - if (!dht_marker_found) { - trace("No Huffman table loaded, using the default one\n"); - if (build_default_huffman_tables(priv)) - return -1; - } - -#ifdef SANITY_CHECK - if ( (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor) - || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor)) - error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n"); - if ( (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor) - || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor)) - error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n"); - if ( (priv->component_infos[cCb].Hfactor!=1) - || (priv->component_infos[cCr].Hfactor!=1) - || (priv->component_infos[cCb].Vfactor!=1) - || (priv->component_infos[cCr].Vfactor!=1)) - error("Sampling other than 1x1 for Cr and Cb is not supported\n"); -#endif - - return 0; -bogus_jpeg_format: - error("Bogus jpeg format\n"); - return -1; -} - -/******************************************************************************* - * - * Functions exported of the library. - * - * Note: Some applications can access directly to internal pointer of the - * structure. It's is not recommended, but if you have many images to - * uncompress with the same parameters, some functions can be called to speedup - * the decoding. - * - ******************************************************************************/ - -/** - * Allocate a new tinyjpeg decoder object. - * - * Before calling any other functions, an object need to be called. - */ -struct jdec_private *tinyjpeg_init(void) -{ - struct jdec_private *priv; - - priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private)); - if (priv == NULL) - return NULL; - return priv; -} - -/** - * Free a tinyjpeg object. - * - * No others function can be called after this one. - */ -void tinyjpeg_free(struct jdec_private *priv) -{ - int i; - for (i=0; i<COMPONENTS; i++) { - if (priv->components[i]) - free(priv->components[i]); - priv->components[i] = NULL; - } - free(priv); -} - -/** - * Initialize the tinyjpeg object and prepare the decoding of the stream. - * - * Check if the jpeg can be decoded with this jpeg decoder. - * Fill some table used for preprocessing. - */ -int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size) -{ - int ret; - - /* Identify the file */ - if ((buf[0] != 0xFF) || (buf[1] != SOI)) - error("Not a JPG file ?\n"); - - priv->stream_begin = buf+2; - priv->stream_length = size-2; - priv->stream_end = priv->stream_begin + priv->stream_length; - - ret = parse_JFIF(priv, priv->stream_begin); - - return ret; -} - -static const decode_MCU_fct decode_mcu_3comp_table[4] = { - decode_MCU_1x1_3planes, - decode_MCU_1x2_3planes, - decode_MCU_2x1_3planes, - decode_MCU_2x2_3planes, -}; - -static const decode_MCU_fct pixart_decode_mcu_3comp_table[4] = { - NULL, - NULL, - pixart_decode_MCU_2x1_3planes, - NULL, -}; - -static const decode_MCU_fct decode_mcu_1comp_table[4] = { - decode_MCU_1x1_1plane, - decode_MCU_1x2_1plane, - decode_MCU_2x1_1plane, - decode_MCU_2x2_1plane, -}; - -static const convert_colorspace_fct convert_colorspace_yuv420p[4] = { - YCrCB_to_YUV420P_1x1, - YCrCB_to_YUV420P_1x2, - YCrCB_to_YUV420P_2x1, - YCrCB_to_YUV420P_2x2, -}; - -static const convert_colorspace_fct convert_colorspace_rgb24[4] = { - YCrCB_to_RGB24_1x1, - YCrCB_to_RGB24_1x2, - YCrCB_to_RGB24_2x1, - YCrCB_to_RGB24_2x2, -}; - -static const convert_colorspace_fct convert_colorspace_bgr24[4] = { - YCrCB_to_BGR24_1x1, - YCrCB_to_BGR24_1x2, - YCrCB_to_BGR24_2x1, - YCrCB_to_BGR24_2x2, -}; - -static const convert_colorspace_fct convert_colorspace_grey[4] = { - YCrCB_to_Grey_1x1, - YCrCB_to_Grey_1x2, - YCrCB_to_Grey_2x1, - YCrCB_to_Grey_2x2, -}; - -/** - * Decode and convert the jpeg image into @pixfmt@ image - * - * Note: components will be automaticaly allocated if no memory is attached. - */ -int tinyjpeg_decode(struct jdec_private *priv, int pixfmt) -{ - unsigned int x, y, xstride_by_mcu, ystride_by_mcu; - unsigned int bytes_per_blocklines[3], bytes_per_mcu[3]; - decode_MCU_fct decode_MCU; - const decode_MCU_fct *decode_mcu_table; - const convert_colorspace_fct *colorspace_array_conv; - convert_colorspace_fct convert_to_pixfmt; - - if (setjmp(priv->jump_state)) - return -1; - - /* To keep gcc happy initialize some array */ - bytes_per_mcu[1] = 0; - bytes_per_mcu[2] = 0; - bytes_per_blocklines[1] = 0; - bytes_per_blocklines[2] = 0; - - decode_mcu_table = decode_mcu_3comp_table; - if (priv->flags & TINYJPEG_FLAGS_PIXART_JPEG) - decode_mcu_table = pixart_decode_mcu_3comp_table; - - switch (pixfmt) { - case TINYJPEG_FMT_YUV420P: - colorspace_array_conv = convert_colorspace_yuv420p; - if (priv->components[0] == NULL) - priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); - if (priv->components[1] == NULL) - priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4); - if (priv->components[2] == NULL) - priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4); - bytes_per_blocklines[0] = priv->width; - bytes_per_blocklines[1] = priv->width/4; - bytes_per_blocklines[2] = priv->width/4; - bytes_per_mcu[0] = 8; - bytes_per_mcu[1] = 4; - bytes_per_mcu[2] = 4; - break; - - case TINYJPEG_FMT_RGB24: - colorspace_array_conv = convert_colorspace_rgb24; - if (priv->components[0] == NULL) - priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); - bytes_per_blocklines[0] = priv->width * 3; - bytes_per_mcu[0] = 3*8; - break; - - case TINYJPEG_FMT_BGR24: - colorspace_array_conv = convert_colorspace_bgr24; - if (priv->components[0] == NULL) - priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3); - bytes_per_blocklines[0] = priv->width * 3; - bytes_per_mcu[0] = 3*8; - break; - - case TINYJPEG_FMT_GREY: - decode_mcu_table = decode_mcu_1comp_table; - if (priv->flags & TINYJPEG_FLAGS_PIXART_JPEG) - error("Greyscale output not support for PIXART JPEG's\n"); - colorspace_array_conv = convert_colorspace_grey; - if (priv->components[0] == NULL) - priv->components[0] = (uint8_t *)malloc(priv->width * priv->height); - bytes_per_blocklines[0] = priv->width; - bytes_per_mcu[0] = 8; - break; - - default: - error("Bad pixel format\n"); - } - - xstride_by_mcu = ystride_by_mcu = 8; - if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) { - decode_MCU = decode_mcu_table[0]; - convert_to_pixfmt = colorspace_array_conv[0]; - trace("Use decode 1x1 sampling\n"); - } else if (priv->component_infos[cY].Hfactor == 1) { - decode_MCU = decode_mcu_table[1]; - convert_to_pixfmt = colorspace_array_conv[1]; - ystride_by_mcu = 16; - trace("Use decode 1x2 sampling (not supported)\n"); - } else if (priv->component_infos[cY].Vfactor == 2) { - decode_MCU = decode_mcu_table[3]; - convert_to_pixfmt = colorspace_array_conv[3]; - xstride_by_mcu = 16; - ystride_by_mcu = 16; - trace("Use decode 2x2 sampling\n"); - } else { - decode_MCU = decode_mcu_table[2]; - convert_to_pixfmt = colorspace_array_conv[2]; - xstride_by_mcu = 16; - trace("Use decode 2x1 sampling\n"); - } - - if (decode_MCU == NULL) - error("no decode MCU function for this JPEG format (PIXART?)\n"); - - resync(priv); - - /* Don't forget to that block can be either 8 or 16 lines */ - bytes_per_blocklines[0] *= ystride_by_mcu; - bytes_per_blocklines[1] *= ystride_by_mcu; - bytes_per_blocklines[2] *= ystride_by_mcu; - - bytes_per_mcu[0] *= xstride_by_mcu/8; - bytes_per_mcu[1] *= xstride_by_mcu/8; - bytes_per_mcu[2] *= xstride_by_mcu/8; - - /* Just the decode the image by macroblock (size is 8x8, 8x16, or 16x16) */ - for (y=0; y < priv->height/ystride_by_mcu; y++) - { - //trace("Decoding row %d\n", y); - priv->plane[0] = priv->components[0] + (y * bytes_per_blocklines[0]); - priv->plane[1] = priv->components[1] + (y * bytes_per_blocklines[1]); - priv->plane[2] = priv->components[2] + (y * bytes_per_blocklines[2]); - for (x=0; x < priv->width; x+=xstride_by_mcu) - { - decode_MCU(priv); - convert_to_pixfmt(priv); - priv->plane[0] += bytes_per_mcu[0]; - priv->plane[1] += bytes_per_mcu[1]; - priv->plane[2] += bytes_per_mcu[2]; - if (priv->restarts_to_go>0) - { - priv->restarts_to_go--; - if (priv->restarts_to_go == 0) - { - priv->stream -= (priv->nbits_in_reservoir/8); - resync(priv); - if (find_next_rst_marker(priv) < 0) - return -1; - } - } - } - } - - if (priv->flags & TINYJPEG_FLAGS_PIXART_JPEG) { - /* Additional sanity check for funky Pixart format */ - if ((priv->stream_end - priv->stream) > 5) - error("Pixart JPEG error, stream does not end with EOF marker\n"); - } - - return 0; -} - -const char *tinyjpeg_get_errorstring(struct jdec_private *priv) -{ - return priv->error_string; -} - -void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height) -{ - *width = priv->width; - *height = priv->height; -} - -int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components) -{ - int i; - for (i=0; priv->components[i] && i<COMPONENTS; i++) - components[i] = priv->components[i]; - return 0; -} - -int tinyjpeg_set_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents) -{ - unsigned int i; - if (ncomponents > COMPONENTS) - ncomponents = COMPONENTS; - for (i=0; i<ncomponents; i++) - priv->components[i] = components[i]; - return 0; -} - -int tinyjpeg_set_flags(struct jdec_private *priv, int flags) -{ - int oldflags = priv->flags; - priv->flags = flags; - return oldflags; -} - diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h b/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h deleted file mode 100644 index b0096f0de..000000000 --- a/v4l2-apps/lib/libv4l/libv4lconvert/tinyjpeg.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Small jpeg decoder library (header file) - * - * Copyright (c) 2006, Luc Saillard <luc@saillard.org> - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the author nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - - -#ifndef __JPEGDEC_H__ -#define __JPEGDEC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct jdec_private; - -/* Flags that can be set by any applications */ -#define TINYJPEG_FLAGS_MJPEG_TABLE (1<<1) -#define TINYJPEG_FLAGS_PIXART_JPEG (1<<2) - -/* Format accepted in outout */ -enum tinyjpeg_fmt { - TINYJPEG_FMT_GREY = 1, - TINYJPEG_FMT_BGR24, - TINYJPEG_FMT_RGB24, - TINYJPEG_FMT_YUV420P, -}; - -struct jdec_private *tinyjpeg_init(void); -void tinyjpeg_free(struct jdec_private *priv); - -int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size); -int tinyjpeg_decode(struct jdec_private *priv, int pixel_format); -const char *tinyjpeg_get_errorstring(struct jdec_private *priv); -void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height); -int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components); -int tinyjpeg_set_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents); -int tinyjpeg_set_flags(struct jdec_private *priv, int flags); - -#ifdef __cplusplus -} -#endif - -#endif - - - |