RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
PentaxDecompressor.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
22#include "adt/Array1DRef.h"
23#include "adt/Array2DRef.h"
24#include "adt/Bit.h"
25#include "adt/Casts.h"
26#include "adt/Invariant.h"
27#include "adt/Optional.h"
28#include "adt/Point.h"
31#include "codes/HuffmanCode.h"
33#include "common/RawImage.h"
35#include "io/Buffer.h"
36#include "io/ByteStream.h"
37#include <array>
38#include <cassert>
39#include <cstdint>
40#include <utility>
41#include <vector>
42
43namespace rawspeed {
44
45// 16 entries of codes per bit length
46// 13 entries of code values
47const std::array<std::array<std::array<uint8_t, 16>, 2>, 1>
49 {{{0, 2, 3, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
50 {3, 4, 2, 5, 1, 6, 0, 7, 8, 9, 10, 11, 12}}},
51 }};
52
54 Optional<ByteStream> metaData)
55 : mRaw(std::move(img)), ht(SetupPrefixCodeDecoder(metaData)) {
56 if (mRaw->getCpp() != 1 || mRaw->getDataType() != RawImageType::UINT16 ||
57 mRaw->getBpp() != sizeof(uint16_t))
58 ThrowRDE("Unexpected component count / data type");
59
60 if (!mRaw->dim.x || !mRaw->dim.y || mRaw->dim.x % 2 != 0 ||
61 mRaw->dim.x > 8384 || mRaw->dim.y > 6208) {
62 ThrowRDE("Unexpected image dimensions found: (%d; %d)", mRaw->dim.x,
63 mRaw->dim.y);
64 }
65}
66
69 // Temporary table, used during parsing LJpeg.
71
72 /* Initialize with legacy data */
73 auto nCodes = hc.setNCodesPerLength(Buffer(pentax_tree[0][0].data(), 16));
74 invariant(nCodes == 13); // see pentax_tree definition
75 hc.setCodeValues(Array1DRef<const uint8_t>(pentax_tree[0][1].data(), nCodes));
76
77 return hc;
78}
79
82 // Temporary table, used during parsing LJpeg.
84
85 const uint32_t depth = stream.getU16() + 12;
86 if (depth > 15)
87 ThrowRDE("Depth of huffman table is too great (%u).", depth);
88
89 stream.skipBytes(12);
90
91 std::array<uint32_t, 16> v0;
92 std::array<uint32_t, 16> v1;
93 for (uint32_t i = 0; i < depth; i++)
94 v0[i] = stream.getU16();
95 for (uint32_t i = 0; i < depth; i++) {
96 v1[i] = stream.getByte();
97
98 if (v1[i] == 0 || v1[i] > 12)
99 ThrowRDE("Data corrupt: v1[%u]=%u, expected [1..12]", depth, v1[i]);
100 }
101
102 std::vector<uint8_t> nCodesPerLength;
103 nCodesPerLength.resize(17);
104
105 std::array<uint32_t, 16> v2;
106 /* Calculate codes and store bitcounts */
107 for (uint32_t c = 0; c < depth; c++) {
108 v2[c] = extractHighBits(v0[c], v1[c], /*effectiveBitwidth=*/12);
109 nCodesPerLength.at(v1[c])++;
110 }
111
112 assert(nCodesPerLength.size() == 17);
113 assert(nCodesPerLength[0] == 0);
114 auto nCodes = hc.setNCodesPerLength(Buffer(&nCodesPerLength[1], 16));
115 invariant(nCodes == depth);
116
117 std::vector<uint8_t> codeValues;
118 codeValues.reserve(nCodes);
119
120 /* Find smallest */
121 for (uint32_t i = 0; i < depth; i++) {
122 uint32_t sm_val = 0xfffffff;
123 uint32_t sm_num = 0xff;
124 for (uint32_t j = 0; j < depth; j++) {
125 if (v2[j] <= sm_val) {
126 sm_num = j;
127 sm_val = v2[j];
128 }
129 }
130 invariant(sm_num < 16);
131 codeValues.push_back(implicit_cast<uint8_t>(sm_num));
132 v2[sm_num] = 0xffffffff;
133 }
134
135 assert(codeValues.size() == nCodes);
136 hc.setCodeValues(Array1DRef<const uint8_t>(codeValues.data(), nCodes));
137
138 return hc;
139}
140
144
145 if (metaData)
146 hc = SetupPrefixCodeDecoder_Modern(*metaData);
147 else
149
150 PrefixCodeDecoder<> ht(std::move(*hc));
151 ht.setup(true, false);
152
153 return ht;
154}
155
157 const Array2DRef<uint16_t> out(mRaw->getU16DataAsUncroppedArray2DRef());
158
159 invariant(out.height() > 0);
160 invariant(out.width() > 0);
161 invariant(out.width() % 2 == 0);
162
164 for (int row = 0; row < out.height(); row++) {
165 std::array<int, 2> pred = {{}};
166 if (row >= 2)
167 pred = {out(row - 2, 0), out(row - 2, 1)};
168
169 for (int col = 0; col < out.width(); col++) {
170 pred[col & 1] += ht.decodeDifference(bs);
171 int value = pred[col & 1];
172 if (!isIntN(value, 16))
173 ThrowRDE("decoded value out of bounds at %d:%d", col, row);
174 out(row, col) = implicit_cast<uint16_t>(value);
175 }
176 }
177}
178
179} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
#define ThrowRDE(...)
assert(dim.area() >=area)
int RAWSPEED_READONLY height() const
int RAWSPEED_READONLY width() const
Array1DRef< const uint8_t > getAsArray1DRef() const
Definition Buffer.h:70
void skipBytes(size_type nbytes)
Definition ByteStream.h:130
Buffer peekRemainingBuffer() const
Definition ByteStream.h:108
uint32_t setNCodesPerLength(Buffer data)
Definition HuffmanCode.h:99
void setCodeValues(Array1DRef< const typename Traits::CodeValueTy > data)
static const std::array< std::array< std::array< uint8_t, 16 >, 2 >, 1 > pentax_tree
void decompress(ByteStream data) const
static PrefixCodeDecoder SetupPrefixCodeDecoder(Optional< ByteStream > metaData)
static HuffmanCode< BaselineCodeTag > SetupPrefixCodeDecoder_Modern(ByteStream stream)
const PrefixCodeDecoder ht
PentaxDecompressor(RawImage img, Optional< ByteStream > metaData)
static HuffmanCode< BaselineCodeTag > SetupPrefixCodeDecoder_Legacy()
PrefixCodeLUTDecoder< CodeTag, PrefixCodeLookupDecoder< CodeTag > > PrefixCodeDecoder
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
constexpr bool RAWSPEED_READNONE isIntN(T value, unsigned int nBits)
Definition Bit.h:87
constexpr RAWSPEED_READNONE T extractHighBits(T value, unsigned nBits, unsigned effectiveBitwidth=bitwidth< T >())
Definition Bit.h:120