libopenraw  0.3.7
olympusdecompressor.cpp
1 /*
2  * libopenraw - olympusdecompressor.cpp
3  *
4  * Copyright (C) 2011-2022 Hubert Figuière
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 
32 namespace OpenRaw {
33 namespace Internals {
34 
35 static void decompressOlympus(const uint8_t* buffer, size_t size, uint16_t* data16,
36  uint32_t w, uint32_t h);
37 
38 // decompression ported from RawSpeed.
39 static void decompressOlympus(const uint8_t* buffer, size_t size, uint16_t* data16,
40  uint32_t w, uint32_t h)
41 {
42  int nbits, sign, low, high, n;
43  // These are for handling even and odd rows.
44  int wo[2] = { 0, 0 };
45  int nw[2] = { 0, 0 };
46  int acarry[2][3], pred, diff;
47 
48  // The pitch is for the predictor: two row up.
49  int pitch = w * 2;
50 
51  /* Build a table to quickly look up "high" value */
52  char bittable[4096];
53  for (int i = 0; i < 4096; i++) {
54  int b = i;
55  for (high = 0; high < 12; high++) {
56  if ((b >> (11 - high)) & 1) {
57  break;
58  }
59  }
60  bittable[i] = high;
61  }
62 
63  buffer += 7;
64 
65  BitIterator bits(buffer, size - 7);
66 
67  for (uint32_t y = 0; y < h; y++) {
68  memset(acarry, 0, sizeof acarry);
69 
70  uint16_t* dest = &data16[(y * pitch)/2];
71  for (uint32_t x = 0; x < w / 2; x++) {
72  auto col = x * 2;
73  for (int p = 0; p < 2; p++) {
74  int i = 2 * (acarry[p][2] < 3);
75  for (nbits = 2 + i; (uint16_t)acarry[p][0] >> (nbits + i); nbits++) {
76  }
77 
78  uint32_t b = bits.peek(15);
79  sign = (b >> 14) * -1;
80  low = (b >> 12) & 3;
81  high = bittable[b & 4095];
82  // Skip bits used above.
83  bits.skip(std::min(12 + 3, high + 1 + 3));
84 
85  if (high == 12) {
86  high = bits.get(16 - nbits) >> 1;
87  }
88 
89  acarry[p][0] = (high << nbits) | bits.get(nbits);
90  diff = (acarry[p][0] ^ sign) + acarry[p][1];
91  acarry[p][1] = (diff * 3 + acarry[p][1]) >> 5;
92  acarry[p][2] = acarry[p][0] > 16 ? 0 : acarry[p][2] + 1;
93 
94  if (y < 2 || col < 2) {
95  if (y < 2 && col < 2) {
96  pred = 0;
97  } else if (y < 2) {
98  pred = wo[p];
99  } else {
100  // The (int) cast is required as col is unsigned
101  // and cause type promotion of the negative index.
102  pred = dest[-pitch + (int)(col + p)];
103  nw[p] = pred;
104  }
105  dest[col + p] = pred + ((diff << 2) | low);
106  // Set predictor
107  wo[p] = dest[col + p];
108  } else {
109  // See above for the cast.
110  n = dest[-pitch + (int)(col + p)];
111  if (((wo[p] < nw[p]) & (nw[p] < n)) | ((n < nw[p]) & (nw[p] < wo[p]))) {
112  if (abs(wo[p] - nw[p]) > 32 || abs(n - nw[p]) > 32) {
113  pred = wo[p] + n - nw[p];
114  } else {
115  pred = (wo[p] + n) >> 1;
116  }
117  } else {
118  pred = abs(wo[p] - nw[p]) > abs(n - nw[p]) ? wo[p] : n;
119  }
120 
121  dest[col + p] = pred + ((diff << 2) | low);
122  // Set predictors
123  wo[p] = dest[col + p];
124  nw[p] = n;
125  }
126  }
127  }
128  }
129 }
130 
132 {
133  RawDataPtr output(new RawData);
134 
135  output->allocData(m_w * m_h * 2);
136  decompressOlympus(m_buffer, m_size, (uint16_t*)output->data(), m_w, m_h);
137 
138  // hardcoded 12bits values
139  output->setBpc(12);
140  output->setWhiteLevel((1 << 12) - 1);
141 
142  return output;
143 }
144 
145 }
146 }
virtual RawDataPtr decompress() override
Represent camera raw data.
Definition: rawdata.hpp:38
Global namespace for libopenraw.
Definition: arwfile.cpp:29