libopenraw
crwdecompressor.cpp
1/*
2 * libopenraw - crwdecompressor.h
3 *
4 * Copyright (C) 2007-2016 Hubert Figuiere
5 *
6 * This library is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20/*
21 Simple reference decompresser for Canon digital cameras.
22 Outputs raw 16-bit CCD data, no header, native byte order.
23
24 Written by Dave Coffin.
25 Downloaded from http://cybercom.net/~dcoffin/dcraw/decompress.c
26
27 $Revision: 1.1 $
28 $Date: 2005/06/27 14:07:24 $
29*/
30
31#include <fcntl.h>
32#include <string.h>
33
34#include <libopenraw/consts.h>
35#include <libopenraw/debug.h>
36
37#include "rawdata.hpp"
38#include "crwdecompressor.hpp"
39#include "exception.hpp"
40#include "trace.hpp"
41#include "io/stream.hpp"
42
43namespace OpenRaw { namespace Internals {
44
45CrwDecompressor::CrwDecompressor(IO::Stream * stream,
46 RawContainer * container)
47 : Decompressor(stream, container),
48 m_table(0),
49 m_height(0), m_width(0),
50 m_free(0), m_leaf(0),
51 m_bitbuf(0), m_vbits(0)
52{
53}
54
55
56CrwDecompressor::~CrwDecompressor()
57{
58}
59
60
61/*
62 A rough description of Canon's compression algorithm:
63
64 + Each pixel outputs a 10-bit sample, from 0 to 1023.
65 + Split the data into blocks of 64 samples each.
66 + Subtract from each sample the value of the sample two positions
67 to the left, which has the same color filter. From the two
68 leftmost samples in each row, subtract 512.
69 + For each nonzero sample, make a token consisting of two four-bit
70 numbers. The low nibble is the number of bits required to
71 represent the sample, and the high nibble is the number of
72 zero samples preceding this sample.
73 + Output this token as a variable-length bitstring using
74 one of three tablesets. Follow it with a fixed-length
75 bitstring containing the sample.
76
77 The "first_decode" table is used for the first sample in each
78 block, and the "second_decode" table is used for the others.
79*/
80
81/*
82 Construct a decode tree according the specification in *source.
83 The first 16 bytes specify how many codes should be 1-bit, 2-bit
84 3-bit, etc. Bytes after that are the leaf values.
85
86 For example, if the source is
87
88 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
89 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
90
91 then the code is
92
93 00 0x04
94 010 0x03
95 011 0x05
96 100 0x06
97 101 0x02
98 1100 0x07
99 1101 0x01
100 11100 0x08
101 11101 0x09
102 11110 0x00
103 111110 0x0a
104 1111110 0x0b
105 1111111 0xff
106*/
107void CrwDecompressor::make_decoder(decode_t *dest, const uint8_t *source,
108 int level)
109{
110 int i, next;
111
112 if (level==0) {
113 m_free = dest;
114 m_leaf = 0;
115 }
116 m_free++;
117/*
118 At what level should the next leaf appear?
119*/
120 for (i=next=0; i <= m_leaf && next < 16; ) {
121 i += source[next++];
122 }
123
124 if (i > m_leaf) {
125 if (level < next) { /* Are we there yet? */
126 dest->branch[0] = m_free;
127 make_decoder(m_free,source,level+1);
128 dest->branch[1] = m_free;
129 make_decoder(m_free,source,level+1);
130 }
131 else {
132 dest->leaf = source[16 + m_leaf++];
133 }
134 }
135}
136
137void CrwDecompressor::init_tables(uint32_t table_idx)
138{
139 static const uint8_t first_tree[3][29] = {
140 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
141 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
142
143 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
144 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
145
146 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
147 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
148 };
149
150 static const uint8_t second_tree[3][180] = {
151 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
152 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
153 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
154 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
155 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
156 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
157 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
158 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
159 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
160 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
161 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
162 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
163 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
164 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
165 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
166
167 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
168 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
169 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
170 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
171 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
172 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
173 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
174 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
175 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
176 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
177 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
178 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
179 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
180 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
181 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
182
183 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
184 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
185 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
186 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
187 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
188 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
189 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
190 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
191 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
192 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
193 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
194 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
195 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
196 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
197 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
198 };
199
200 if (table_idx > 2)
201 table_idx = 2;
202 memset( m_first_decode, 0, sizeof(m_first_decode));
203 memset(m_second_decode, 0, sizeof(m_second_decode));
204 make_decoder(m_first_decode, first_tree[table_idx], 0);
205 make_decoder(m_second_decode, second_tree[table_idx], 0);
206}
207
208/*
209 getbits(-1) initializes the buffer
210 getbits(n) where 0 <= n <= 25 returns an n-bit integer
211*/
212uint32_t CrwDecompressor::getbits(IO::Stream * s, int nbits)
213{
214 uint32_t ret = 0;
215 uint8_t c;
216
217 if (nbits == 0)
218 return 0;
219 if (nbits == -1)
220 ret = m_bitbuf = m_vbits = 0;
221 else {
222 ret = m_bitbuf << (32 - m_vbits) >> (32 - nbits);
223 m_vbits -= nbits;
224 }
225 while (m_vbits < 25) {
226 try {
227 c = s->readByte();
228 m_bitbuf = (m_bitbuf << 8) + c;
229 if (c == 0xff)
230 s->readByte(); /* always extra 00 after ff */
231 m_vbits += 8;
232 }
233 catch(const Internals::IOException &)
234 {
235 break;
236 }
237 }
238 return ret;
239}
240
241namespace {
242
243static
244int canon_has_lowbits(IO::Stream * s)
245{
246 uint8_t test[0x4000 - 26];
247 int ret=1;
248 uint32_t i;
249
250 s->seek (0, SEEK_SET);
251 s->read (test, sizeof(test));
252 for (i=514; i < sizeof(test) - 1; i++)
253 if (test[i] == 0xff) {
254 if (test[i+1])
255 return 1;
256 ret=0;
257 }
258 return ret;
259}
260
261}
262
263
264// int oldmain(int argc, char **argv)
266{
267 decode_t *decode, *dindex;
268 int i, j, leaf, len, diff, diffbuf[64], r, save;
269 int carry = 0, base[2] = {0, 0};
270 uint32_t column = 0;
271 uint16_t outbuf[64];
272 uint8_t c;
273
274 RawDataPtr bitmap(new RawData);
275
276 bitmap->setDataType(OR_DATA_TYPE_RAW);
277 // we know the 10-bits are hardcoded in the CRW
278 bitmap->setBpc(10);
279 bitmap->setWhiteLevel((1 << 10) - 1);
280 uint8_t *rawbuf = (uint8_t*)bitmap->allocData(m_width
281 * sizeof(uint16_t)
282 * m_height);
283 bitmap->setDimensions(m_width,
284 m_height);
285
286 init_tables(m_table);
287
288 int lowbits = canon_has_lowbits(m_stream);
289 LOGDBG2("lowbits = %d height = %d width = %d\n", lowbits,
290 m_height, m_width);
291 m_stream->seek(514 + lowbits * m_height * m_width / 4, SEEK_SET);
292 getbits(m_stream, -1); /* Prime the bit buffer */
293
294 while (column < m_width * m_height) {
295 memset(diffbuf, 0, sizeof(diffbuf));
296 decode = m_first_decode;
297 for (i = 0; i < 64; i++ ) {
298
299 for (dindex = decode; dindex->branch[0]; ) {
300 dindex = dindex->branch[getbits(m_stream, 1)];
301 }
302 leaf = dindex->leaf;
303 decode = m_second_decode;
304
305 if (leaf == 0 && i) {
306 break;
307 }
308 if (leaf == 0xff) {
309 continue;
310 }
311 i += leaf >> 4;
312 len = leaf & 15;
313 if (len == 0) {
314 continue;
315 }
316 diff = getbits(m_stream, len);
317 if ((diff & (1 << (len-1))) == 0) {
318 diff -= (1 << len) - 1;
319 }
320 if (i < 64) {
321 diffbuf[i] = diff;
322 }
323 }
324 diffbuf[0] += carry;
325 carry = diffbuf[0];
326 for (i=0; i < 64; i++ ) {
327 if (column++ % m_width == 0) {
328 base[0] = base[1] = 512;
329 }
330 outbuf[i] = (base[i & 1] += diffbuf[i]);
331 }
332 if (lowbits) {
333 save = m_stream->seek(0, SEEK_CUR);
334 m_stream->seek((column-64)/4, SEEK_SET);
335 for (i=j=0; j < 64/4; j++ ) {
336 c = m_stream->readByte();
337 for (r = 0; r < 8; r += 2) {
338 // outbuf is 64, so we must check for it to not
339 // overflow (read out of bounds)
340 uint16_t next = i < 63 ? outbuf[i+1] : 0;
341 outbuf[i] = (next << 2) + ((c >> r) & 3);
342 i++;
343 }
344 }
345 m_stream->seek(save, SEEK_SET);
346 }
347 memcpy(rawbuf, outbuf, 2 * 64);
348 rawbuf += 2 * 64;
349 }
350 return bitmap;
351}
352
353
354
355} }
356
357/*
358 Local Variables:
359 mode:c++
360 c-file-style:"stroustrup"
361 c-file-offsets:((innamespace . 0))
362 indent-tabs-mode:nil
363 fill-column:80
364 End:
365*/
void setDataType(DataType _type)
void setBpc(uint32_t _bpc)
virtual RawDataPtr decompress() override
virtual void setDimensions(uint32_t x, uint32_t y) override
Definition rawdata.cpp:260
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30