History of the reverse engineering of the compression used in the
	JL2005B, JL2005C, and JL2005D cameras
-----------------------------------------------------------

All of these cameras use a compression format which is derived from JPEG
but is in several respects non-standard, making the job of understanding
it very difficult.

Thus, after several years have passed by, during which it has been possible
to get the raw files out of these cameras but not possible to do anything
with the data in the raw files, a task force was started to deal with the
problem. The results of the reverse engineering work by Adam Rubin and
Bertrik Sikken were shared by means of a wiki page with Hans de Goede
and me (Theodore Kilgore). What is known as of April 10, 2010 is listed
at

<http://sourceforge.net/apps/mediawiki/gphoto/index.php?title=ImageEncoding
Jeilin2005CD>

A dump of this page is given below.

The description provided in this webpage was used to write the decompression
code. The objective was to provide output in a standard, uncompressed bitmap
format in order to provide the opportunity to apply whatever techniques for
image enhancement or postprocessing that might be needed. The format chosen
for this was PPM, used in many other camera libraries in libgphoto2.

Faced with the choice of incorporating a modified variant of libjpeg in
the decompression code, for ultimate inclusion in libgphoto2/camlibs/jl2005c,
or else finding a way to use the standard library functions of libjpeg,
Hans de Goede found a way to use the standard library functions with minimal
modification.

The details of how the decompression algorithm needs to work are well laid
out in the dump of the wiki web page (below). See especially the section
called "Entropy coded data."

A modified version of the file jpeg_memsrcdest.c is part of the
decompression package here. The copyright notice of the original file is
preserved inside the file, and it is also copied here:

/*
 * jpeg_memsrcdest.c and 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.
 */


Below is a dump of:
<http://sourceforge.net/apps/mediawiki/gphoto/index.php?title=ImageEncoding
Jeilin2005CD>
Made on 28 April 2010.

ImageEncodingJeilin2005CD
From gphoto
Jump to: navigation, search
Contents

    * 1 Introduction
    * 2 Photo Allocation Table
    * 3 Image format
          o 3.1 Image header
          o 3.2 Thumbnail image
          o 3.3 Entropy coded data
                + 3.3.1 Huffman table
                + 3.3.2 Quantisation table

Introduction

This page describes the image format used in cameras with the Jeilin JL2005B / JL2005C / JL2005D chip.

This chip stores images in a non-standard JPEG-like format. To understand the information on this page, it is recommended to have a basic understanding of JPEG compression.
Photo Allocation Table

At the start of the camera's accessible RAM is the PAT (photo allocation table), 0x30 bytes of data (not included in image headers), immediately followed by the 16-byte image headers for all the photos in consecutive order.

A few bytes of the data at the start of the PAT table are of interest. All word values are big-endian.

    * 0x00-0x06 -- "JL2005B" or "JL2005C" or "JL2005D", whichever chip this camera has.
    * 0x07 -- bit flags; apparently bit 2 is set if this camera supports thumbnails, and cleared if it doesn't; sometimes bits 0 and/or 1 are set, purposes unknown; all other bits always observed as zero so far
    * 0x08-0x09 -- first writeable block in camera's RAM (see "Image Header" below for block sizes)
    * 0x0a-0x0b -- first unused block after image data (where next photo taken would start)
    * 0x0c-0x0d -- word containing number of images in the camera, counting each frame within a clip as one. This many 16-byte image headers should be read from the PAT table starting at offset 0x30; any headers beyond this should be ignored.
    * 0x0e-0x0f -- number of free blocks remaining in camera's RAM 

Other bytes may be added as discovered.
Image format

The raw image file seems to consist of the following parts:

    * a 16-byte image header
    * some kind of thumbnail of the actual image
    * entropy-coded JPEG-like image data 

These parts are described in the following paragraphs.
Image header

The 16-byte image header is the very first thing in a raw image file (copied directly from the PAT, except where specifically noted) and contains basic image meta-data. All words are stored big-endian, and block size is 0x80 bytes for the JL2005B and 0x200 bytes for the JL2005C and JL2005D chips. "Significant" means that the value of the bit, byte, or word indicates or is used for something, but I don't (yet) know what that is, and what the effects of it are, if any. I suspect some of those values may not affect anything.

Definitions, as I understand them (corrections welcome!):

    * Still mode - Camera takes one photo when shutter button is pressed
    * Burst mode - Camera takes a sequence (a constant small number, usually 3) of still photos when shutter button is pressed once, meant to be viewed as separate images
    * Continuous mode - Camera continues rapidly (several fps) taking photos until told to stop (or memory is full); result is meant to be viewed as a video clip, e.g. AVI format. The camera may temporarily use a lower resolution and different compression ratio during this. 


Byte(s) Meaning
0x00 0x00: standard still image

0x01: intermediate photo from continuous mode

0x02: photo taken in burst mode

0x11: first image from continuous mode

0x21: last image from continuous mode

Anything else: unknown

The OEM driver processes 0x11 as a special case, 0x01 and 0x21 as if they were 0x01, and anything else (including 0x02) as if it were 0x00.
0x01 Attributes: If bit 4 is set, gamma correction is enabled. All other bits are unknown, although usually some are set. Bits 2-3 and 7 are significant.
0x02 

Bits 0-1: resolution of this photo (camera-dependent), 00 = CIF or VGA, 01 = QCIF or QVGA. If supported, 02 = SVGA, 03 = even larger than SVGA

Bits 4-5: 00 = lower compression ratio, 01 = higher compression ratio, 10 = compression for continuous mode

All other bits have always been observed as zero so far.
0x03 Bits 0-6: image quality factor (0x64 = 100% is best quality), specifics below under "Quantization Table"

Bit 7: if set, read the raw file into memory but do not decode it. (For manufacturer or developer testing?)
0x04 Image height, in units of 8 pixels
0x05 Image width, in units of 8 pixels
0x06-0x07 Total size of image data in blocks, including thumbnail if any
0x08 When writing the raw file, if byte 0x03 bit 7 is set (don't decode image) and byte 0x02 bit 4 is set (higher compression ratio), then a workspace area of ( width * (photo height in pixels - this byte) / 2 ) bytes is temporarily allocated, instead of width * height.

When reading in the raw file, if byte 0x03 bit 7 is set and byte 0x02 bit 4 is set, the value used by the OEM driver for image height in pixels follows the same equation.

I don't (yet) know why either of these are done. (For manufacturer or developer testing?)
0x09 Bits 0-1: see description of header byte 0x0b, below.

Bits 2-7: If the camera supports thumbnail images (PAT+07 bit 2 set), the thumbnail's length in blocks is this 6-bit value. So far, a 6-bit value of 0x18 or 0x3c (i.e. byte value 0x6n or 0xfn where n <= 3) in these bits means a thumbnail (resolution 96x64 or 128x120 pixels respectively), and 0x00 means no thumbnail. The meaning of any other value is not certain, but probably means "no thumbnail". Thumbnail encoding is described below.
0x0a Attributes, apparently constant for any particular camera. Bits 0-1 are significant.
0x0b Zero if still mode or burst mode. For continuous mode (indicated by byte 0x00 of header), the first image has the total number of images in this video clip in this byte, and successive images in this clip are numbered consecutively in this byte, from 1 to (# images - 1). This is actually a ten-bit value; bits 0 and 1 of header byte 0x09 are bits 8 and 9 of it respectively. That gives it a maximum value of 0x3ff (1023 decimal). That's the latest conjecture, anyway.

Note: Some cameras (including all using the JL2005B) that have a continuous mode do NOT use this byte and leave it at zero. The start and end of clips can still be detected by header byte 0x00.
0x0c-0x0d Starting address of this image in camera's RAM, in blocks.
0x0e-0x0f Word value, big-endian, significant, function unknown so far. Could be data, a pointer, or a checksum of some sort.

(part of this table was derived from the jl2005c code already in gphoto)
Thumbnail image

Directly following the image header, sometimes, is a thumbnail image. See "Image Header" byte 0x09, above, to detect whether one is present.

From observation:

    * JL2005B -- no thumbnails
    * JL2005C -- some have thumbnails; if so, 96x64 pixels
    * JL2005D -- many have thumbnails; if so, 128x120 pixels 

Note that the aspect ratio of the thumbnails is not necessarily the same as that of the picture.

Pixels in the thumbnail are encoded left-to-right, top-to-bottom. Each pixel of the thumbnail image is represented by a 16-bit word, big endian encoded, with bits assigned to R, G and B components as follows (a.k.a. RGB565):

    * bit 15-11: red
    * bit 10- 5: green
    * bit 4 - 0: blue 

All of these are the most significant 5 or 6 bits for that color, with the unused low-order bits set to zero.
Entropy coded data

Following the thumbnail image (if present), is the entropy coded data. This data looks a bit like the entropy coded data used in JPEG images.

The image is sub-divided as follows:

    * The image is divided in vertical strips of 16 pixels wide and height pixels high, so the whole image consists of width/16 strips, encoded from left-to-right.
    * Each strip is subdivided in MCUs (minimum coded unit) of 16x16 pixels, encoded from top to bottom.
    * Each MCU consists of 4 blocks of 8x8 pixels each, containing pixels from the Bayer mosaicing pattern. They appear in the following order:
          o First the green pixels of the top half of the 16x16 pixel MCU
          o Then the green pixels of the bottom half of the 16x16 pixel MCU
          o Then the red pixels for the entire MCU
          o Finally the blue pixels for the entire MCU 
    * The order of the red, green and blue pixels in the Bayer pattern is as follows: RG/GB. This means the first line of a MCU starts with a red pixel, then a green pixel from the first green line from the first green block. The second line starts with a green pixel from the second green line from the first green block, then a blue pixel. 

With respect to the encoding:

    * MCUs in a strip are encoded like a JPEG MCU. There are only two Huffman tables (one for the DC and one for the AC coefficients) and there is only one quantisation table.
    * The blue and red 8x8 blocks inside an MCU each have a DC coefficient that is differential to the DC coefficient of the same block in the previous MCU, like a standard JPEG.
    * The two green 8x8 blocks inside an MCU share a single DC coefficient, so the DC coefficient of the first green block is differential to the one from the second block and vice versa.
    * The DC coefficients in the first MCU in a strip are not differential, but contain the absolute value.
    * 0xFF bytes in the entropy coded data are followed by 0x00 stuff-bytes, just like JPEG.
    * A strip is encoded as a bunch of MCUs, followed by 0xFFD9 (this is the End-Of-Image marker in JPEG) and padded with 0x00 until the next 16-byte aligned address. The start of the entropy coded stream is considered to be address 0 in this case.
    * An image is encoded as a bunch of strips, followed by bogus data until the end of the total image data (which is a multiple of the block size, 0x80 or 0x200 bytes). 

Huffman table

The Huffman table used is the recommended table for the luminance component from the JPEG specification. In C, encoded as a JPEG DHT table, this looks like:

static const unsigned char dht_table[] = {
0xFF, 0xC4,
0x00, 0xD2

// luma DC
0x00,
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,

// luma AC
0x10,
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D,
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
};

Quantisation table

The magnitude of the elements in the quantisation table in JPEG-like encoding basically determines the compromise between image quality and image size. A quantisation table with small values results in a high quality but large image and a quantisation table with large values results in a low quality but small image.

The quantisation table used in the Jeilin encoding is a scaled version of a base quantisation table. This base quantisation table is very similar (within a few percent) to the one given in the JPEG specification.

The scale factor (in percent) is calculated from the quality value from the header (call it q) in the following way:

    * q = 0: scale factor = 5000
    * 0 < q <= 50: scale factor = 5000 / q
    * 50 < q <= 100: scale factor = 2 * (100 - q)
    * q > 100: assume q = 100 

Scaling is done by multiplying each element of the table by the scale factor, dividing by 100 and rounding to the nearest integer value. The minimum value of an element after scaling is 1 and the maximum value is 255.
Retrieved from "http://sourceforge.net/apps/mediawiki/gphoto/index.php?title=ImageEncodingJeilin2005CD"
Views

    * Page
    * Discussion
    * View source
    * History

Personal tools

Navigation

    * Main Page
    * Community portal
    * Current events
    * Recent changes
    * Random page
    * Help

Search
 
Toolbox

    * What links here
    * Related changes
    * Special pages
    * Printable version
    * Permanent link

Powered by MediaWiki

    * This page was last modified on 25 April 2010, at 18:30.
    * This page has been accessed 223 times.


© 2010 Geeknet, Inc. Terms of Use Privacy Policy

