/* README for libgphoto2/camlibs/sonix camera library
*
* Copyright (C) 2005 Theodore Kilgore <kilgota@auburn.edu>
*
* 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 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.
*/
This library is intended to support the stillcam functions of the Vivivar
Vivicam 3350B and similar cameras which use the sn9c2028 chip from Sonix.
The 3350B uses an OV7630 sensor and produces a maximum
resolution of 640x480 and an option to use 320x240. The photos are all
compressed. The compression scheme is lossy and seems to be a variation on
RLE. The decompression algorithm originates, I understand, in the work of
Bertrik Sikkens for the sn9c102 cameras. In the macam project for
MacOS-X camera support(webcam-osx project on sourceforge), the
decompression algorithm for the sn9c2028 cameras was developed by Mattias
Krauss and adapted for use with the Vivitar Vivicam 3350B in particular
by Harald Ruda <hrx at users.sourceforge.net>, who also brought their work
to my attention.
Features of the camera include the ability to delete all photos. A "delete last"
function and a "capture" function also exist in the macam driver, but neither
seems to work when tested with my Vivicam 3350B. They may work with other
sn9c2028 cameras, and if so will be included here in the future.
Another camera which the macam driver also supports has been listed here as a
supported camera. It apparently uses 352x288 and 176x144 resolution settings.
I have not personally tested it and would appreciate any
reports about it, as well as any other cameras which seem to have the same
chip. These cameras also can act as pccam or webcam and use isochronous
transfer to do that. Support for this feature in Linux requires a kernel
module. That is a possible future project, but the requirement for direct
kernel support precludes supporting the webcam function here.
The following remarks come from some notes in the macam source code, which is
licensed under the GPL. I thank the webcam-osx developers for their help and
cooperation. The section about the Vivicam 3350B was written by Harald.
(quotation begins)
The video in the data stream is a GRBG-Bayer pattern (compressed by some sort
of run-length encoding and Huffman compression). The data stream format is
as follows:
<frame 1 header>
<line 1 header>
<pixel 1 bitcode>
<pixel 2 bitcode>
...
<pixel x bitcode>
<line 2 header>
...
<line y header>
<padding bits>
<frame 2 header>
...
The frame header is 12 bytes long
(0xff 0xff 0x00 0xc4 0xc4 0x96
0x00 0x<*1> 0x<*2> 0x<*3> 0x<*4> 0x<*5>). <*1> seems to be a frame counter
(bits 6 and 7) and a size indicator
(bits 1 and 2: 00=VGA, 01=SIF, 10=QSIF) Bit 0 seems to be always 1,
4 and 5 seem to be always 0. Bit 3 is often 0 (but not always).
<*2> to <*5>'s meanings are probably some sort of brightness summary/average.
After that, the video lines follow. Each line starts with a 16-bit line
header with two 8-bit starting values - since it's a Bayer pattern, there
are two color components alternating in each line. Both components are
tracked individually and independently (just alternating).
After the line header, the actual pixels follow. The line lengths don't match
exactly their named formats - for example, VGA mode seems to have only 638
Pixels in a row. For each pixel, there's a code in the stream that describes
the next component value. It can either be described as a change from the
last value of that component or as a direct value. These codes are not bound
to bytes - it's a pure bitstream. Codes have different lengths, according to
their likeliness. The algorithm is similar to Huffman compression, the main
differences are
) the two modes,
b) the bit codes seem to be handmade,
c) there's some redundancy because of the two description modes
and
d) not all possible values exist - therefore, the values had to be quantized
(i.e. this compression algorithm is lossy). The codes are as follows
(they are not completely correct, I have to figure out a better way to
decipher this, but they basically work):
*/
/*
0 : 0 (leave as is)
1000 : +8
1001 : -8
101 : +3
110 : -3
11100 : +18
11101xxxxx : =8*(xxxxx)+4 (these values seem
to be unprecise - especially for low values)
1111 : -18
*/
/*
ViviCam 3350B additions
=======================
This uses the OV7630 imaging chip, which has a BGGR bayer matrix
The code sent is almost exactly the same as above, except:
- need to skip 20 bytes, not 12 when decoding
- rows do indeed contain the full amount of pixels
(the first two are actually the first two!)
- the bit-stream decoding is almost the same, these work very well,
and are absolutely correct
11100 : +20
11101xxxxx : =8*(xxxxx)+0
1111 : -20
Some of these changes may also apply to the original (Sonix2028) driver,
but without a way to test changes, they will be left alone.
(end quotation)
Apparently, the Mac deals with downloads from the camera in a slightly
different manner. I found it necessary here to skip only 8 bytes, as the
"first 12 bytes" simply do not comprise part of the data. Otherwise, the
decompression algorithm used here is slightly simplified from what is used in
the macam driver, but is essentially identical. It seems to work perfectly,
except that brightness and/or gamma need sometimes to be adjusted, especially
for photos taken in dim light.