|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
* libopenraw - crwdecompressor.h
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* Copyright (C) 2007-2016 Hubert Figuiere
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* This library is free software: you can redistribute it and/or
|
|
rpm-build |
d2b433 |
* modify it under the terms of the GNU Lesser General Public License
|
|
rpm-build |
d2b433 |
* as published by the Free Software Foundation, either version 3 of
|
|
rpm-build |
d2b433 |
* the License, or (at your option) any later version.
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
d2b433 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
d2b433 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
d2b433 |
* Lesser General Public License for more details.
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
d2b433 |
* License along with this library. If not, see
|
|
rpm-build |
d2b433 |
* <http://www.gnu.org/licenses/>.
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
Simple reference decompresser for Canon digital cameras.
|
|
rpm-build |
d2b433 |
Outputs raw 16-bit CCD data, no header, native byte order.
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
Written by Dave Coffin.
|
|
rpm-build |
d2b433 |
Downloaded from http://cybercom.net/~dcoffin/dcraw/decompress.c
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
$Revision: 1.1 $
|
|
rpm-build |
d2b433 |
$Date: 2005/06/27 14:07:24 $
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include <fcntl.h>
|
|
rpm-build |
d2b433 |
#include <string.h>
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include <libopenraw/consts.h>
|
|
rpm-build |
d2b433 |
#include <libopenraw/debug.h>
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include "rawdata.hpp"
|
|
rpm-build |
d2b433 |
#include "crwdecompressor.hpp"
|
|
rpm-build |
d2b433 |
#include "exception.hpp"
|
|
rpm-build |
d2b433 |
#include "trace.hpp"
|
|
rpm-build |
d2b433 |
#include "io/stream.hpp"
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
namespace OpenRaw { namespace Internals {
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CrwDecompressor::CrwDecompressor(IO::Stream * stream,
|
|
rpm-build |
d2b433 |
RawContainer * container)
|
|
rpm-build |
d2b433 |
: Decompressor(stream, container),
|
|
rpm-build |
d2b433 |
m_table(0),
|
|
rpm-build |
d2b433 |
m_height(0), m_width(0),
|
|
rpm-build |
d2b433 |
m_free(0), m_leaf(0),
|
|
rpm-build |
d2b433 |
m_bitbuf(0), m_vbits(0)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CrwDecompressor::~CrwDecompressor()
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
A rough description of Canon's compression algorithm:
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
+ Each pixel outputs a 10-bit sample, from 0 to 1023.
|
|
rpm-build |
d2b433 |
+ Split the data into blocks of 64 samples each.
|
|
rpm-build |
d2b433 |
+ Subtract from each sample the value of the sample two positions
|
|
rpm-build |
d2b433 |
to the left, which has the same color filter. From the two
|
|
rpm-build |
d2b433 |
leftmost samples in each row, subtract 512.
|
|
rpm-build |
d2b433 |
+ For each nonzero sample, make a token consisting of two four-bit
|
|
rpm-build |
d2b433 |
numbers. The low nibble is the number of bits required to
|
|
rpm-build |
d2b433 |
represent the sample, and the high nibble is the number of
|
|
rpm-build |
d2b433 |
zero samples preceding this sample.
|
|
rpm-build |
d2b433 |
+ Output this token as a variable-length bitstring using
|
|
rpm-build |
d2b433 |
one of three tablesets. Follow it with a fixed-length
|
|
rpm-build |
d2b433 |
bitstring containing the sample.
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
The "first_decode" table is used for the first sample in each
|
|
rpm-build |
d2b433 |
block, and the "second_decode" table is used for the others.
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
Construct a decode tree according the specification in *source.
|
|
rpm-build |
d2b433 |
The first 16 bytes specify how many codes should be 1-bit, 2-bit
|
|
rpm-build |
d2b433 |
3-bit, etc. Bytes after that are the leaf values.
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
For example, if the source is
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
|
|
rpm-build |
d2b433 |
0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
then the code is
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
00 0x04
|
|
rpm-build |
d2b433 |
010 0x03
|
|
rpm-build |
d2b433 |
011 0x05
|
|
rpm-build |
d2b433 |
100 0x06
|
|
rpm-build |
d2b433 |
101 0x02
|
|
rpm-build |
d2b433 |
1100 0x07
|
|
rpm-build |
d2b433 |
1101 0x01
|
|
rpm-build |
d2b433 |
11100 0x08
|
|
rpm-build |
d2b433 |
11101 0x09
|
|
rpm-build |
d2b433 |
11110 0x00
|
|
rpm-build |
d2b433 |
111110 0x0a
|
|
rpm-build |
d2b433 |
1111110 0x0b
|
|
rpm-build |
d2b433 |
1111111 0xff
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
void CrwDecompressor::make_decoder(decode_t *dest, const uint8_t *source,
|
|
rpm-build |
d2b433 |
int level)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
int i, next;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (level==0) {
|
|
rpm-build |
d2b433 |
m_free = dest;
|
|
rpm-build |
d2b433 |
m_leaf = 0;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
m_free++;
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
At what level should the next leaf appear?
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
for (i=next=0; i <= m_leaf && next < 16; ) {
|
|
rpm-build |
d2b433 |
i += source[next++];
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (i > m_leaf) {
|
|
rpm-build |
d2b433 |
if (level < next) { /* Are we there yet? */
|
|
rpm-build |
d2b433 |
dest->branch[0] = m_free;
|
|
rpm-build |
d2b433 |
make_decoder(m_free,source,level+1);
|
|
rpm-build |
d2b433 |
dest->branch[1] = m_free;
|
|
rpm-build |
d2b433 |
make_decoder(m_free,source,level+1);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
else {
|
|
rpm-build |
d2b433 |
dest->leaf = source[16 + m_leaf++];
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
void CrwDecompressor::init_tables(uint32_t table_idx)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
static const uint8_t first_tree[3][29] = {
|
|
rpm-build |
d2b433 |
{ 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
|
|
rpm-build |
d2b433 |
0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff },
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
{ 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
|
|
rpm-build |
d2b433 |
0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff },
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
{ 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
|
|
rpm-build |
d2b433 |
0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff },
|
|
rpm-build |
d2b433 |
};
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
static const uint8_t second_tree[3][180] = {
|
|
rpm-build |
d2b433 |
{ 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
|
|
rpm-build |
d2b433 |
0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
|
|
rpm-build |
d2b433 |
0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0,
|
|
rpm-build |
d2b433 |
0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42,
|
|
rpm-build |
d2b433 |
0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57,
|
|
rpm-build |
d2b433 |
0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9,
|
|
rpm-build |
d2b433 |
0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98,
|
|
rpm-build |
d2b433 |
0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6,
|
|
rpm-build |
d2b433 |
0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4,
|
|
rpm-build |
d2b433 |
0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7,
|
|
rpm-build |
d2b433 |
0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1,
|
|
rpm-build |
d2b433 |
0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64,
|
|
rpm-build |
d2b433 |
0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
|
|
rpm-build |
d2b433 |
0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
|
|
rpm-build |
d2b433 |
0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff },
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
{ 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
|
|
rpm-build |
d2b433 |
0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
|
|
rpm-build |
d2b433 |
0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
|
|
rpm-build |
d2b433 |
0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51,
|
|
rpm-build |
d2b433 |
0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26,
|
|
rpm-build |
d2b433 |
0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59,
|
|
rpm-build |
d2b433 |
0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9,
|
|
rpm-build |
d2b433 |
0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99,
|
|
rpm-build |
d2b433 |
0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85,
|
|
rpm-build |
d2b433 |
0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8,
|
|
rpm-build |
d2b433 |
0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a,
|
|
rpm-build |
d2b433 |
0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9,
|
|
rpm-build |
d2b433 |
0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
|
|
rpm-build |
d2b433 |
0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
|
|
rpm-build |
d2b433 |
0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff },
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
{ 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
|
|
rpm-build |
d2b433 |
0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
|
|
rpm-build |
d2b433 |
0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
|
|
rpm-build |
d2b433 |
0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34,
|
|
rpm-build |
d2b433 |
0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41,
|
|
rpm-build |
d2b433 |
0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48,
|
|
rpm-build |
d2b433 |
0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69,
|
|
rpm-build |
d2b433 |
0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8,
|
|
rpm-build |
d2b433 |
0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94,
|
|
rpm-build |
d2b433 |
0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a,
|
|
rpm-build |
d2b433 |
0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6,
|
|
rpm-build |
d2b433 |
0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62,
|
|
rpm-build |
d2b433 |
0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5,
|
|
rpm-build |
d2b433 |
0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
|
|
rpm-build |
d2b433 |
0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff }
|
|
rpm-build |
d2b433 |
};
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (table_idx > 2)
|
|
rpm-build |
d2b433 |
table_idx = 2;
|
|
rpm-build |
d2b433 |
memset( m_first_decode, 0, sizeof(m_first_decode));
|
|
rpm-build |
d2b433 |
memset(m_second_decode, 0, sizeof(m_second_decode));
|
|
rpm-build |
d2b433 |
make_decoder(m_first_decode, first_tree[table_idx], 0);
|
|
rpm-build |
d2b433 |
make_decoder(m_second_decode, second_tree[table_idx], 0);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
getbits(-1) initializes the buffer
|
|
rpm-build |
d2b433 |
getbits(n) where 0 <= n <= 25 returns an n-bit integer
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
uint32_t CrwDecompressor::getbits(IO::Stream * s, int nbits)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
uint32_t ret = 0;
|
|
rpm-build |
d2b433 |
uint8_t c;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (nbits == 0)
|
|
rpm-build |
d2b433 |
return 0;
|
|
rpm-build |
d2b433 |
if (nbits == -1)
|
|
rpm-build |
d2b433 |
ret = m_bitbuf = m_vbits = 0;
|
|
rpm-build |
d2b433 |
else {
|
|
rpm-build |
d2b433 |
ret = m_bitbuf << (32 - m_vbits) >> (32 - nbits);
|
|
rpm-build |
d2b433 |
m_vbits -= nbits;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
while (m_vbits < 25) {
|
|
rpm-build |
d2b433 |
try {
|
|
rpm-build |
d2b433 |
c = s->readByte();
|
|
rpm-build |
d2b433 |
m_bitbuf = (m_bitbuf << 8) + c;
|
|
rpm-build |
d2b433 |
if (c == 0xff)
|
|
rpm-build |
d2b433 |
s->readByte(); /* always extra 00 after ff */
|
|
rpm-build |
d2b433 |
m_vbits += 8;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
catch(const Internals::IOException &)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
return ret;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
namespace {
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
static
|
|
rpm-build |
d2b433 |
int canon_has_lowbits(IO::Stream * s)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
uint8_t test[0x4000 - 26];
|
|
rpm-build |
d2b433 |
int ret=1;
|
|
rpm-build |
d2b433 |
uint32_t i;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
s->seek (0, SEEK_SET);
|
|
rpm-build |
d2b433 |
s->read (test, sizeof(test));
|
|
rpm-build |
d2b433 |
for (i=514; i < sizeof(test) - 1; i++)
|
|
rpm-build |
d2b433 |
if (test[i] == 0xff) {
|
|
rpm-build |
d2b433 |
if (test[i+1])
|
|
rpm-build |
d2b433 |
return 1;
|
|
rpm-build |
d2b433 |
ret=0;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
return ret;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
// int oldmain(int argc, char **argv)
|
|
rpm-build |
d2b433 |
RawDataPtr CrwDecompressor::decompress()
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
decode_t *decode, *dindex;
|
|
rpm-build |
d2b433 |
int i, j, leaf, len, diff, diffbuf[64], r, save;
|
|
rpm-build |
d2b433 |
int carry = 0, base[2] = {0, 0};
|
|
rpm-build |
d2b433 |
uint32_t column = 0;
|
|
rpm-build |
d2b433 |
uint16_t outbuf[64];
|
|
rpm-build |
d2b433 |
uint8_t c;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
RawDataPtr bitmap(new RawData);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
bitmap->setDataType(OR_DATA_TYPE_RAW);
|
|
rpm-build |
d2b433 |
// we know the 10-bits are hardcoded in the CRW
|
|
rpm-build |
d2b433 |
bitmap->setBpc(10);
|
|
rpm-build |
d2b433 |
bitmap->setWhiteLevel((1 << 10) - 1);
|
|
rpm-build |
d2b433 |
uint8_t *rawbuf = (uint8_t*)bitmap->allocData(m_width
|
|
rpm-build |
d2b433 |
* sizeof(uint16_t)
|
|
rpm-build |
d2b433 |
* m_height);
|
|
rpm-build |
d2b433 |
bitmap->setDimensions(m_width,
|
|
rpm-build |
d2b433 |
m_height);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
init_tables(m_table);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
int lowbits = canon_has_lowbits(m_stream);
|
|
rpm-build |
d2b433 |
LOGDBG2("lowbits = %d height = %d width = %d\n", lowbits,
|
|
rpm-build |
d2b433 |
m_height, m_width);
|
|
rpm-build |
d2b433 |
m_stream->seek(514 + lowbits * m_height * m_width / 4, SEEK_SET);
|
|
rpm-build |
d2b433 |
getbits(m_stream, -1); /* Prime the bit buffer */
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
while (column < m_width * m_height) {
|
|
rpm-build |
d2b433 |
memset(diffbuf, 0, sizeof(diffbuf));
|
|
rpm-build |
d2b433 |
decode = m_first_decode;
|
|
rpm-build |
d2b433 |
for (i = 0; i < 64; i++ ) {
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
for (dindex = decode; dindex->branch[0]; ) {
|
|
rpm-build |
d2b433 |
dindex = dindex->branch[getbits(m_stream, 1)];
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
leaf = dindex->leaf;
|
|
rpm-build |
d2b433 |
decode = m_second_decode;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (leaf == 0 && i) {
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
if (leaf == 0xff) {
|
|
rpm-build |
d2b433 |
continue;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
i += leaf >> 4;
|
|
rpm-build |
d2b433 |
len = leaf & 15;
|
|
rpm-build |
d2b433 |
if (len == 0) {
|
|
rpm-build |
d2b433 |
continue;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
diff = getbits(m_stream, len);
|
|
rpm-build |
d2b433 |
if ((diff & (1 << (len-1))) == 0) {
|
|
rpm-build |
d2b433 |
diff -= (1 << len) - 1;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
if (i < 64) {
|
|
rpm-build |
d2b433 |
diffbuf[i] = diff;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
diffbuf[0] += carry;
|
|
rpm-build |
d2b433 |
carry = diffbuf[0];
|
|
rpm-build |
d2b433 |
for (i=0; i < 64; i++ ) {
|
|
rpm-build |
d2b433 |
if (column++ % m_width == 0) {
|
|
rpm-build |
d2b433 |
base[0] = base[1] = 512;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
outbuf[i] = (base[i & 1] += diffbuf[i]);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
if (lowbits) {
|
|
rpm-build |
d2b433 |
save = m_stream->seek(0, SEEK_CUR);
|
|
rpm-build |
d2b433 |
m_stream->seek((column-64)/4, SEEK_SET);
|
|
rpm-build |
d2b433 |
for (i=j=0; j < 64/4; j++ ) {
|
|
rpm-build |
d2b433 |
c = m_stream->readByte();
|
|
rpm-build |
d2b433 |
for (r = 0; r < 8; r += 2) {
|
|
rpm-build |
d2b433 |
// outbuf is 64, so we must check for it to not
|
|
rpm-build |
d2b433 |
// overflow (read out of bounds)
|
|
rpm-build |
d2b433 |
uint16_t next = i < 63 ? outbuf[i+1] : 0;
|
|
rpm-build |
d2b433 |
outbuf[i] = (next << 2) + ((c >> r) & 3);
|
|
rpm-build |
d2b433 |
i++;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
m_stream->seek(save, SEEK_SET);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
memcpy(rawbuf, outbuf, 2 * 64);
|
|
rpm-build |
d2b433 |
rawbuf += 2 * 64;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
return bitmap;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
} }
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
Local Variables:
|
|
rpm-build |
d2b433 |
mode:c++
|
|
rpm-build |
d2b433 |
c-file-style:"stroustrup"
|
|
rpm-build |
d2b433 |
c-file-offsets:((innamespace . 0))
|
|
rpm-build |
d2b433 |
indent-tabs-mode:nil
|
|
rpm-build |
d2b433 |
fill-column:80
|
|
rpm-build |
d2b433 |
End:
|
|
rpm-build |
d2b433 |
*/
|