1 /*
2 Copyright 2016 Esri
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 A local copy of the license and additional notices are located with the
17 source distribution at:
18
19 http://github.com/Esri/lerc/
20
21 Contributors: Thomas Maurer
22 */
23
24 #include "Defines.h"
25 #include "include/Lerc_c_api.h"
26 #include "include/Lerc_types.h"
27 #include "Lerc.h"
28
29 USING_NAMESPACE_LERC
30
31 // -------------------------------------------------------------------------- ;
32
lerc_computeCompressedSize(const void * pData,unsigned int dataType,int nDim,int nCols,int nRows,int nBands,int nMasks,const unsigned char * pValidBytes,double maxZErr,unsigned int * numBytes)33 lerc_status lerc_computeCompressedSize(const void* pData, unsigned int dataType, int nDim, int nCols, int nRows, int nBands,
34 int nMasks, const unsigned char* pValidBytes, double maxZErr, unsigned int* numBytes)
35 {
36 return lerc_computeCompressedSizeForVersion(pData, -1, dataType, nDim, nCols, nRows, nBands, nMasks, pValidBytes, maxZErr, numBytes);
37 }
38
39 // -------------------------------------------------------------------------- ;
40
lerc_computeCompressedSizeForVersion(const void * pData,int version,unsigned int dataType,int nDim,int nCols,int nRows,int nBands,int nMasks,const unsigned char * pValidBytes,double maxZErr,unsigned int * numBytes)41 lerc_status lerc_computeCompressedSizeForVersion(const void* pData, int version, unsigned int dataType, int nDim, int nCols, int nRows, int nBands,
42 int nMasks, const unsigned char* pValidBytes, double maxZErr, unsigned int* numBytes)
43 {
44 if (!numBytes)
45 return (lerc_status)ErrCode::WrongParam;
46
47 *numBytes = 0;
48
49 if (!pData || dataType >= Lerc::DT_Undefined || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || maxZErr < 0)
50 return (lerc_status)ErrCode::WrongParam;
51
52 if (!(nMasks == 0 || nMasks == 1 || nMasks == nBands) || (nMasks > 0 && !pValidBytes))
53 return (lerc_status)ErrCode::WrongParam;
54
55 Lerc::DataType dt = (Lerc::DataType)dataType;
56 return (lerc_status)Lerc::ComputeCompressedSize(pData, version, dt, nDim, nCols, nRows, nBands, nMasks, pValidBytes, maxZErr, *numBytes);
57 }
58
59 // -------------------------------------------------------------------------- ;
60
lerc_encode(const void * pData,unsigned int dataType,int nDim,int nCols,int nRows,int nBands,int nMasks,const unsigned char * pValidBytes,double maxZErr,unsigned char * pOutBuffer,unsigned int outBufferSize,unsigned int * nBytesWritten)61 lerc_status lerc_encode(const void* pData, unsigned int dataType, int nDim, int nCols, int nRows, int nBands,
62 int nMasks, const unsigned char* pValidBytes, double maxZErr, unsigned char* pOutBuffer, unsigned int outBufferSize,
63 unsigned int* nBytesWritten)
64 {
65 return lerc_encodeForVersion(pData, -1, dataType, nDim, nCols, nRows, nBands, nMasks, pValidBytes, maxZErr, pOutBuffer, outBufferSize, nBytesWritten);
66 }
67
68 // -------------------------------------------------------------------------- ;
69
lerc_encodeForVersion(const void * pData,int version,unsigned int dataType,int nDim,int nCols,int nRows,int nBands,int nMasks,const unsigned char * pValidBytes,double maxZErr,unsigned char * pOutBuffer,unsigned int outBufferSize,unsigned int * nBytesWritten)70 lerc_status lerc_encodeForVersion(const void* pData, int version, unsigned int dataType, int nDim, int nCols, int nRows, int nBands,
71 int nMasks, const unsigned char* pValidBytes, double maxZErr, unsigned char* pOutBuffer, unsigned int outBufferSize,
72 unsigned int* nBytesWritten)
73 {
74 if (!nBytesWritten)
75 return (lerc_status)ErrCode::WrongParam;
76
77 *nBytesWritten = 0;
78
79 if (!pData || dataType >= Lerc::DT_Undefined || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0 || maxZErr < 0 || !pOutBuffer || !outBufferSize)
80 return (lerc_status)ErrCode::WrongParam;
81
82 if (!(nMasks == 0 || nMasks == 1 || nMasks == nBands) || (nMasks > 0 && !pValidBytes))
83 return (lerc_status)ErrCode::WrongParam;
84
85 Lerc::DataType dt = (Lerc::DataType)dataType;
86 return (lerc_status)Lerc::Encode(pData, version, dt, nDim, nCols, nRows, nBands, nMasks, pValidBytes, maxZErr, pOutBuffer, outBufferSize, *nBytesWritten);
87 }
88
89 // -------------------------------------------------------------------------- ;
90
lerc_getBlobInfo(const unsigned char * pLercBlob,unsigned int blobSize,unsigned int * infoArray,double * dataRangeArray,int infoArraySize,int dataRangeArraySize)91 lerc_status lerc_getBlobInfo(const unsigned char* pLercBlob, unsigned int blobSize,
92 unsigned int* infoArray, double* dataRangeArray, int infoArraySize, int dataRangeArraySize)
93 {
94 if (!pLercBlob || !blobSize || (!infoArray && !dataRangeArray) || ((infoArraySize <= 0) && (dataRangeArraySize <= 0)))
95 return (lerc_status)ErrCode::WrongParam;
96
97 Lerc::LercInfo lercInfo;
98 ErrCode errCode = Lerc::GetLercInfo(pLercBlob, blobSize, lercInfo);
99 if (errCode != ErrCode::Ok)
100 return (lerc_status)errCode;
101
102 if (infoArray)
103 {
104 int i = 0, ias = infoArraySize;
105
106 if (ias > 0)
107 memset(infoArray, 0, ias * sizeof(infoArray[0]));
108
109 if (i < ias)
110 infoArray[i++] = (unsigned int)lercInfo.version;
111 if (i < ias)
112 infoArray[i++] = (unsigned int)lercInfo.dt;
113 if (i < ias)
114 infoArray[i++] = (unsigned int)lercInfo.nDim;
115 if (i < ias)
116 infoArray[i++] = (unsigned int)lercInfo.nCols;
117 if (i < ias)
118 infoArray[i++] = (unsigned int)lercInfo.nRows;
119 if (i < ias)
120 infoArray[i++] = (unsigned int)lercInfo.nBands;
121 if (i < ias)
122 infoArray[i++] = (unsigned int)lercInfo.numValidPixel;
123 if (i < ias)
124 infoArray[i++] = (unsigned int)lercInfo.blobSize;
125 if (i < ias)
126 infoArray[i++] = (unsigned int)lercInfo.nMasks;
127 }
128
129 if (dataRangeArray)
130 {
131 int i = 0, dras = dataRangeArraySize;
132
133 if (dras > 0)
134 memset(dataRangeArray, 0, dras * sizeof(dataRangeArray[0]));
135
136 if (i < dras)
137 dataRangeArray[i++] = lercInfo.zMin;
138 if (i < dras)
139 dataRangeArray[i++] = lercInfo.zMax;
140 if (i < dras)
141 dataRangeArray[i++] = lercInfo.maxZError;
142 }
143
144 return (lerc_status)ErrCode::Ok;
145 }
146
147 // -------------------------------------------------------------------------- ;
148
lerc_decode(const unsigned char * pLercBlob,unsigned int blobSize,int nMasks,unsigned char * pValidBytes,int nDim,int nCols,int nRows,int nBands,unsigned int dataType,void * pData)149 lerc_status lerc_decode(const unsigned char* pLercBlob, unsigned int blobSize, int nMasks,
150 unsigned char* pValidBytes, int nDim, int nCols, int nRows, int nBands, unsigned int dataType, void* pData)
151 {
152 if (!pLercBlob || !blobSize || !pData || dataType >= Lerc::DT_Undefined || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0)
153 return (lerc_status)ErrCode::WrongParam;
154
155 if (!(nMasks == 0 || nMasks == 1 || nMasks == nBands) || (nMasks > 0 && !pValidBytes))
156 return (lerc_status)ErrCode::WrongParam;
157
158 Lerc::DataType dt = (Lerc::DataType)dataType;
159
160 ErrCode errCode = Lerc::Decode(pLercBlob, blobSize, nMasks, pValidBytes, nDim, nCols, nRows, nBands, dt, pData);
161 if (errCode != ErrCode::Ok)
162 return (lerc_status)errCode;
163
164 return (lerc_status)ErrCode::Ok;
165 }
166
167 // -------------------------------------------------------------------------- ;
168
lerc_decodeToDouble(const unsigned char * pLercBlob,unsigned int blobSize,int nMasks,unsigned char * pValidBytes,int nDim,int nCols,int nRows,int nBands,double * pData)169 lerc_status lerc_decodeToDouble(const unsigned char* pLercBlob, unsigned int blobSize, int nMasks,
170 unsigned char* pValidBytes, int nDim, int nCols, int nRows, int nBands, double* pData)
171 {
172 if (!pLercBlob || !blobSize || !pData || nDim <= 0 || nCols <= 0 || nRows <= 0 || nBands <= 0)
173 return (lerc_status)ErrCode::WrongParam;
174
175 if (!(nMasks == 0 || nMasks == 1 || nMasks == nBands) || (nMasks > 0 && !pValidBytes))
176 return (lerc_status)ErrCode::WrongParam;
177
178 Lerc::LercInfo lercInfo;
179 ErrCode errCode;
180 if ((errCode = Lerc::GetLercInfo(pLercBlob, blobSize, lercInfo)) != ErrCode::Ok)
181 return (lerc_status)errCode;
182
183 Lerc::DataType dt = lercInfo.dt;
184 if (dt > Lerc::DT_Double)
185 return (lerc_status)ErrCode::Failed;
186
187 if (dt == Lerc::DT_Double)
188 {
189 if ((errCode = Lerc::Decode(pLercBlob, blobSize, nMasks, pValidBytes, nDim, nCols, nRows, nBands, dt, pData)) != ErrCode::Ok)
190 return (lerc_status)errCode;
191 }
192 else
193 {
194 // use the buffer passed for in place decode and convert
195 int sizeofDt[] = { 1, 1, 2, 2, 4, 4, 4, 8 };
196 size_t nDataValues = nDim * nCols * nRows * nBands;
197 void* ptrDec = (Byte*)pData + nDataValues * (sizeof(double) - sizeofDt[dt]);
198
199 if ((errCode = Lerc::Decode(pLercBlob, blobSize, nMasks, pValidBytes, nDim, nCols, nRows, nBands, dt, ptrDec)) != ErrCode::Ok)
200 return (lerc_status)errCode;
201
202 if ((errCode = Lerc::ConvertToDouble(ptrDec, dt, nDataValues, pData)) != ErrCode::Ok)
203 return (lerc_status)errCode;
204 }
205
206 return (lerc_status)ErrCode::Ok;
207 }
208
209 // -------------------------------------------------------------------------- ;
210
211