1 /*
2     RawSpeed - RAW file decoder.
3 
4     Copyright (C) 2009-2014 Klaus Post
5     Copyright (C) 2017 Roman Lebedev
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Lesser General Public License for more details.
16 
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
22 #include "common/TableLookUp.h"
23 #include "common/Common.h"                // for clampBits
24 #include "decoders/RawDecoderException.h" // for ThrowRDE
25 #include <cassert>                        // for assert
26 #include <cstdint>                        // for uint16_t
27 #include <limits>                         // for numeric_limits
28 
29 namespace rawspeed {
30 
31 // How many different values can uint16_t represent?
32 constexpr int TABLE_MAX_ELTS = std::numeric_limits<uint16_t>::max() + 1;
33 constexpr int TABLE_SIZE = TABLE_MAX_ELTS * 2;
34 
35 // Creates n numre of tables.
TableLookUp(int _ntables,bool _dither)36 TableLookUp::TableLookUp(int _ntables, bool _dither)
37     : ntables(_ntables), dither(_dither) {
38   if (ntables < 1) {
39     ThrowRDE("Cannot construct 0 tables");
40   }
41   tables.resize(ntables * TABLE_SIZE, uint16_t(0));
42 }
43 
setTable(int ntable,const std::vector<uint16_t> & table)44 void TableLookUp::setTable(int ntable, const std::vector<uint16_t>& table) {
45   assert(!table.empty());
46 
47   const int nfilled = table.size();
48   if (nfilled > TABLE_MAX_ELTS)
49     ThrowRDE("Table lookup with %i entries is unsupported", nfilled);
50 
51   if (ntable > ntables) {
52     ThrowRDE("Table lookup with number greater than number of tables.");
53   }
54   uint16_t* t = &tables[ntable * TABLE_SIZE];
55   if (!dither) {
56     for (int i = 0; i < TABLE_MAX_ELTS; i++) {
57       t[i] = (i < nfilled) ? table[i] : table[nfilled - 1];
58     }
59     return;
60   }
61   for (int i = 0; i < nfilled; i++) {
62     int center = table[i];
63     int lower = i > 0 ? table[i - 1] : center;
64     int upper = i < (nfilled - 1) ? table[i + 1] : center;
65     int delta = upper - lower;
66     t[i * 2] = clampBits(center - ((upper - lower + 2) / 4), 16);
67     t[i * 2 + 1] = uint16_t(delta);
68     // FIXME: this is completely broken when the curve is non-monotonic.
69   }
70 
71   for (int i = nfilled; i < TABLE_MAX_ELTS; i++) {
72     t[i * 2] = table[nfilled - 1];
73     t[i * 2 + 1] = 0;
74   }
75   t[0] = t[1];
76   t[TABLE_SIZE - 1] = t[TABLE_SIZE - 2];
77 }
78 
getTable(int n)79 uint16_t* TableLookUp::getTable(int n) {
80   if (n > ntables) {
81     ThrowRDE("Table lookup with number greater than number of tables.");
82   }
83   return &tables[n * TABLE_SIZE];
84 }
85 
86 } // namespace rawspeed
87