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 static
00240 int canon_has_lowbits(IO::Stream * s)
00241 {
00242 uint8_t test[0x4000 - 26];
00243 int ret=1;
00244 uint32_t i;
00245
00246 s->seek (0, SEEK_SET);
00247 s->read (test, sizeof(test));
00248 for (i=514; i < sizeof(test) - 1; i++)
00249 if (test[i] == 0xff) {
00250 if (test[i+1])
00251 return 1;
00252 ret=0;
00253 }
00254 return ret;
00255 }
00256
00257
00258
00259
00260 RawData *CrwDecompressor::decompress(RawData *in)
00261 {
00262 decode_t *decode, *dindex;
00263 int i, j, leaf, len, diff, diffbuf[64], r, save;
00264 int carry=0, base[2];
00265 uint32_t column = 0;
00266 uint16_t outbuf[64];
00267 uint8_t c;
00268
00269 RawData *bitmap;
00270 if(in == NULL)
00271 bitmap = new RawData();
00272 else
00273 bitmap = in;
00274 bitmap->setDataType(OR_DATA_TYPE_CFA);
00275 bitmap->setBpc(16);
00276 uint8_t *rawbuf = (uint8_t*)bitmap->allocData(m_width
00277 * sizeof(uint16_t)
00278 * m_height);
00279 bitmap->setDimensions(m_width,
00280 m_height);
00281
00282 init_tables(m_table);
00283
00284 int lowbits = canon_has_lowbits(m_stream);
00285 Debug::Trace(DEBUG2) << "lowbits = " << lowbits
00286 << " height = " << m_height
00287 << " width = " << m_width
00288 << "\n";
00289 m_stream->seek(514 + lowbits*m_height*m_width/4, SEEK_SET);
00290 getbits(m_stream, -1);
00291
00292 while (column < m_width * m_height) {
00293 memset(diffbuf,0,sizeof(diffbuf));
00294 decode = m_first_decode;
00295 for (i=0; i < 64; i++ ) {
00296
00297 for (dindex=decode; dindex->branch[0]; )
00298 dindex = dindex->branch[getbits(m_stream, 1)];
00299 leaf = dindex->leaf;
00300 decode = m_second_decode;
00301
00302 if (leaf == 0 && i)
00303 break;
00304 if (leaf == 0xff)
00305 continue;
00306 i += leaf >> 4;
00307 len = leaf & 15;
00308 if (len == 0)
00309 continue;
00310 diff = getbits(m_stream, len);
00311 if ((diff & (1 << (len-1))) == 0)
00312 diff -= (1 << len) - 1;
00313 if (i < 64)
00314 diffbuf[i] = diff;
00315 }
00316 diffbuf[0] += carry;
00317 carry = diffbuf[0];
00318 for (i=0; i < 64; i++ ) {
00319 if (column++ % m_width == 0)
00320 base[0] = base[1] = 512;
00321 outbuf[i] = ( base[i & 1] += diffbuf[i] );
00322 }
00323 if (lowbits) {
00324 save = m_stream->seek(0, SEEK_CUR);
00325 m_stream->seek((column-64)/4, SEEK_SET);
00326 for (i=j=0; j < 64/4; j++ ) {
00327 c = m_stream->readByte();
00328 for (r = 0; r < 8; r += 2) {
00329 outbuf[i] = (outbuf[i+1] << 2) + ((c >> r) & 3);
00330 i++;
00331 }
00332 }
00333 m_stream->seek(save, SEEK_SET);
00334 }
00335 memcpy(rawbuf, outbuf, 2 * 64);
00336 rawbuf += 2 * 64;
00337 }
00338 return bitmap;
00339 }
00340
00341
00342
00343 } }