libopenraw
olympusdecompressor.cpp
1/*
2 * libopenraw - olympusdecompressor.cpp
3 *
4 * Copyright (C) 2011-2016 Hubert Figuiere
5 * Olympus Decompression copied from RawSpeed
6 * Copyright (C) 2009 Klaus Post
7 *
8 * This library is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation, either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
21 */
22
23#include <stdlib.h>
24#include <string.h>
25
26#include <algorithm>
27
28#include "rawdata.hpp"
29#include "olympusdecompressor.hpp"
30#include "bititerator.hpp"
31
32namespace OpenRaw {
33namespace Internals {
34
35static void decompressOlympus(const uint8_t* buffer, size_t size, uint8_t* data,
36 uint32_t w, uint32_t h);
37
38// decompression ported from RawSpeed.
39static void decompressOlympus(const uint8_t* buffer, size_t size, uint8_t* data,
40 uint32_t w, uint32_t h)
41{
42 int nbits, sign, low, high, i, wo0, n, nw0, wo1, nw1;
43 int acarry0[3], acarry1[3], pred, diff;
44
45 int pitch = w * 2; //(((w * 2/*bpp*/) + 15) / 16) * 16; // TODO make that
46 //part of the outer datas
47
48 /* Build a table to quickly look up "high" value */
49 char bittable[4096];
50 for (i = 0; i < 4096; i++) {
51 int b = i;
52 for (high = 0; high < 12; high++) {
53 if ((b >> (11 - high)) & 1) {
54 break;
55 }
56 }
57 bittable[i] = high;
58 }
59 wo0 = nw0 = wo1 = nw1 = 0;
60 buffer += 7;
61
62 BitIterator bits(buffer, size - 7);
63
64 for (uint32_t y = 0; y < h; y++) {
65 memset(acarry0, 0, sizeof acarry0);
66 memset(acarry1, 0, sizeof acarry1);
67 uint16_t* dest = (uint16_t*)&data[y * pitch];
68 for (uint32_t x = 0; x < w; x++) {
69 // bits.checkPos();
70 // bits.fill();
71 i = 2 * (acarry0[2] < 3);
72 for (nbits = 2 + i; (uint16_t)acarry0[0] >> (nbits + i); nbits++) {
73 }
74
75 uint32_t b = bits.peek(15);
76 sign = (b >> 14) * -1;
77 low = (b >> 12) & 3;
78 high = bittable[b & 4095];
79 // Skip bits used above.
80 bits.skip(std::min(12 + 3, high + 1 + 3));
81
82 if (high == 12) {
83 high = bits.get(16 - nbits) >> 1;
84 }
85
86 acarry0[0] = (high << nbits) | bits.get(nbits);
87 diff = (acarry0[0] ^ sign) + acarry0[1];
88 acarry0[1] = (diff * 3 + acarry0[1]) >> 5;
89 acarry0[2] = acarry0[0] > 16 ? 0 : acarry0[2] + 1;
90
91 if (y < 2 || x < 2) {
92 if (y < 2 && x < 2) {
93 pred = 0;
94 } else if (y < 2) {
95 pred = wo0;
96 } else {
97 pred = dest[-pitch + ((int)x)];
98 nw0 = pred;
99 }
100 dest[x] = pred + ((diff << 2) | low);
101 // Set predictor
102 wo0 = dest[x];
103 } else {
104 n = dest[-pitch + ((int)x)];
105 if (((wo0 < nw0) & (nw0 < n)) | ((n < nw0) & (nw0 < wo0))) {
106 if (abs(wo0 - nw0) > 32 || abs(n - nw0) > 32) {
107 pred = wo0 + n - nw0;
108 } else {
109 pred = (wo0 + n) >> 1;
110 }
111 } else {
112 pred = abs(wo0 - nw0) > abs(n - nw0) ? wo0 : n;
113 }
114
115 dest[x] = pred + ((diff << 2) | low);
116 // Set predictors
117 wo0 = dest[x];
118 nw0 = n;
119 }
120 // _ASSERTE(0 == dest[x] >> 12) ;
121
122 // ODD PIXELS
123 x += 1;
124 // bits.checkPos();
125 // bits.fill();
126 i = 2 * (acarry1[2] < 3);
127 for (nbits = 2 + i; (uint16_t)acarry1[0] >> (nbits + i); nbits++) {
128 }
129 b = bits.peek(15);
130 sign = (b >> 14) * -1;
131 low = (b >> 12) & 3;
132 high = bittable[b & 4095];
133 // Skip bits used above.
134 bits.skip(std::min(12 + 3, high + 1 + 3));
135
136 if (high == 12) {
137 high = bits.get(16 - nbits) >> 1;
138 }
139
140 acarry1[0] = (high << nbits) | bits.get(nbits);
141 diff = (acarry1[0] ^ sign) + acarry1[1];
142 acarry1[1] = (diff * 3 + acarry1[1]) >> 5;
143 acarry1[2] = acarry1[0] > 16 ? 0 : acarry1[2] + 1;
144
145 if (y < 2 || x < 2) {
146 if (y < 2 && x < 2) {
147 pred = 0;
148 } else if (y < 2) {
149 pred = wo1;
150 } else {
151 pred = dest[-pitch + ((int)x)];
152 nw1 = pred;
153 }
154 dest[x] = pred + ((diff << 2) | low);
155 // Set predictor
156 wo1 = dest[x];
157 } else {
158 n = dest[-pitch + ((int)x)];
159 if (((wo1 < nw1) & (nw1 < n)) | ((n < nw1) & (nw1 < wo1))) {
160 if (abs(wo1 - nw1) > 32 || abs(n - nw1) > 32) {
161 pred = wo1 + n - nw1;
162 } else {
163 pred = (wo1 + n) >> 1;
164 }
165 } else {
166 pred = abs(wo1 - nw1) > abs(n - nw1) ? wo1 : n;
167 }
168
169 dest[x] = pred + ((diff << 2) | low);
170
171 // Set predictors
172 wo1 = dest[x];
173 nw1 = n;
174 }
175 // _ASSERTE(0 == dest[x] >> 12) ;
176 }
177 }
178}
179
181{
182 RawDataPtr output(new RawData);
183
184 output->allocData(m_w * m_h * 2);
185 decompressOlympus(m_buffer, m_size, (uint8_t*)output->data(), m_w, m_h);
186
187 // hardcoded 12bits values
188 output->setBpc(12);
189 output->setWhiteLevel((1 << 12) - 1);
190
191 return output;
192}
193
194}
195}
void setBpc(uint32_t _bpc)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30