1 //
2 // (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
3 //
4 
5 #include "util.h"
6 #include "decoderstrategy.h"
7 #include "encoderstrategy.h"
8 #include "lookuptable.h"
9 #include "losslesstraits.h"
10 #include "defaulttraits.h"
11 #include "jlscodecfactory.h"
12 #include "jpegstreamreader.h"
13 
14 #include <cstdio>
15 #include <vector>
16 
17 
18 using namespace std;
19 using namespace charls;
20 
21 
22 // As defined in the JPEG-LS standard
23 
24 // used to determine how large runs should be encoded at a time.
25 const int J[32] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15};
26 
27 #include "scan.h"
28 
29 
30 // Visual Studio 2013 does not supports the keyword noexcept. But it has the macro _NOEXCEPT.
31 #ifndef _NOEXCEPT
32 #define _NOEXCEPT noexcept
33 #endif
34 
35 
36 class charls_category : public error_category {
37 public:
name() const38     const char* name() const _NOEXCEPT override
39     {
40         return "charls";
41     }
42 
message(int) const43     string message(int /* errval */) const override
44     {
45         return "CharLS error";
46     }
47 };
48 
49 
CharLSCategoryInstance()50 const error_category& CharLSCategoryInstance()
51 {
52     static charls_category instance;
53     return instance;
54 }
55 
56 
QuantizeGratientOrg(const JlsCustomParameters & preset,int32_t NEAR,int32_t Di)57 signed char QuantizeGratientOrg(const JlsCustomParameters& preset, int32_t NEAR, int32_t Di)
58 {
59     if (Di <= -preset.T3) return  -4;
60     if (Di <= -preset.T2) return  -3;
61     if (Di <= -preset.T1) return  -2;
62     if (Di < -NEAR)  return  -1;
63     if (Di <=  NEAR) return   0;
64     if (Di < preset.T1)   return   1;
65     if (Di < preset.T2)   return   2;
66     if (Di < preset.T3)   return   3;
67 
68     return  4;
69 }
70 
71 
CreateQLutLossless(int32_t cbit)72 vector<signed char> CreateQLutLossless(int32_t cbit)
73 {
74     JlsCustomParameters preset = ComputeDefault((1 << cbit) - 1, 0);
75     int32_t range = preset.MAXVAL + 1;
76 
77     vector<signed char> lut(range * 2);
78 
79     for (int32_t diff = -range; diff < range; diff++)
80     {
81         lut[range + diff] = QuantizeGratientOrg(preset, 0,diff);
82     }
83     return lut;
84 }
85 
86 // Lookup tables to replace code with lookup tables.
87 // To avoid threading issues, all tables are created when the program is loaded.
88 
89 
90 // Lookup table: decode symbols that are smaller or equal to 8 bit (16 tables for each value of k)
91 CTable decodingTables[16] = { InitTable(0), InitTable(1), InitTable(2), InitTable(3),
92                               InitTable(4), InitTable(5), InitTable(6), InitTable(7),
93                               InitTable(8), InitTable(9), InitTable(10), InitTable(11),
94                               InitTable(12), InitTable(13), InitTable(14),InitTable(15) };
95 
96 
97 // Lookup tables: sample differences to bin indexes.
98 vector<signed char> rgquant8Ll = CreateQLutLossless(8);
99 vector<signed char> rgquant10Ll = CreateQLutLossless(10);
100 vector<signed char> rgquant12Ll = CreateQLutLossless(12);
101 vector<signed char> rgquant16Ll = CreateQLutLossless(16);
102 
103 
104 template<typename STRATEGY>
GetCodec(const JlsParameters & params,const JlsCustomParameters & presets)105 unique_ptr<STRATEGY> JlsCodecFactory<STRATEGY>::GetCodec(const JlsParameters& params, const JlsCustomParameters& presets)
106 {
107     unique_ptr<STRATEGY> strategy;
108 
109     if (presets.RESET != 0 && presets.RESET != BASIC_RESET)
110     {
111         DefaultTraitsT<uint8_t, uint8_t> traits((1 << params.bitsPerSample) - 1, params.allowedLossyError, presets.RESET);
112         traits.MAXVAL = presets.MAXVAL;
113         strategy = std::unique_ptr<STRATEGY>(new JlsCodec<DefaultTraitsT<uint8_t, uint8_t>, STRATEGY>(traits, params));
114     }
115     else
116     {
117         strategy = GetCodecImpl(params);
118     }
119 
120     if (strategy)
121     {
122         strategy->SetPresets(presets);
123     }
124     return strategy;
125 }
126 
127 
128 template<typename TRAITS, typename STRATEGY>
CreateCodec(const TRAITS & t,const STRATEGY *,const JlsParameters & params)129 unique_ptr<STRATEGY> CreateCodec(const TRAITS& t, const STRATEGY*, const JlsParameters& params)
130 {
131     return unique_ptr<STRATEGY>(new JlsCodec<TRAITS, STRATEGY>(t, params));
132 }
133 
134 
135 template<typename STRATEGY>
GetCodecImpl(const JlsParameters & params)136 unique_ptr<STRATEGY> JlsCodecFactory<STRATEGY>::GetCodecImpl(const JlsParameters& params)
137 {
138     STRATEGY* s = nullptr;
139 
140     if (params.interleaveMode == InterleaveMode::Sample && params.components != 3)
141         return nullptr;
142 
143 #ifndef DISABLE_SPECIALIZATIONS
144 
145     // optimized lossless versions common formats
146     if (params.allowedLossyError == 0)
147     {
148         if (params.interleaveMode == InterleaveMode::Sample)
149         {
150             if (params.bitsPerSample == 8)
151                 return CreateCodec(LosslessTraitsT<Triplet<uint8_t>, 8>(), s, params);
152         }
153         else
154         {
155             switch (params.bitsPerSample)
156             {
157                 case  8: return CreateCodec(LosslessTraitsT<uint8_t, 8>(), s, params);
158                 case 12: return CreateCodec(LosslessTraitsT<uint16_t, 12>(), s, params);
159                 case 16: return CreateCodec(LosslessTraitsT<uint16_t, 16>(), s, params);
160             }
161         }
162     }
163 
164 #endif
165 
166     int maxval = (1 << params.bitsPerSample) - 1;
167 
168     if (params.bitsPerSample <= 8)
169     {
170         if (params.interleaveMode == InterleaveMode::Sample)
171             return CreateCodec(DefaultTraitsT<uint8_t, Triplet<uint8_t> >(maxval, params.allowedLossyError), s, params);
172 
173         return CreateCodec(DefaultTraitsT<uint8_t, uint8_t>((1 << params.bitsPerSample) - 1, params.allowedLossyError), s, params);
174     }
175     if (params.bitsPerSample <= 16)
176     {
177         if (params.interleaveMode == InterleaveMode::Sample)
178             return CreateCodec(DefaultTraitsT<uint16_t,Triplet<uint16_t> >(maxval, params.allowedLossyError), s, params);
179 
180         return CreateCodec(DefaultTraitsT<uint16_t, uint16_t>(maxval, params.allowedLossyError), s, params);
181     }
182     return nullptr;
183 }
184 
185 
186 template class JlsCodecFactory<DecoderStrategy>;
187 template class JlsCodecFactory<EncoderStrategy>;
188