diff -uprN libv4lconvert-old/Makefile libv4lconvert-new/Makefile
--- libv4lconvert-old/Makefile	2009-03-01 15:37:38.000000000 -0600
+++ libv4lconvert-new/Makefile	2009-03-04 16:22:52.000000000 -0600
@@ -12,7 +12,7 @@ endif

  CONVERT_OBJS  = libv4lconvert.o tinyjpeg.o sn9c10x.o sn9c20x.o pac207.o \
  		mr97310a.o flip.o crop.o jidctflt.o spca561-decompress.o \
-		rgbyuv.o spca501.o bayer.o
+		rgbyuv.o spca501.o sq905c.o bayer.o
  TARGETS       = $(CONVERT_LIB) libv4lconvert.pc
  INCLUDES      = ../include/libv4lconvert.h

diff -uprN libv4lconvert-old/libv4lconvert-priv.h libv4lconvert-new/libv4lconvert-priv.h
--- libv4lconvert-old/libv4lconvert-priv.h	2009-03-01 15:37:38.000000000 -0600
+++ libv4lconvert-new/libv4lconvert-priv.h	2009-03-04 16:22:52.000000000 -0600
@@ -47,6 +47,10 @@
  #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M','3','1','0')
  #endif

+#ifndef V4L2_PIX_FMT_SQ905C
+#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C')
+#endif
+
  #ifndef V4L2_PIX_FMT_PJPG
  #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G')
  #endif
@@ -180,6 +184,9 @@ void v4lconvert_decode_pac207(const unsi
  void v4lconvert_decode_mr97310a(const unsigned char *src, unsigned char *dst,
    int width, int height);

+void v4lconvert_decode_sq905c(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);

diff -uprN libv4lconvert-old/libv4lconvert.c libv4lconvert-new/libv4lconvert.c
--- libv4lconvert-old/libv4lconvert.c	2009-03-01 15:37:38.000000000 -0600
+++ libv4lconvert-new/libv4lconvert.c	2009-03-04 16:22:52.000000000 -0600
@@ -61,6 +61,7 @@ static const struct v4lconvert_pixfmt su
    { V4L2_PIX_FMT_SN9C10X,      V4LCONVERT_COMPRESSED },
    { V4L2_PIX_FMT_PAC207,       V4LCONVERT_COMPRESSED },
    { V4L2_PIX_FMT_MR97310A,     V4LCONVERT_COMPRESSED },
+  { V4L2_PIX_FMT_SQ905C,       V4LCONVERT_COMPRESSED },
    { V4L2_PIX_FMT_PJPG,         V4LCONVERT_COMPRESSED },
  };

@@ -608,6 +609,7 @@ static int v4lconvert_convert_pixfmt(str
      case V4L2_PIX_FMT_SN9C10X:
      case V4L2_PIX_FMT_PAC207:
      case V4L2_PIX_FMT_MR97310A:
+    case V4L2_PIX_FMT_SQ905C:
      {
        unsigned char *tmpbuf;

@@ -633,6 +635,10 @@ static int v4lconvert_convert_pixfmt(str
  	  v4lconvert_decode_mr97310a(src, tmpbuf, width, height);
  	  src_pix_fmt = V4L2_PIX_FMT_SBGGR8;
  	  break;
+	case V4L2_PIX_FMT_SQ905C:
+	  v4lconvert_decode_sq905c(src, tmpbuf, width, height);
+	  src_pix_fmt = V4L2_PIX_FMT_SRGGB8;
+	  break;
        }
        src = tmpbuf;
        /* Deliberate fall through to raw bayer fmt code! */
diff -uprN libv4lconvert-old/sq905c.c libv4lconvert-new/sq905c.c
--- libv4lconvert-old/sq905c.c	1969-12-31 18:00:00.000000000 -0600
+++ libv4lconvert-new/sq905c.c	2009-03-04 16:27:17.000000000 -0600
@@ -0,0 +1,217 @@
+/*
+ * sq905c.c
+ *
+ * Here is the decompression function for the SQ905C cameras. The functions
+ * used are adapted from the libgphoto2 functions for the same cameras,
+ * which was
+ * Copyright (c) 2005 and 2007 Theodore Kilgore <kilgota@auburn.edu>
+ * This version for libv4lconvert is
+ * Copyright (c) 2009 Theodore Kilgore <kilgota@auburn.edu>
+ *
+ * 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 <stdlib.h>
+
+#include "libv4lconvert-priv.h"
+
+
+#define CLIP(x) ((x) < 0 ? 0 : ((x) > 0xff) ? 0xff : (x))
+
+
+static int
+sq905c_first_decompress(unsigned char *output, unsigned char *input,
+					    unsigned int outputsize)
+{
+	unsigned char parity = 0;
+	unsigned char nibble_to_keep[2];
+	unsigned char temp1 = 0, temp2 = 0;
+	unsigned char input_byte;
+	unsigned char lookup = 0;
+	unsigned int i = 0;
+	unsigned int bytes_used = 0;
+	unsigned int bytes_done = 0;
+	unsigned int bit_counter = 8;
+	unsigned int cycles = 0;
+	int table[9] = { -1, 0, 2, 6, 0x0e, 0x0e, 0x0e, 0x0e, 0xfb};
+	unsigned char lookup_table[16]
+		     = {0, 2, 6, 0x0e, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
+			0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb};
+	unsigned char translator[16] = {8, 7, 9, 6, 10, 11, 12, 13,
+					14, 15, 5, 4, 3, 2, 1, 0};
+
+	nibble_to_keep[0] = 0;
+	nibble_to_keep[1] = 0;
+
+	while (bytes_done < outputsize) {
+		while (parity < 2) {
+			while (lookup > table[cycles]) {
+				if (bit_counter == 8) {
+					input_byte = input[bytes_used];
+					bytes_used++;
+					temp1 = input_byte;
+					bit_counter = 0;
+				}
+				input_byte = temp1;
+				temp2 = (temp2 << 1) & 0xFF;
+				input_byte = input_byte >> 7;
+				temp2 = temp2 | input_byte;
+				temp1 = (temp1 << 1) & 0xFF;
+				bit_counter++;
+				cycles++;
+				if (cycles > 9)
+					return -1;
+				lookup = temp2 & 0xff;
+			}
+			temp2 = 0;
+			for (i = 0; i < 17; i++) {
+				if (lookup == lookup_table[i]) {
+					nibble_to_keep[parity] = translator[i];
+					break;
+				}
+				if (i == 16)
+					return -1;
+			}
+			cycles = 0;
+			parity++;
+		}
+		output[bytes_done] = (nibble_to_keep[0]<<4)|nibble_to_keep[1];
+		bytes_done++;
+		parity = 0;
+	}
+	return 0;
+}
+
+static int
+sq905c_second_decompress(unsigned char *uncomp, unsigned char *in,
+						    int width, int height)
+{
+	int diff = 0;
+	int tempval = 0;
+	int i, m, parity;
+	unsigned char delta_left = 0;
+	unsigned char delta_right = 0;
+	int input_counter = 0;
+	int delta_table[] = {-144, -110, -77, -53, -35, -21, -11, -3,
+				2, 10, 20, 34, 52, 76, 110, 144};
+	unsigned char *templine_red;
+	unsigned char *templine_green;
+	unsigned char *templine_blue;
+	templine_red = malloc(width);
+	if (!templine_red) {
+		free(templine_red);
+		return -1;
+	}
+	for (i = 0; i < width; i++)
+		templine_red[i] = 0x80;
+	templine_green = malloc(width);
+	if (!templine_green) {
+		free(templine_green);
+		return -1;
+	}
+	for (i = 0; i < width; i++)
+		templine_green[i] = 0x80;
+	templine_blue = malloc(width);
+	if (!templine_blue) {
+		free(templine_blue);
+		return -1;
+	}
+	for (i = 0; i < width; i++)
+		templine_blue[i] = 0x80;
+	for (m = 0; m < height/2; m++) {
+		/* First we do an even-numbered line */
+		for (i = 0; i < width/2; i++) {
+			parity = i&1;
+			delta_right = in[input_counter] & 0x0f;
+			delta_left = (in[input_counter]>>4)&0xff;
+			input_counter++;
+			/* left pixel (red) */
+			diff = delta_table[delta_left];
+			if (!i)
+				tempval = templine_red[0] + diff;
+			else
+				tempval = (templine_red[i]
+					+ uncomp[2*m*width+2*i-2])/2 + diff;
+			tempval = CLIP(tempval);
+			uncomp[2*m*width+2*i] = tempval;
+			templine_red[i] = tempval;
+			/* right pixel (green) */
+			diff = delta_table[delta_right];
+			if (!i)
+				tempval = templine_green[1] + diff;
+			else if (2*i == width - 2)
+				tempval = (templine_green[i]
+						+ uncomp[2*m*width+2*i-1])/2
+							+ diff;
+			else
+				tempval = (templine_green[i+1]
+						+ uncomp[2*m*width+2*i-1])/2
+							+ diff;
+			tempval = CLIP(tempval);
+			uncomp[2*m*width+2*i+1] = tempval;
+			templine_green[i] = tempval;
+		}
+		/* then an odd-numbered line */
+		for (i = 0; i < width/2; i++) {
+			delta_right = in[input_counter] & 0x0f;
+			delta_left = (in[input_counter]>>4) & 0xff;
+			input_counter++;
+			/* left pixel (green) */
+			diff = delta_table[delta_left];
+			if (!i)
+				tempval = templine_green[0] + diff;
+			else
+				tempval = (templine_green[i]
+					+ uncomp[(2*m+1)*width+2*i-2])/2
+						+ diff;
+			tempval = CLIP(tempval);
+			uncomp[(2*m+1)*width+2*i] = tempval;
+			templine_green[i] = tempval;
+			/* right pixel (blue) */
+			diff = delta_table[delta_right];
+			if (!i)
+				tempval = templine_blue[0] + diff;
+			else
+				tempval = (templine_blue[i]
+					    + uncomp[(2*m+1)*width+2*i-1])/2
+						+ diff;
+			tempval = CLIP(tempval);
+			uncomp[(2*m+1)*width+2*i+1] = tempval;
+			templine_blue[i] = tempval;
+		}
+	}
+	free(templine_green);
+	free(templine_red);
+	free(templine_blue);
+	return 0;
+}
+
+void v4lconvert_decode_sq905c(const unsigned char *src, unsigned char *dst,
+  int width, int height)
+{
+	int size;
+	unsigned char *temp_data;
+	unsigned char *raw;
+	/* here we get rid of the 0x50 bytes of header in src. */
+	raw = src + 0x50;
+	size = width*height/2;
+	temp_data = malloc(size);
+	if (!temp_data)
+		goto out;
+	sq905c_first_decompress(temp_data, raw, size);
+	sq905c_second_decompress(dst, temp_data, width, height);
+out:
+	free(temp_data);
+}
