00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <assert.h>
00032 #include <string.h>
00033 #include <libopenraw++/rawdata.h>
00034
00035 #include "crwdecompressor.h"
00036 #include "debug.h"
00037 #include "rawcontainer.h"
00038 #include "io/stream.h"
00039 #include "exception.h"
00040
00041 namespace OpenRaw { namespace Internals {
00042
00043 CrwDecompressor::CrwDecompressor(IO::Stream * stream,
00044 RawContainer * container)
00045 : Decompressor(stream, container),
00046 m_table(0),
00047 m_height(0), m_width(0),
00048 m_free(0), m_leaf(0),
00049 m_bitbuf(0), m_vbits(0)
00050 {
00051 }
00052
00053
00054 CrwDecompressor::~CrwDecompressor()
00055 {
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void CrwDecompressor::make_decoder(decode_t *dest, const uint8_t *source,
00106 int level)
00107 {
00108 int i, next;
00109
00110 if (level==0) {
00111 m_free = dest;
00112 m_leaf = 0;
00113 }
00114 m_free++;
00115
00116
00117
00118 for (i=next=0; i <= m_leaf && next < 16; ) {
00119 i += source[next++];
00120 }
00121
00122 if (i > m_leaf) {
00123 if (level < next) {
00124 dest->branch[0] = m_free;
00125 make_decoder(m_free,source,level+1);
00126 dest->branch[1] = m_free;
00127 make_decoder(m_free,source,level+1);
00128 }
00129 else {
00130 dest->leaf = source[16 + m_leaf++];
00131 }
00132 }
00133 }
00134
00135 void CrwDecompressor::init_tables(uint32_t table_idx)
00136 {
00137 static const uint8_t first_tree[3][29] = {
00138 { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
00139 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
00140
00141 { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
00142 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
00143
00144 { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
00145 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
00146 };
00147
00148 static const uint8_t second_tree[3][180] = {
00149 { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
00150 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
00151 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
00152 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
00153 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
00154 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
00155 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
00156 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
00157 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
00158 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
00159 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
00160 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
00161 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
00162 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
00163 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
00164
00165 { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
00166 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
00167 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
00168 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
00169 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
00170 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
00171 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
00172 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
00173 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
00174 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
00175 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
00176 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
00177 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
00178 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
00179 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
00180
00181 { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
00182 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
00183 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
00184 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
00185 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
00186 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
00187 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
00188 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
00189 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
00190 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
00191 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
00192 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
00193 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
00194 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
00195 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
00196 };
00197
00198 if (table_idx > 2)
00199 table_idx = 2;
00200 memset( m_first_decode, 0, sizeof(m_first_decode));
00201 memset(m_second_decode, 0, sizeof(m_second_decode));
00202 make_decoder(m_first_decode, first_tree[table_idx], 0);
00203 make_decoder(m_second_decode, second_tree[table_idx], 0);
00204 }
00205
00206
00207
00208
00209
00210 uint32_t CrwDecompressor::getbits(IO::Stream * s, int nbits)
00211 {
00212 uint32_t ret = 0;
00213 uint8_t c;
00214
00215 if (nbits == 0)
00216 return 0;
00217 if (nbits == -1)
00218 ret = m_bitbuf = m_vbits = 0;
00219 else {
00220 ret = m_bitbuf << (32 - m_vbits) >> (32 - nbits);
00221 m_vbits -= nbits;
00222 }
00223 while (m_vbits < 25) {
00224 try {
00225 c = s->readByte();
00226 m_bitbuf = (m_bitbuf << 8) + c;
00227 if (c == 0xff)
00228 s->readByte();
00229 m_vbits += 8;
00230 }
00231 catch(const Internals::IOException &)
00232 {
00233 break;
00234 }
00235 }
00236 return ret;
00237 }
00238
00239 namespace {
00240
00241 static
00242 int canon_has_lowbits(IO::Stream * s)
00243 {
00244 uint8_t test[0x4000 - 26];
00245 int ret=1;
00246 uint32_t i;
00247
00248 s->seek (0, SEEK_SET);
00249 s->read (test, sizeof(test));
00250 for (i=514; i < sizeof(test) - 1; i++)
00251 if (test[i] == 0xff) {
00252 if (test[i+1])
00253 return 1;
00254 ret=0;
00255 }
00256 return ret;
00257 }
00258
00259 }
00260
00261
00262
00263 RawData *CrwDecompressor::decompress(RawData *in)
00264 {
00265 decode_t *decode, *dindex;
00266 int i, j, leaf, len, diff, diffbuf[64], r, save;
00267 int carry=0, base[2];
00268 uint32_t column = 0;
00269 uint16_t outbuf[64];
00270 uint8_t c;
00271
00272 RawData *bitmap;
00273 if(in == NULL)
00274 bitmap = new RawData();
00275 else
00276 bitmap = in;
00277 bitmap->setDataType(OR_DATA_TYPE_CFA);
00278
00279 bitmap->setBpc(10);
00280 bitmap->setMax((1 << 10) - 1);
00281 uint8_t *rawbuf = (uint8_t*)bitmap->allocData(m_width
00282 * sizeof(uint16_t)
00283 * m_height);
00284 bitmap->setDimensions(m_width,
00285 m_height);
00286
00287 init_tables(m_table);
00288
00289 int lowbits = canon_has_lowbits(m_stream);
00290 Debug::Trace(DEBUG2) << "lowbits = " << lowbits
00291 << " height = " << m_height
00292 << " width = " << m_width
00293 << "\n";
00294 m_stream->seek(514 + lowbits*m_height*m_width/4, SEEK_SET);
00295 getbits(m_stream, -1);
00296
00297 while (column < m_width * m_height) {
00298 memset(diffbuf,0,sizeof(diffbuf));
00299 decode = m_first_decode;
00300 for (i=0; i < 64; i++ ) {
00301
00302 for (dindex=decode; dindex->branch[0]; )
00303 dindex = dindex->branch[getbits(m_stream, 1)];
00304 leaf = dindex->leaf;
00305 decode = m_second_decode;
00306
00307 if (leaf == 0 && i)
00308 break;
00309 if (leaf == 0xff)
00310 continue;
00311 i += leaf >> 4;
00312 len = leaf & 15;
00313 if (len == 0)
00314 continue;
00315 diff = getbits(m_stream, len);
00316 if ((diff & (1 << (len-1))) == 0)
00317 diff -= (1 << len) - 1;
00318 if (i < 64)
00319 diffbuf[i] = diff;
00320 }
00321 diffbuf[0] += carry;
00322 carry = diffbuf[0];
00323 for (i=0; i < 64; i++ ) {
00324 if (column++ % m_width == 0)
00325 base[0] = base[1] = 512;
00326 outbuf[i] = ( base[i & 1] += diffbuf[i] );
00327 }
00328 if (lowbits) {
00329 save = m_stream->seek(0, SEEK_CUR);
00330 m_stream->seek((column-64)/4, SEEK_SET);
00331 for (i=j=0; j < 64/4; j++ ) {
00332 c = m_stream->readByte();
00333 for (r = 0; r < 8; r += 2) {
00334 outbuf[i] = (outbuf[i+1] << 2) + ((c >> r) & 3);
00335 i++;
00336 }
00337 }
00338 m_stream->seek(save, SEEK_SET);
00339 }
00340 memcpy(rawbuf, outbuf, 2 * 64);
00341 rawbuf += 2 * 64;
00342 }
00343 return bitmap;
00344 }
00345
00346
00347
00348 } }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358