source: thirdparty/SZ/sz/src/szd_double.c @ 2c47b73

Revision 2c47b73, 57.1 KB checked in by Hal Finkel <hfinkel@…>, 6 years ago (diff)

more work on adding SZ (latest version)

  • Property mode set to 100644
RevLine 
[2c47b73]1/**
2 *  @file szd_double.c
3 *  @author Sheng Di and Dingwen Tao
4 *  @date Aug, 2016
5 *  @brief
6 *  (C) 2016 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
7 *      See COPYRIGHT in top-level directory.
8 */
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include "szd_double.h"
14#include "TightDataPointStorageD.h"
15#include "sz.h"
16#include "Huffman.h"
17#include "szd_double_pwr.h"
18#include "szd_double_ts.h"
19
20int SZ_decompress_args_double(double** newData, size_t r5, size_t r4, size_t r3, size_t r2, size_t r1, unsigned char* cmpBytes, size_t cmpSize)
21{
22        int status = SZ_SCES;
23        size_t dataLength = computeDataLength(r5,r4,r3,r2,r1);
24       
25        //unsigned char* tmpBytes;
26        size_t targetUncompressSize = dataLength <<3; //i.e., *8
27        //tmpSize must be "much" smaller than dataLength
28        size_t i, tmpSize = 12+MetaDataByteLength+exe_params->SZ_SIZE_TYPE;
29        unsigned char* szTmpBytes;
30        if(cmpSize!=12+4+MetaDataByteLength && cmpSize!=12+8+MetaDataByteLength)
31        {
32                int isZlib = isZlibFormat(cmpBytes[0], cmpBytes[1]);
33                if(confparams_dec->szMode!=SZ_TEMPORAL_COMPRESSION)
34                {
35                        if(isZlib)
36                                confparams_dec->szMode = SZ_BEST_COMPRESSION;
37                        else
38                                confparams_dec->szMode = SZ_BEST_SPEED;                 
39                }
40                if(confparams_dec->szMode==SZ_BEST_SPEED)
41                {
42                        tmpSize = cmpSize;
43                        szTmpBytes = cmpBytes; 
44                }       
45                else if(confparams_dec->szMode==SZ_BEST_COMPRESSION || confparams_dec->szMode==SZ_DEFAULT_COMPRESSION || confparams_dec->szMode==SZ_TEMPORAL_COMPRESSION)
46                {
47                        if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
48                                targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES;                     
49                        tmpSize = zlib_uncompress5(cmpBytes, (unsigned long)cmpSize, &szTmpBytes, (unsigned long)targetUncompressSize+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE);                   
50                        //szTmpBytes = (unsigned char*)malloc(sizeof(unsigned char)*tmpSize);
51                        //memcpy(szTmpBytes, tmpBytes, tmpSize);
52                        //free(tmpBytes); //release useless memory             
53                }
54                else
55                {
56                        printf("Wrong value of confparams_dec->szMode in the double compressed bytes.\n");
57                        status = SZ_MERR;
58                        return status;
59                }       
60        }
61        else
62                szTmpBytes = cmpBytes;
63        //TODO: convert szTmpBytes to double array.
64        TightDataPointStorageD* tdps;
65        int errBoundMode = new_TightDataPointStorageD_fromFlatBytes(&tdps, szTmpBytes, tmpSize);
66
67        int dim = computeDimension(r5,r4,r3,r2,r1);
68        int doubleSize = sizeof(double);
69        if(tdps->isLossless)
70        {
71                *newData = (double*)malloc(doubleSize*dataLength);
72                if(sysEndianType==BIG_ENDIAN_SYSTEM)
73                {
74                        memcpy(*newData, szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE, dataLength*doubleSize);
75                }
76                else
77                {
78                        unsigned char* p = szTmpBytes+4+MetaDataByteLength+exe_params->SZ_SIZE_TYPE;
79                        for(i=0;i<dataLength;i++,p+=doubleSize)
80                                (*newData)[i] = bytesToDouble(p);
81                }               
82        }
83        else if (dim == 1)
84                getSnapshotData_double_1D(newData,r1,tdps, errBoundMode);
85        else
86        if (dim == 2)
87                getSnapshotData_double_2D(newData,r2,r1,tdps, errBoundMode);
88        else
89        if (dim == 3)
90                getSnapshotData_double_3D(newData,r3,r2,r1,tdps, errBoundMode);
91        else
92        if (dim == 4)
93                getSnapshotData_double_4D(newData,r4,r3,r2,r1,tdps, errBoundMode);
94        else
95        {
96                printf("Error: currently support only at most 4 dimensions!\n");
97                status = SZ_DERR;
98        }
99        free_TightDataPointStorageD2(tdps);
100        if(confparams_dec->szMode!=SZ_BEST_SPEED && cmpSize!=12+MetaDataByteLength+exe_params->SZ_SIZE_TYPE)
101                free(szTmpBytes);       
102        return status;
103}
104
105void decompressDataSeries_double_1D(double** data, size_t dataSeriesLength, TightDataPointStorageD* tdps) 
106{
107        updateQuantizationInfo(tdps->intervals);
108        size_t i, j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
109                                                                // in resiMidBits, p is to track the
110                                                                // byte_index of resiMidBits, l is for
111                                                                // leadNum
112        unsigned char* leadNum;
113        double interval = tdps->realPrecision*2;
114       
115        convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
116        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
117
118        int* type = (int*)malloc(dataSeriesLength*sizeof(int));
119
120        HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
121        decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
122        SZ_ReleaseHuffman(huffmanTree); 
123       
124        unsigned char preBytes[8];
125        unsigned char curBytes[8];
126       
127        memset(preBytes, 0, 8);
128
129        size_t curByteIndex = 0;
130        int reqBytesLength, resiBitsLength, resiBits; 
131        unsigned char leadingNum;       
132        double medianValue, exactData, predValue;
133       
134        reqBytesLength = tdps->reqLength/8;
135        resiBitsLength = tdps->reqLength%8;
136        medianValue = tdps->medianValue;
137       
138        int type_;
139        for (i = 0; i < dataSeriesLength; i++) {
140                type_ = type[i];
141                switch (type_) {
142                case 0:
143                        // compute resiBits
144                        resiBits = 0;
145                        if (resiBitsLength != 0) {
146                                int kMod8 = k % 8;
147                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
148                                if (rightMovSteps > 0) {
149                                        int code = getRightMovingCode(kMod8, resiBitsLength);
150                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
151                                } else if (rightMovSteps < 0) {
152                                        int code1 = getLeftMovingCode(kMod8);
153                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
154                                        int leftMovSteps = -rightMovSteps;
155                                        rightMovSteps = 8 - leftMovSteps;
156                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
157                                        p++;
158                                        resiBits = resiBits
159                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
160                                } else // rightMovSteps == 0
161                                {
162                                        int code = getRightMovingCode(kMod8, resiBitsLength);
163                                        resiBits = (tdps->residualMidBits[p] & code);
164                                        p++;
165                                }
166                                k += resiBitsLength;
167                        }
168
169                        // recover the exact data
170                        memset(curBytes, 0, 8);
171                        leadingNum = leadNum[l++];
172                        memcpy(curBytes, preBytes, leadingNum);
173                        for (j = leadingNum; j < reqBytesLength; j++)
174                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
175                        if (resiBitsLength != 0) {
176                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
177                                curBytes[reqBytesLength] = resiByte;
178                        }
179                       
180                        exactData = bytesToDouble(curBytes);
181                        (*data)[i] = exactData + medianValue;
182                        memcpy(preBytes,curBytes,8);
183                        break;
184                default:
185                        //predValue = 2 * (*data)[i-1] - (*data)[i-2];
186                        predValue = (*data)[i-1];
187                        (*data)[i] = predValue + (type_-exe_params->intvRadius)*interval;
188                        break;
189                }
190                //printf("%.30G\n",(*data)[i]);
191        }
192       
193#ifdef HAVE_TIMECMPR   
194        if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
195                memcpy(multisteps->hist_data, (*data), dataSeriesLength*sizeof(double));
196#endif 
197       
198        free(leadNum);
199        free(type);
200        return;
201}
202
203void decompressDataSeries_double_2D(double** data, size_t r1, size_t r2, TightDataPointStorageD* tdps) 
204{
205        updateQuantizationInfo(tdps->intervals);
206        //printf("tdps->intervals=%d, exe_params->intvRadius=%d\n", tdps->intervals, exe_params->intvRadius);
207       
208        size_t j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
209        // in resiMidBits, p is to track the
210        // byte_index of resiMidBits, l is for
211        // leadNum
212        size_t dataSeriesLength = r1*r2;
213        //      printf ("%d %d\n", r1, r2);
214
215        unsigned char* leadNum;
216        double realPrecision = tdps->realPrecision;
217
218        convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
219
220        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
221
222        int* type = (int*)malloc(dataSeriesLength*sizeof(int));
223
224        HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
225        decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
226        SZ_ReleaseHuffman(huffmanTree); 
227
228        unsigned char preBytes[8];
229        unsigned char curBytes[8];
230
231        memset(preBytes, 0, 8);
232
233        size_t curByteIndex = 0;
234        int reqBytesLength, resiBitsLength, resiBits; 
235        unsigned char leadingNum;       
236        double medianValue, exactData;
237        int type_;
238
239        reqBytesLength = tdps->reqLength/8;
240        resiBitsLength = tdps->reqLength%8;
241        medianValue = tdps->medianValue;
242
243        double pred1D, pred2D;
244        size_t ii, jj;
245
246        /* Process Row-0, data 0 */
247
248        // compute resiBits
249        resiBits = 0;
250        if (resiBitsLength != 0) {
251                int kMod8 = k % 8;
252                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
253                if (rightMovSteps > 0) {
254                        int code = getRightMovingCode(kMod8, resiBitsLength);
255                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
256                } else if (rightMovSteps < 0) {
257                        int code1 = getLeftMovingCode(kMod8);
258                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
259                        int leftMovSteps = -rightMovSteps;
260                        rightMovSteps = 8 - leftMovSteps;
261                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
262                        p++;
263                        resiBits = resiBits
264                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
265                } else // rightMovSteps == 0
266                {
267                        int code = getRightMovingCode(kMod8, resiBitsLength);
268                        resiBits = (tdps->residualMidBits[p] & code);
269                        p++;
270                }
271                k += resiBitsLength;
272        }
273
274        // recover the exact data
275        memset(curBytes, 0, 8);
276        leadingNum = leadNum[l++];
277        memcpy(curBytes, preBytes, leadingNum);
278        for (j = leadingNum; j < reqBytesLength; j++)
279                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
280        if (resiBitsLength != 0) {
281                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
282                curBytes[reqBytesLength] = resiByte;
283        }
284
285        exactData = bytesToDouble(curBytes);
286        (*data)[0] = exactData + medianValue;
287        memcpy(preBytes,curBytes,8);
288
289        /* Process Row-0, data 1 */
290        type_ = type[1]; 
291        if (type_ != 0)
292        {
293                pred1D = (*data)[0];
294                (*data)[1] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
295        }
296        else
297        {
298                // compute resiBits
299                resiBits = 0;
300                if (resiBitsLength != 0) {
301                        int kMod8 = k % 8;
302                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
303                        if (rightMovSteps > 0) {
304                                int code = getRightMovingCode(kMod8, resiBitsLength);
305                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
306                        } else if (rightMovSteps < 0) {
307                                int code1 = getLeftMovingCode(kMod8);
308                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
309                                int leftMovSteps = -rightMovSteps;
310                                rightMovSteps = 8 - leftMovSteps;
311                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
312                                p++;
313                                resiBits = resiBits
314                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
315                        } else // rightMovSteps == 0
316                        {
317                                int code = getRightMovingCode(kMod8, resiBitsLength);
318                                resiBits = (tdps->residualMidBits[p] & code);
319                                p++;
320                        }
321                        k += resiBitsLength;
322                }
323
324                // recover the exact data
325                memset(curBytes, 0, 8);
326                leadingNum = leadNum[l++];
327                memcpy(curBytes, preBytes, leadingNum);
328                for (j = leadingNum; j < reqBytesLength; j++)
329                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
330                if (resiBitsLength != 0) {
331                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
332                        curBytes[reqBytesLength] = resiByte;
333                }
334               
335                exactData = bytesToDouble(curBytes);
336                (*data)[1] = exactData + medianValue;
337                memcpy(preBytes,curBytes,8);
338        }
339
340        /* Process Row-0, data 2 --> data r2-1 */
341        for (jj = 2; jj < r2; jj++)
342        {
343                type_ = type[jj];
344                if (type_ != 0)
345                {
346                        pred1D = 2*(*data)[jj-1] - (*data)[jj-2];                       
347                        (*data)[jj] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
348                }
349                else
350                {
351                        // compute resiBits
352                        resiBits = 0;
353                        if (resiBitsLength != 0) {
354                                int kMod8 = k % 8;
355                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
356                                if (rightMovSteps > 0) {
357                                        int code = getRightMovingCode(kMod8, resiBitsLength);
358                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
359                                } else if (rightMovSteps < 0) {
360                                        int code1 = getLeftMovingCode(kMod8);
361                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
362                                        int leftMovSteps = -rightMovSteps;
363                                        rightMovSteps = 8 - leftMovSteps;
364                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
365                                        p++;
366                                        resiBits = resiBits
367                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
368                                } else // rightMovSteps == 0
369                                {
370                                        int code = getRightMovingCode(kMod8, resiBitsLength);
371                                        resiBits = (tdps->residualMidBits[p] & code);
372                                        p++;
373                                }
374                                k += resiBitsLength;
375                        }
376
377                        // recover the exact data
378                        memset(curBytes, 0, 8);
379                        leadingNum = leadNum[l++];
380                        memcpy(curBytes, preBytes, leadingNum);
381                        for (j = leadingNum; j < reqBytesLength; j++)
382                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
383                        if (resiBitsLength != 0) {
384                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
385                                curBytes[reqBytesLength] = resiByte;
386                        }
387
388                        exactData = bytesToDouble(curBytes);
389                        (*data)[jj] = exactData + medianValue;
390                        memcpy(preBytes,curBytes,8);
391                }
392        }
393
394        size_t index;
395        /* Process Row-1 --> Row-r1-1 */
396        for (ii = 1; ii < r1; ii++)
397        {
398                /* Process row-ii data 0 */
399                index = ii*r2;
400
401                type_ = type[index];
402                if (type_ != 0)
403                {
404                        pred1D = (*data)[index-r2];
405                        (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
406                }
407                else
408                {
409                        // compute resiBits
410                        resiBits = 0;
411                        if (resiBitsLength != 0) {
412                                int kMod8 = k % 8;
413                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
414                                if (rightMovSteps > 0) {
415                                        int code = getRightMovingCode(kMod8, resiBitsLength);
416                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
417                                } else if (rightMovSteps < 0) {
418                                        int code1 = getLeftMovingCode(kMod8);
419                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
420                                        int leftMovSteps = -rightMovSteps;
421                                        rightMovSteps = 8 - leftMovSteps;
422                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
423                                        p++;
424                                        resiBits = resiBits
425                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
426                                } else // rightMovSteps == 0
427                                {
428                                        int code = getRightMovingCode(kMod8, resiBitsLength);
429                                        resiBits = (tdps->residualMidBits[p] & code);
430                                        p++;
431                                }
432                                k += resiBitsLength;
433                        }
434
435                        // recover the exact data
436                        memset(curBytes, 0, 8);
437                        leadingNum = leadNum[l++];
438                        memcpy(curBytes, preBytes, leadingNum);
439                        for (j = leadingNum; j < reqBytesLength; j++)
440                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
441                        if (resiBitsLength != 0) {
442                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
443                                curBytes[reqBytesLength] = resiByte;
444                        }
445
446                        exactData = bytesToDouble(curBytes);
447                        (*data)[index] = exactData + medianValue;
448                        memcpy(preBytes,curBytes,8);
449                }
450
451                /* Process row-ii data 1 --> r2-1*/
452                for (jj = 1; jj < r2; jj++)
453                {
454                        index = ii*r2+jj;
455                        pred2D = (*data)[index-1] + (*data)[index-r2] - (*data)[index-r2-1];
456
457                        type_ = type[index];
458                        if (type_ != 0)
459                        {
460                                (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
461                        }
462                        else
463                        {
464                                // compute resiBits
465                                resiBits = 0;
466                                if (resiBitsLength != 0) {
467                                        int kMod8 = k % 8;
468                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
469                                        if (rightMovSteps > 0) {
470                                                int code = getRightMovingCode(kMod8, resiBitsLength);
471                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
472                                        } else if (rightMovSteps < 0) {
473                                                int code1 = getLeftMovingCode(kMod8);
474                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
475                                                int leftMovSteps = -rightMovSteps;
476                                                rightMovSteps = 8 - leftMovSteps;
477                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
478                                                p++;
479                                                resiBits = resiBits
480                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
481                                        } else // rightMovSteps == 0
482                                        {
483                                                int code = getRightMovingCode(kMod8, resiBitsLength);
484                                                resiBits = (tdps->residualMidBits[p] & code);
485                                                p++;
486                                        }
487                                        k += resiBitsLength;
488                                }
489
490                                // recover the exact data
491                                memset(curBytes, 0, 8);
492                                leadingNum = leadNum[l++];
493                                memcpy(curBytes, preBytes, leadingNum);
494                                for (j = leadingNum; j < reqBytesLength; j++)
495                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
496                                if (resiBitsLength != 0) {
497                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
498                                        curBytes[reqBytesLength] = resiByte;
499                                }
500
501                                exactData = bytesToDouble(curBytes);
502                                (*data)[index] = exactData + medianValue;
503                                memcpy(preBytes,curBytes,8);
504                        }
505                }
506        }
507
508#ifdef HAVE_TIMECMPR   
509        if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
510                memcpy(multisteps->hist_data, (*data), dataSeriesLength*sizeof(double));
511#endif 
512
513        free(leadNum);
514        free(type);
515        return;
516}
517
518void decompressDataSeries_double_3D(double** data, size_t r1, size_t r2, size_t r3, TightDataPointStorageD* tdps) 
519{
520        updateQuantizationInfo(tdps->intervals);
521        size_t j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
522        // in resiMidBits, p is to track the
523        // byte_index of resiMidBits, l is for
524        // leadNum
525        size_t dataSeriesLength = r1*r2*r3;
526        size_t r23 = r2*r3;
527//      printf ("%d %d %d\n", r1, r2, r3);
528
529        unsigned char* leadNum;
530        double realPrecision = tdps->realPrecision;
531
532        convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
533
534        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
535
536        int* type = (int*)malloc(dataSeriesLength*sizeof(int));
537
538        HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
539        decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
540        SZ_ReleaseHuffman(huffmanTree); 
541
542        unsigned char preBytes[8];
543        unsigned char curBytes[8];
544
545        memset(preBytes, 0, 8);
546
547        size_t curByteIndex = 0;
548        int reqBytesLength, resiBitsLength, resiBits;
549        unsigned char leadingNum;
550        double medianValue, exactData;
551        int type_;
552
553        reqBytesLength = tdps->reqLength/8;
554        resiBitsLength = tdps->reqLength%8;
555        medianValue = tdps->medianValue;
556
557        double pred1D, pred2D, pred3D;
558        size_t ii, jj, kk;
559
560        ///////////////////////////     Process layer-0 ///////////////////////////
561        /* Process Row-0 data 0*/
562        // compute resiBits
563        resiBits = 0;
564        if (resiBitsLength != 0) {
565                int kMod8 = k % 8;
566                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
567                if (rightMovSteps > 0) {
568                        int code = getRightMovingCode(kMod8, resiBitsLength);
569                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
570                } else if (rightMovSteps < 0) {
571                        int code1 = getLeftMovingCode(kMod8);
572                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
573                        int leftMovSteps = -rightMovSteps;
574                        rightMovSteps = 8 - leftMovSteps;
575                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
576                        p++;
577                        resiBits = resiBits
578                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
579                } else // rightMovSteps == 0
580                {
581                        int code = getRightMovingCode(kMod8, resiBitsLength);
582                        resiBits = (tdps->residualMidBits[p] & code);
583                        p++;
584                }
585                k += resiBitsLength;
586        }
587
588        // recover the exact data
589        memset(curBytes, 0, 8);
590        leadingNum = leadNum[l++];
591        memcpy(curBytes, preBytes, leadingNum);
592        for (j = leadingNum; j < reqBytesLength; j++)
593                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
594        if (resiBitsLength != 0) {
595                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
596                curBytes[reqBytesLength] = resiByte;
597        }
598
599        exactData = bytesToDouble(curBytes);
600        (*data)[0] = exactData + medianValue;
601        memcpy(preBytes,curBytes,8);
602
603        /* Process Row-0, data 1 */
604        pred1D = (*data)[0];
605
606        type_ = type[1];
607        if (type_ != 0)
608        {
609                (*data)[1] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
610        }
611        else
612        {
613                // compute resiBits
614                resiBits = 0;
615                if (resiBitsLength != 0) {
616                        int kMod8 = k % 8;
617                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
618                        if (rightMovSteps > 0) {
619                                int code = getRightMovingCode(kMod8, resiBitsLength);
620                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
621                        } else if (rightMovSteps < 0) {
622                                int code1 = getLeftMovingCode(kMod8);
623                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
624                                int leftMovSteps = -rightMovSteps;
625                                rightMovSteps = 8 - leftMovSteps;
626                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
627                                p++;
628                                resiBits = resiBits
629                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
630                        } else // rightMovSteps == 0
631                        {
632                                int code = getRightMovingCode(kMod8, resiBitsLength);
633                                resiBits = (tdps->residualMidBits[p] & code);
634                                p++;
635                        }
636                        k += resiBitsLength;
637                }
638
639                // recover the exact data
640                memset(curBytes, 0, 8);
641                leadingNum = leadNum[l++];
642                memcpy(curBytes, preBytes, leadingNum);
643                for (j = leadingNum; j < reqBytesLength; j++)
644                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
645                if (resiBitsLength != 0) {
646                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
647                        curBytes[reqBytesLength] = resiByte;
648                }
649
650                exactData = bytesToDouble(curBytes);
651                (*data)[1] = exactData + medianValue;
652                memcpy(preBytes,curBytes,8);
653        }
654
655        /* Process Row-0, data 2 --> data r3-1 */
656        for (jj = 2; jj < r3; jj++)
657        {
658                pred1D = 2*(*data)[jj-1] - (*data)[jj-2];
659
660                type_ = type[jj];
661                if (type_ != 0)
662                {
663                        (*data)[jj] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
664                }
665                else
666                {
667                        // compute resiBits
668                        resiBits = 0;
669                        if (resiBitsLength != 0) {
670                                int kMod8 = k % 8;
671                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
672                                if (rightMovSteps > 0) {
673                                        int code = getRightMovingCode(kMod8, resiBitsLength);
674                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
675                                } else if (rightMovSteps < 0) {
676                                        int code1 = getLeftMovingCode(kMod8);
677                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
678                                        int leftMovSteps = -rightMovSteps;
679                                        rightMovSteps = 8 - leftMovSteps;
680                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
681                                        p++;
682                                        resiBits = resiBits
683                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
684                                } else // rightMovSteps == 0
685                                {
686                                        int code = getRightMovingCode(kMod8, resiBitsLength);
687                                        resiBits = (tdps->residualMidBits[p] & code);
688                                        p++;
689                                }
690                                k += resiBitsLength;
691                        }
692
693                        // recover the exact data
694                        memset(curBytes, 0, 8);
695                        leadingNum = leadNum[l++];
696                        memcpy(curBytes, preBytes, leadingNum);
697                        for (j = leadingNum; j < reqBytesLength; j++)
698                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
699                        if (resiBitsLength != 0) {
700                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
701                                curBytes[reqBytesLength] = resiByte;
702                        }
703
704                        exactData = bytesToDouble(curBytes);
705                        (*data)[jj] = exactData + medianValue;
706                        memcpy(preBytes,curBytes,8);
707                }
708        }
709
710        size_t index;
711        /* Process Row-1 --> Row-r2-1 */
712        for (ii = 1; ii < r2; ii++)
713        {
714                /* Process row-ii data 0 */
715                index = ii*r3;
716                pred1D = (*data)[index-r3];
717
718                type_ = type[index];
719                if (type_ != 0)
720                {
721                        (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
722                }
723                else
724                {
725                        // compute resiBits
726                        resiBits = 0;
727                        if (resiBitsLength != 0) {
728                                int kMod8 = k % 8;
729                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
730                                if (rightMovSteps > 0) {
731                                        int code = getRightMovingCode(kMod8, resiBitsLength);
732                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
733                                } else if (rightMovSteps < 0) {
734                                        int code1 = getLeftMovingCode(kMod8);
735                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
736                                        int leftMovSteps = -rightMovSteps;
737                                        rightMovSteps = 8 - leftMovSteps;
738                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
739                                        p++;
740                                        resiBits = resiBits
741                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
742                                } else // rightMovSteps == 0
743                                {
744                                        int code = getRightMovingCode(kMod8, resiBitsLength);
745                                        resiBits = (tdps->residualMidBits[p] & code);
746                                        p++;
747                                }
748                                k += resiBitsLength;
749                        }
750
751                        // recover the exact data
752                        memset(curBytes, 0, 8);
753                        leadingNum = leadNum[l++];
754                        memcpy(curBytes, preBytes, leadingNum);
755                        for (j = leadingNum; j < reqBytesLength; j++)
756                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
757                        if (resiBitsLength != 0) {
758                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
759                                curBytes[reqBytesLength] = resiByte;
760                        }
761
762                        exactData = bytesToDouble(curBytes);
763                        (*data)[index] = exactData + medianValue;
764                        memcpy(preBytes,curBytes,8);
765                }
766
767                /* Process row-ii data 1 --> r3-1*/
768                for (jj = 1; jj < r3; jj++)
769                {
770                        index = ii*r3+jj;
771                        pred2D = (*data)[index-1] + (*data)[index-r3] - (*data)[index-r3-1];
772
773                        type_ = type[index];
774                        if (type_ != 0)
775                        {
776                                (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
777                        }
778                        else
779                        {
780                                // compute resiBits
781                                resiBits = 0;
782                                if (resiBitsLength != 0) {
783                                        int kMod8 = k % 8;
784                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
785                                        if (rightMovSteps > 0) {
786                                                int code = getRightMovingCode(kMod8, resiBitsLength);
787                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
788                                        } else if (rightMovSteps < 0) {
789                                                int code1 = getLeftMovingCode(kMod8);
790                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
791                                                int leftMovSteps = -rightMovSteps;
792                                                rightMovSteps = 8 - leftMovSteps;
793                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
794                                                p++;
795                                                resiBits = resiBits
796                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
797                                        } else // rightMovSteps == 0
798                                        {
799                                                int code = getRightMovingCode(kMod8, resiBitsLength);
800                                                resiBits = (tdps->residualMidBits[p] & code);
801                                                p++;
802                                        }
803                                        k += resiBitsLength;
804                                }
805
806                                // recover the exact data
807                                memset(curBytes, 0, 8);
808                                leadingNum = leadNum[l++];
809                                memcpy(curBytes, preBytes, leadingNum);
810                                for (j = leadingNum; j < reqBytesLength; j++)
811                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
812                                if (resiBitsLength != 0) {
813                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
814                                        curBytes[reqBytesLength] = resiByte;
815                                }
816
817                                exactData = bytesToDouble(curBytes);
818                                (*data)[index] = exactData + medianValue;
819                                memcpy(preBytes,curBytes,8);
820                        }
821                }
822        }
823
824        ///////////////////////////     Process layer-1 --> layer-r1-1 ///////////////////////////
825
826        for (kk = 1; kk < r1; kk++)
827        {
828                /* Process Row-0 data 0*/
829                index = kk*r23;
830                pred1D = (*data)[index-r23];
831
832                type_ = type[index];
833                if (type_ != 0)
834                {
835                        (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
836                }
837                else
838                {
839                        // compute resiBits
840                        resiBits = 0;
841                        if (resiBitsLength != 0) {
842                                int kMod8 = k % 8;
843                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
844                                if (rightMovSteps > 0) {
845                                        int code = getRightMovingCode(kMod8, resiBitsLength);
846                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
847                                } else if (rightMovSteps < 0) {
848                                        int code1 = getLeftMovingCode(kMod8);
849                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
850                                        int leftMovSteps = -rightMovSteps;
851                                        rightMovSteps = 8 - leftMovSteps;
852                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
853                                        p++;
854                                        resiBits = resiBits
855                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
856                                } else // rightMovSteps == 0
857                                {
858                                        int code = getRightMovingCode(kMod8, resiBitsLength);
859                                        resiBits = (tdps->residualMidBits[p] & code);
860                                        p++;
861                                }
862                                k += resiBitsLength;
863                        }
864
865                        // recover the exact data
866                        memset(curBytes, 0, 8);
867                        leadingNum = leadNum[l++];
868                        memcpy(curBytes, preBytes, leadingNum);
869                        for (j = leadingNum; j < reqBytesLength; j++)
870                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
871                        if (resiBitsLength != 0) {
872                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
873                                curBytes[reqBytesLength] = resiByte;
874                        }
875
876                        exactData = bytesToDouble(curBytes);
877                        (*data)[index] = exactData + medianValue;
878                        memcpy(preBytes,curBytes,8);
879                }
880
881                /* Process Row-0 data 1 --> data r3-1 */
882                for (jj = 1; jj < r3; jj++)
883                {
884                        index = kk*r23+jj;
885                        pred2D = (*data)[index-1] + (*data)[index-r23] - (*data)[index-r23-1];
886
887                        type_ = type[index];
888                        if (type_ != 0)
889                        {
890                                (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
891                        }
892                        else
893                        {
894                                // compute resiBits
895                                resiBits = 0;
896                                if (resiBitsLength != 0) {
897                                        int kMod8 = k % 8;
898                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
899                                        if (rightMovSteps > 0) {
900                                                int code = getRightMovingCode(kMod8, resiBitsLength);
901                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
902                                        } else if (rightMovSteps < 0) {
903                                                int code1 = getLeftMovingCode(kMod8);
904                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
905                                                int leftMovSteps = -rightMovSteps;
906                                                rightMovSteps = 8 - leftMovSteps;
907                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
908                                                p++;
909                                                resiBits = resiBits
910                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
911                                        } else // rightMovSteps == 0
912                                        {
913                                                int code = getRightMovingCode(kMod8, resiBitsLength);
914                                                resiBits = (tdps->residualMidBits[p] & code);
915                                                p++;
916                                        }
917                                        k += resiBitsLength;
918                                }
919
920                                // recover the exact data
921                                memset(curBytes, 0, 8);
922                                leadingNum = leadNum[l++];
923                                memcpy(curBytes, preBytes, leadingNum);
924                                for (j = leadingNum; j < reqBytesLength; j++)
925                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
926                                if (resiBitsLength != 0) {
927                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
928                                        curBytes[reqBytesLength] = resiByte;
929                                }
930
931                                exactData = bytesToDouble(curBytes);
932                                (*data)[index] = exactData + medianValue;
933                                memcpy(preBytes,curBytes,8);
934                        }
935                }
936
937                /* Process Row-1 --> Row-r2-1 */
938                for (ii = 1; ii < r2; ii++)
939                {
940                        /* Process Row-i data 0 */
941                        index = kk*r23 + ii*r3;
942                        pred2D = (*data)[index-r3] + (*data)[index-r23] - (*data)[index-r23-r3];
943
944                        type_ = type[index];
945                        if (type_ != 0)
946                        {
947                                (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
948                        }
949                        else
950                        {
951                                // compute resiBits
952                                resiBits = 0;
953                                if (resiBitsLength != 0) {
954                                        int kMod8 = k % 8;
955                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
956                                        if (rightMovSteps > 0) {
957                                                int code = getRightMovingCode(kMod8, resiBitsLength);
958                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
959                                        } else if (rightMovSteps < 0) {
960                                                int code1 = getLeftMovingCode(kMod8);
961                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
962                                                int leftMovSteps = -rightMovSteps;
963                                                rightMovSteps = 8 - leftMovSteps;
964                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
965                                                p++;
966                                                resiBits = resiBits
967                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
968                                        } else // rightMovSteps == 0
969                                        {
970                                                int code = getRightMovingCode(kMod8, resiBitsLength);
971                                                resiBits = (tdps->residualMidBits[p] & code);
972                                                p++;
973                                        }
974                                        k += resiBitsLength;
975                                }
976
977                                // recover the exact data
978                                memset(curBytes, 0, 8);
979                                leadingNum = leadNum[l++];
980                                memcpy(curBytes, preBytes, leadingNum);
981                                for (j = leadingNum; j < reqBytesLength; j++)
982                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
983                                if (resiBitsLength != 0) {
984                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
985                                        curBytes[reqBytesLength] = resiByte;
986                                }
987
988                                exactData = bytesToDouble(curBytes);
989                                (*data)[index] = exactData + medianValue;
990                                memcpy(preBytes,curBytes,8);
991                        }
992
993                        /* Process Row-i data 1 --> data r3-1 */
994                        for (jj = 1; jj < r3; jj++)
995                        {
996                                index = kk*r23 + ii*r3 + jj;
997                                pred3D = (*data)[index-1] + (*data)[index-r3] + (*data)[index-r23]
998                                        - (*data)[index-r3-1] - (*data)[index-r23-r3] - (*data)[index-r23-1] + (*data)[index-r23-r3-1];
999
1000                                type_ = type[index];
1001                                if (type_ != 0)
1002                                {
1003                                        (*data)[index] = pred3D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1004                                }
1005                                else
1006                                {
1007                                        // compute resiBits
1008                                        resiBits = 0;
1009                                        if (resiBitsLength != 0) {
1010                                                int kMod8 = k % 8;
1011                                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1012                                                if (rightMovSteps > 0) {
1013                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1014                                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1015                                                } else if (rightMovSteps < 0) {
1016                                                        int code1 = getLeftMovingCode(kMod8);
1017                                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
1018                                                        int leftMovSteps = -rightMovSteps;
1019                                                        rightMovSteps = 8 - leftMovSteps;
1020                                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1021                                                        p++;
1022                                                        resiBits = resiBits
1023                                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1024                                                } else // rightMovSteps == 0
1025                                                {
1026                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1027                                                        resiBits = (tdps->residualMidBits[p] & code);
1028                                                        p++;
1029                                                }
1030                                                k += resiBitsLength;
1031                                        }
1032
1033                                        // recover the exact data
1034                                        memset(curBytes, 0, 8);
1035                                        leadingNum = leadNum[l++];
1036                                        memcpy(curBytes, preBytes, leadingNum);
1037                                        for (j = leadingNum; j < reqBytesLength; j++)
1038                                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1039                                        if (resiBitsLength != 0) {
1040                                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1041                                                curBytes[reqBytesLength] = resiByte;
1042                                        }
1043
1044                                        exactData = bytesToDouble(curBytes);
1045                                        (*data)[index] = exactData + medianValue;
1046                                        memcpy(preBytes,curBytes,8);
1047                                }
1048                        }
1049                }
1050        }
1051
1052#ifdef HAVE_TIMECMPR   
1053        if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1054                memcpy(multisteps->hist_data, (*data), dataSeriesLength*sizeof(double));
1055#endif 
1056
1057        free(leadNum);
1058        free(type);
1059        return;
1060}
1061
1062void decompressDataSeries_double_4D(double** data, size_t r1, size_t r2, size_t r3, size_t r4, TightDataPointStorageD* tdps)
1063{
1064        updateQuantizationInfo(tdps->intervals);
1065        size_t j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
1066        // in resiMidBits, p is to track the
1067        // byte_index of resiMidBits, l is for
1068        // leadNum
1069        size_t dataSeriesLength = r1*r2*r3*r4;
1070        size_t r234 = r2*r3*r4;
1071        size_t r34 = r3*r4;
1072//      printf ("%d %d %d\n", r1, r2, r3, r4);
1073
1074        unsigned char* leadNum;
1075        double realPrecision = tdps->realPrecision;
1076
1077        convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
1078
1079        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1080
1081        int* type = (int*)malloc(dataSeriesLength*sizeof(int));
1082
1083        HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
1084        decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
1085        SZ_ReleaseHuffman(huffmanTree); 
1086
1087        unsigned char preBytes[8];
1088        unsigned char curBytes[8];
1089
1090        memset(preBytes, 0, 8);
1091
1092        size_t curByteIndex = 0;
1093        int reqBytesLength, resiBitsLength, resiBits;
1094        unsigned char leadingNum;
1095        double medianValue, exactData;
1096        int type_;
1097
1098        reqBytesLength = tdps->reqLength/8;
1099        resiBitsLength = tdps->reqLength%8;
1100        medianValue = tdps->medianValue;
1101
1102        double pred1D, pred2D, pred3D;
1103        size_t ii, jj, kk, ll;
1104        size_t index;
1105
1106        for (ll = 0; ll < r1; ll++)
1107        {
1108
1109                ///////////////////////////     Process layer-0 ///////////////////////////
1110                /* Process Row-0 data 0*/
1111                index = ll*r234;
1112
1113                // compute resiBits
1114                resiBits = 0;
1115                if (resiBitsLength != 0) {
1116                        int kMod8 = k % 8;
1117                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1118                        if (rightMovSteps > 0) {
1119                                int code = getRightMovingCode(kMod8, resiBitsLength);
1120                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1121                        } else if (rightMovSteps < 0) {
1122                                int code1 = getLeftMovingCode(kMod8);
1123                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
1124                                int leftMovSteps = -rightMovSteps;
1125                                rightMovSteps = 8 - leftMovSteps;
1126                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1127                                p++;
1128                                resiBits = resiBits
1129                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1130                        } else // rightMovSteps == 0
1131                        {
1132                                int code = getRightMovingCode(kMod8, resiBitsLength);
1133                                resiBits = (tdps->residualMidBits[p] & code);
1134                                p++;
1135                        }
1136                        k += resiBitsLength;
1137                }
1138
1139                // recover the exact data
1140                memset(curBytes, 0, 8);
1141                leadingNum = leadNum[l++];
1142                memcpy(curBytes, preBytes, leadingNum);
1143                for (j = leadingNum; j < reqBytesLength; j++)
1144                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1145                if (resiBitsLength != 0) {
1146                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1147                        curBytes[reqBytesLength] = resiByte;
1148                }
1149
1150                exactData = bytesToDouble(curBytes);
1151                (*data)[index] = exactData + medianValue;
1152                memcpy(preBytes,curBytes,8);
1153
1154                /* Process Row-0, data 1 */
1155                index = ll*r234+1;
1156
1157                pred1D = (*data)[index-1];
1158
1159                type_ = type[index];
1160                if (type_ != 0)
1161                {
1162                        (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1163                }
1164                else
1165                {
1166                        // compute resiBits
1167                        resiBits = 0;
1168                        if (resiBitsLength != 0) {
1169                                int kMod8 = k % 8;
1170                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1171                                if (rightMovSteps > 0) {
1172                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1173                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1174                                } else if (rightMovSteps < 0) {
1175                                        int code1 = getLeftMovingCode(kMod8);
1176                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
1177                                        int leftMovSteps = -rightMovSteps;
1178                                        rightMovSteps = 8 - leftMovSteps;
1179                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1180                                        p++;
1181                                        resiBits = resiBits
1182                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1183                                } else // rightMovSteps == 0
1184                                {
1185                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1186                                        resiBits = (tdps->residualMidBits[p] & code);
1187                                        p++;
1188                                }
1189                                k += resiBitsLength;
1190                        }
1191
1192                        // recover the exact data
1193                        memset(curBytes, 0, 8);
1194                        leadingNum = leadNum[l++];
1195                        memcpy(curBytes, preBytes, leadingNum);
1196                        for (j = leadingNum; j < reqBytesLength; j++)
1197                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1198                        if (resiBitsLength != 0) {
1199                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1200                                curBytes[reqBytesLength] = resiByte;
1201                        }
1202
1203                        exactData = bytesToDouble(curBytes);
1204                        (*data)[index] = exactData + medianValue;
1205                        memcpy(preBytes,curBytes,8);
1206                }
1207
1208                /* Process Row-0, data 2 --> data r4-1 */
1209                for (jj = 2; jj < r4; jj++)
1210                {
1211                        index = ll*r234+jj;
1212
1213                        pred1D = 2*(*data)[index-1] - (*data)[index-2];
1214
1215                        type_ = type[index];
1216                        if (type_ != 0)
1217                        {
1218                                (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1219                        }
1220                        else
1221                        {
1222                                // compute resiBits
1223                                resiBits = 0;
1224                                if (resiBitsLength != 0) {
1225                                        int kMod8 = k % 8;
1226                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1227                                        if (rightMovSteps > 0) {
1228                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1229                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1230                                        } else if (rightMovSteps < 0) {
1231                                                int code1 = getLeftMovingCode(kMod8);
1232                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
1233                                                int leftMovSteps = -rightMovSteps;
1234                                                rightMovSteps = 8 - leftMovSteps;
1235                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1236                                                p++;
1237                                                resiBits = resiBits
1238                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1239                                        } else // rightMovSteps == 0
1240                                        {
1241                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1242                                                resiBits = (tdps->residualMidBits[p] & code);
1243                                                p++;
1244                                        }
1245                                        k += resiBitsLength;
1246                                }
1247
1248                                // recover the exact data
1249                                memset(curBytes, 0, 8);
1250                                leadingNum = leadNum[l++];
1251                                memcpy(curBytes, preBytes, leadingNum);
1252                                for (j = leadingNum; j < reqBytesLength; j++)
1253                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1254                                if (resiBitsLength != 0) {
1255                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1256                                        curBytes[reqBytesLength] = resiByte;
1257                                }
1258
1259                                exactData = bytesToDouble(curBytes);
1260                                (*data)[index] = exactData + medianValue;
1261                                memcpy(preBytes,curBytes,8);
1262                        }
1263                }
1264
1265                /* Process Row-1 --> Row-r3-1 */
1266                for (ii = 1; ii < r3; ii++)
1267                {
1268                        /* Process row-ii data 0 */
1269                        index = ll*r234+ii*r4;
1270
1271                        pred1D = (*data)[index-r4];
1272
1273                        type_ = type[index];
1274                        if (type_ != 0)
1275                        {
1276                                (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1277                        }
1278                        else
1279                        {
1280                                // compute resiBits
1281                                resiBits = 0;
1282                                if (resiBitsLength != 0) {
1283                                        int kMod8 = k % 8;
1284                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1285                                        if (rightMovSteps > 0) {
1286                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1287                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1288                                        } else if (rightMovSteps < 0) {
1289                                                int code1 = getLeftMovingCode(kMod8);
1290                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
1291                                                int leftMovSteps = -rightMovSteps;
1292                                                rightMovSteps = 8 - leftMovSteps;
1293                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1294                                                p++;
1295                                                resiBits = resiBits
1296                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1297                                        } else // rightMovSteps == 0
1298                                        {
1299                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1300                                                resiBits = (tdps->residualMidBits[p] & code);
1301                                                p++;
1302                                        }
1303                                        k += resiBitsLength;
1304                                }
1305
1306                                // recover the exact data
1307                                memset(curBytes, 0, 8);
1308                                leadingNum = leadNum[l++];
1309                                memcpy(curBytes, preBytes, leadingNum);
1310                                for (j = leadingNum; j < reqBytesLength; j++)
1311                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1312                                if (resiBitsLength != 0) {
1313                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1314                                        curBytes[reqBytesLength] = resiByte;
1315                                }
1316
1317                                exactData = bytesToDouble(curBytes);
1318                                (*data)[index] = exactData + medianValue;
1319                                memcpy(preBytes,curBytes,8);
1320                        }
1321
1322                        /* Process row-ii data 1 --> r4-1*/
1323                        for (jj = 1; jj < r4; jj++)
1324                        {
1325                                index = ll*r234+ii*r4+jj;
1326
1327                                pred2D = (*data)[index-1] + (*data)[index-r4] - (*data)[index-r4-1];
1328
1329                                type_ = type[index];
1330                                if (type_ != 0)
1331                                {
1332                                        (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1333                                }
1334                                else
1335                                {
1336                                        // compute resiBits
1337                                        resiBits = 0;
1338                                        if (resiBitsLength != 0) {
1339                                                int kMod8 = k % 8;
1340                                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1341                                                if (rightMovSteps > 0) {
1342                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1343                                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1344                                                } else if (rightMovSteps < 0) {
1345                                                        int code1 = getLeftMovingCode(kMod8);
1346                                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
1347                                                        int leftMovSteps = -rightMovSteps;
1348                                                        rightMovSteps = 8 - leftMovSteps;
1349                                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1350                                                        p++;
1351                                                        resiBits = resiBits
1352                                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1353                                                } else // rightMovSteps == 0
1354                                                {
1355                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1356                                                        resiBits = (tdps->residualMidBits[p] & code);
1357                                                        p++;
1358                                                }
1359                                                k += resiBitsLength;
1360                                        }
1361
1362                                        // recover the exact data
1363                                        memset(curBytes, 0, 8);
1364                                        leadingNum = leadNum[l++];
1365                                        memcpy(curBytes, preBytes, leadingNum);
1366                                        for (j = leadingNum; j < reqBytesLength; j++)
1367                                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1368                                        if (resiBitsLength != 0) {
1369                                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1370                                                curBytes[reqBytesLength] = resiByte;
1371                                        }
1372
1373                                        exactData = bytesToDouble(curBytes);
1374                                        (*data)[index] = exactData + medianValue;
1375                                        memcpy(preBytes,curBytes,8);
1376                                }
1377                        }
1378                }
1379
1380                ///////////////////////////     Process layer-1 --> layer-r2-1 ///////////////////////////
1381
1382                for (kk = 1; kk < r2; kk++)
1383                {
1384                        /* Process Row-0 data 0*/
1385                        index = ll*r234+kk*r34;
1386
1387                        pred1D = (*data)[index-r34];
1388
1389                        type_ = type[index];
1390                        if (type_ != 0)
1391                        {
1392                                (*data)[index] = pred1D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1393                        }
1394                        else
1395                        {
1396                                // compute resiBits
1397                                resiBits = 0;
1398                                if (resiBitsLength != 0) {
1399                                        int kMod8 = k % 8;
1400                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1401                                        if (rightMovSteps > 0) {
1402                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1403                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1404                                        } else if (rightMovSteps < 0) {
1405                                                int code1 = getLeftMovingCode(kMod8);
1406                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
1407                                                int leftMovSteps = -rightMovSteps;
1408                                                rightMovSteps = 8 - leftMovSteps;
1409                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1410                                                p++;
1411                                                resiBits = resiBits
1412                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1413                                        } else // rightMovSteps == 0
1414                                        {
1415                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1416                                                resiBits = (tdps->residualMidBits[p] & code);
1417                                                p++;
1418                                        }
1419                                        k += resiBitsLength;
1420                                }
1421
1422                                // recover the exact data
1423                                memset(curBytes, 0, 8);
1424                                leadingNum = leadNum[l++];
1425                                memcpy(curBytes, preBytes, leadingNum);
1426                                for (j = leadingNum; j < reqBytesLength; j++)
1427                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1428                                if (resiBitsLength != 0) {
1429                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1430                                        curBytes[reqBytesLength] = resiByte;
1431                                }
1432
1433                                exactData = bytesToDouble(curBytes);
1434                                (*data)[index] = exactData + medianValue;
1435                                memcpy(preBytes,curBytes,8);
1436                        }
1437
1438                        /* Process Row-0 data 1 --> data r4-1 */
1439                        for (jj = 1; jj < r4; jj++)
1440                        {
1441                                index = ll*r234+kk*r34+jj;
1442
1443                                pred2D = (*data)[index-1] + (*data)[index-r34] - (*data)[index-r34-1];
1444
1445                                type_ = type[index];
1446                                if (type_ != 0)
1447                                {
1448                                        (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1449                                }
1450                                else
1451                                {
1452                                        // compute resiBits
1453                                        resiBits = 0;
1454                                        if (resiBitsLength != 0) {
1455                                                int kMod8 = k % 8;
1456                                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1457                                                if (rightMovSteps > 0) {
1458                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1459                                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1460                                                } else if (rightMovSteps < 0) {
1461                                                        int code1 = getLeftMovingCode(kMod8);
1462                                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
1463                                                        int leftMovSteps = -rightMovSteps;
1464                                                        rightMovSteps = 8 - leftMovSteps;
1465                                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1466                                                        p++;
1467                                                        resiBits = resiBits
1468                                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1469                                                } else // rightMovSteps == 0
1470                                                {
1471                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1472                                                        resiBits = (tdps->residualMidBits[p] & code);
1473                                                        p++;
1474                                                }
1475                                                k += resiBitsLength;
1476                                        }
1477
1478                                        // recover the exact data
1479                                        memset(curBytes, 0, 8);
1480                                        leadingNum = leadNum[l++];
1481                                        memcpy(curBytes, preBytes, leadingNum);
1482                                        for (j = leadingNum; j < reqBytesLength; j++)
1483                                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1484                                        if (resiBitsLength != 0) {
1485                                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1486                                                curBytes[reqBytesLength] = resiByte;
1487                                        }
1488
1489                                        exactData = bytesToDouble(curBytes);
1490                                        (*data)[index] = exactData + medianValue;
1491                                        memcpy(preBytes,curBytes,8);
1492                                }
1493                        }
1494
1495                        /* Process Row-1 --> Row-r3-1 */
1496                        for (ii = 1; ii < r3; ii++)
1497                        {
1498                                /* Process Row-i data 0 */
1499                                index = ll*r234+kk*r34+ii*r4;
1500
1501                                pred2D = (*data)[index-r4] + (*data)[index-r34] - (*data)[index-r34-r4];
1502
1503                                type_ = type[index];
1504                                if (type_ != 0)
1505                                {
1506                                        (*data)[index] = pred2D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1507                                }
1508                                else
1509                                {
1510                                        // compute resiBits
1511                                        resiBits = 0;
1512                                        if (resiBitsLength != 0) {
1513                                                int kMod8 = k % 8;
1514                                                int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1515                                                if (rightMovSteps > 0) {
1516                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1517                                                        resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1518                                                } else if (rightMovSteps < 0) {
1519                                                        int code1 = getLeftMovingCode(kMod8);
1520                                                        int code2 = getRightMovingCode(kMod8, resiBitsLength);
1521                                                        int leftMovSteps = -rightMovSteps;
1522                                                        rightMovSteps = 8 - leftMovSteps;
1523                                                        resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1524                                                        p++;
1525                                                        resiBits = resiBits
1526                                                                        | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1527                                                } else // rightMovSteps == 0
1528                                                {
1529                                                        int code = getRightMovingCode(kMod8, resiBitsLength);
1530                                                        resiBits = (tdps->residualMidBits[p] & code);
1531                                                        p++;
1532                                                }
1533                                                k += resiBitsLength;
1534                                        }
1535
1536                                        // recover the exact data
1537                                        memset(curBytes, 0, 8);
1538                                        leadingNum = leadNum[l++];
1539                                        memcpy(curBytes, preBytes, leadingNum);
1540                                        for (j = leadingNum; j < reqBytesLength; j++)
1541                                                curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1542                                        if (resiBitsLength != 0) {
1543                                                unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1544                                                curBytes[reqBytesLength] = resiByte;
1545                                        }
1546
1547                                        exactData = bytesToDouble(curBytes);
1548                                        (*data)[index] = exactData + medianValue;
1549                                        memcpy(preBytes,curBytes,8);
1550                                }
1551
1552                                /* Process Row-i data 1 --> data r4-1 */
1553                                for (jj = 1; jj < r4; jj++)
1554                                {
1555                                        index = ll*r234+kk*r34+ii*r4+jj;
1556
1557                                        pred3D = (*data)[index-1] + (*data)[index-r4] + (*data)[index-r34]
1558                                                        - (*data)[index-r4-1] - (*data)[index-r34-r4] - (*data)[index-r34-1] + (*data)[index-r34-r4-1];
1559
1560                                        type_ = type[index];
1561                                        if (type_ != 0)
1562                                        {
1563                                                (*data)[index] = pred3D + 2 * (type_ - exe_params->intvRadius) * realPrecision;
1564                                        }
1565                                        else
1566                                        {
1567                                                // compute resiBits
1568                                                resiBits = 0;
1569                                                if (resiBitsLength != 0) {
1570                                                        int kMod8 = k % 8;
1571                                                        int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
1572                                                        if (rightMovSteps > 0) {
1573                                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1574                                                                resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
1575                                                        } else if (rightMovSteps < 0) {
1576                                                                int code1 = getLeftMovingCode(kMod8);
1577                                                                int code2 = getRightMovingCode(kMod8, resiBitsLength);
1578                                                                int leftMovSteps = -rightMovSteps;
1579                                                                rightMovSteps = 8 - leftMovSteps;
1580                                                                resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
1581                                                                p++;
1582                                                                resiBits = resiBits
1583                                                                                | ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
1584                                                        } else // rightMovSteps == 0
1585                                                        {
1586                                                                int code = getRightMovingCode(kMod8, resiBitsLength);
1587                                                                resiBits = (tdps->residualMidBits[p] & code);
1588                                                                p++;
1589                                                        }
1590                                                        k += resiBitsLength;
1591                                                }
1592
1593                                                // recover the exact data
1594                                                memset(curBytes, 0, 8);
1595                                                leadingNum = leadNum[l++];
1596                                                memcpy(curBytes, preBytes, leadingNum);
1597                                                for (j = leadingNum; j < reqBytesLength; j++)
1598                                                        curBytes[j] = tdps->exactMidBytes[curByteIndex++];
1599                                                if (resiBitsLength != 0) {
1600                                                        unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
1601                                                        curBytes[reqBytesLength] = resiByte;
1602                                                }
1603
1604                                                exactData = bytesToDouble(curBytes);
1605                                                (*data)[index] = exactData + medianValue;
1606                                                memcpy(preBytes,curBytes,8);
1607                                        }
1608                                }
1609                        }
1610                }
1611        }
1612
1613//I didn't implement time-based compression for 4D actually.
1614//#ifdef HAVE_TIMECMPR 
1615//      if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1616//              memcpy(multisteps->hist_data, (*data), dataSeriesLength*sizeof(double));
1617//#endif       
1618
1619        free(leadNum);
1620        free(type);
1621        return;
1622}
1623
1624void getSnapshotData_double_1D(double** data, size_t dataSeriesLength, TightDataPointStorageD* tdps, int errBoundMode) 
1625{
1626        size_t i;
1627        if (tdps->allSameData) {
1628                double value = bytesToDouble(tdps->exactMidBytes);
1629                *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1630                for (i = 0; i < dataSeriesLength; i++)
1631                        (*data)[i] = value;
1632        } else {
1633                if (tdps->rtypeArray == NULL) {
1634                        if(errBoundMode < PW_REL)
1635                        {
1636#ifdef HAVE_TIMECMPR                           
1637                                if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1638                                {
1639                                        if(multisteps->compressionType == 0) //snapshot
1640                                                decompressDataSeries_double_1D(data, dataSeriesLength, tdps);
1641                                        else
1642                                                decompressDataSeries_double_1D_ts(data, dataSeriesLength, multisteps, tdps);                                   
1643                                }
1644                                else
1645#endif                                                         
1646                                        decompressDataSeries_double_1D(data, dataSeriesLength, tdps);
1647                        }
1648                        else 
1649                        {
1650                                //decompressDataSeries_double_1D_pwr(data, dataSeriesLength, tdps);
1651                                decompressDataSeries_double_1D_pwrgroup(data, dataSeriesLength, tdps);
1652                        }
1653                        return;
1654                } else {
1655                        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1656                        // insert the reserved values
1657                        //int[] rtypes = TypeManager.convertByteArray2IntArray_fast_1b(
1658                        //              dataSeriesLength, rtypeArray);
1659                        int* rtypes;
1660                        int validLength = computeBitNumRequired(dataSeriesLength);
1661                        decompressBitArraybySimpleLZ77(&rtypes, tdps->rtypeArray, tdps->rtypeArray_size, dataSeriesLength, validLength);
1662                        size_t count = 0;
1663                        for (i = 0; i < dataSeriesLength; i++) {
1664                                if (rtypes[i] == 1)
1665                                        (*data)[i] = tdps->reservedValue;
1666                                else
1667                                        count++;
1668                        }
1669                        // get the decompressed data
1670                        double* decmpData;
1671                        if(errBoundMode < PW_REL)
1672                                decompressDataSeries_double_1D(&decmpData, dataSeriesLength, tdps);
1673                        else 
1674                                decompressDataSeries_double_1D_pwr(&decmpData, dataSeriesLength, tdps);
1675                        // insert the decompressed data
1676                        size_t k = 0;
1677                        for (i = 0; i < dataSeriesLength; i++) {
1678                                if (rtypes[i] == 0) {
1679                                        (*data)[i] = decmpData[k++];
1680                                }
1681                        }
1682                        free(decmpData);
1683                        free(rtypes);
1684                }
1685        }
1686}
1687
1688void getSnapshotData_double_2D(double** data, size_t r1, size_t r2, TightDataPointStorageD* tdps, int errBoundMode) 
1689{
1690        size_t i;
1691        size_t dataSeriesLength = r1*r2;
1692        if (tdps->allSameData) {
1693                double value = bytesToDouble(tdps->exactMidBytes);
1694                *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1695                for (i = 0; i < dataSeriesLength; i++)
1696                        (*data)[i] = value;
1697        } else {
1698                if (tdps->rtypeArray == NULL) {
1699                        if(errBoundMode < PW_REL)
1700                        {
1701#ifdef HAVE_TIMECMPR                           
1702                                if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1703                                {
1704                                        if(multisteps->compressionType == 0) //snapshot
1705                                                decompressDataSeries_double_2D(data, r1, r2, tdps);
1706                                        else
1707                                                decompressDataSeries_double_1D_ts(data, dataSeriesLength, multisteps, tdps);                                   
1708                                }
1709                                else
1710#endif                                         
1711                                        decompressDataSeries_double_2D(data, r1, r2, tdps);
1712                        }
1713                        else 
1714                                decompressDataSeries_double_2D_pwr(data, r1, r2, tdps);
1715                        return;
1716                } else {
1717                        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1718                        // insert the reserved values
1719                        //int[] rtypes = TypeManager.convertByteArray2IntArray_fast_1b(
1720                        //              dataSeriesLength, rtypeArray);
1721                        int* rtypes;
1722                        int validLength = computeBitNumRequired(dataSeriesLength);
1723                        decompressBitArraybySimpleLZ77(&rtypes, tdps->rtypeArray, tdps->rtypeArray_size, dataSeriesLength, validLength);
1724                        size_t count = 0;
1725                        for (i = 0; i < dataSeriesLength; i++) {
1726                                if (rtypes[i] == 1)
1727                                        (*data)[i] = tdps->reservedValue;
1728                                else
1729                                        count++;
1730                        }
1731                        // get the decompressed data
1732                        double* decmpData;
1733                        if(errBoundMode < PW_REL)
1734                                decompressDataSeries_double_2D(&decmpData, r1, r2, tdps);
1735                        else 
1736                                decompressDataSeries_double_2D_pwr(&decmpData, r1, r2, tdps);
1737                        // insert the decompressed data
1738                        size_t k = 0;
1739                        for (i = 0; i < dataSeriesLength; i++) {
1740                                if (rtypes[i] == 0) {
1741                                        (*data)[i] = decmpData[k++];
1742                                }
1743                        }
1744                        free(decmpData);
1745                        free(rtypes);
1746                }
1747        }
1748}
1749
1750void getSnapshotData_double_3D(double** data, size_t r1, size_t r2, size_t r3, TightDataPointStorageD* tdps, int errBoundMode) 
1751{
1752        size_t i;
1753        size_t dataSeriesLength = r1*r2*r3;
1754        if (tdps->allSameData) {
1755                double value = bytesToDouble(tdps->exactMidBytes);
1756                *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1757                for (i = 0; i < dataSeriesLength; i++)
1758                        (*data)[i] = value;
1759        } else {
1760                if (tdps->rtypeArray == NULL) {
1761                        if(errBoundMode < PW_REL)
1762                        {
1763#ifdef HAVE_TIMECMPR                           
1764                                if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1765                                {
1766                                        if(multisteps->compressionType == 0) //snapshot
1767                                                decompressDataSeries_double_3D(data, r1, r2, r3, tdps);
1768                                        else
1769                                                decompressDataSeries_double_1D_ts(data, dataSeriesLength, multisteps, tdps);                                   
1770                                }
1771                                else
1772#endif                                         
1773                                        decompressDataSeries_double_3D(data, r1, r2, r3, tdps);
1774                        }
1775                        else 
1776                                decompressDataSeries_double_3D_pwr(data, r1, r2, r3, tdps);
1777                        return;
1778                } else {
1779                        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1780                        // insert the reserved values
1781                        //int[] rtypes = TypeManager.convertByteArray2IntArray_fast_1b(
1782                        //              dataSeriesLength, rtypeArray);
1783                        int* rtypes;
1784                        int validLength = computeBitNumRequired(dataSeriesLength);
1785                        decompressBitArraybySimpleLZ77(&rtypes, tdps->rtypeArray, tdps->rtypeArray_size, dataSeriesLength, validLength);
1786                        size_t count = 0;
1787                        for (i = 0; i < dataSeriesLength; i++) {
1788                                if (rtypes[i] == 1)
1789                                        (*data)[i] = tdps->reservedValue;
1790                                else
1791                                        count++;
1792                        }
1793                        // get the decompressed data
1794                        double* decmpData;
1795                        if(errBoundMode < PW_REL)
1796                                decompressDataSeries_double_3D(&decmpData, r1, r2, r3, tdps);
1797                        else 
1798                                decompressDataSeries_double_3D_pwr(&decmpData, r1, r2, r3, tdps);                       
1799                        // insert the decompressed data
1800                        size_t k = 0;
1801                        for (i = 0; i < dataSeriesLength; i++) {
1802                                if (rtypes[i] == 0) {
1803                                        (*data)[i] = decmpData[k++];
1804                                }
1805                        }
1806                        free(decmpData);
1807                        free(rtypes);
1808                }
1809        }
1810}
1811
1812void getSnapshotData_double_4D(double** data, size_t r1, size_t r2, size_t r3, size_t r4, TightDataPointStorageD* tdps, int errBoundMode)
1813{
1814        size_t i;
1815        size_t dataSeriesLength = r1*r2*r3*r4;
1816        if (tdps->allSameData) {
1817                double value = bytesToDouble(tdps->exactMidBytes);
1818                *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1819                for (i = 0; i < dataSeriesLength; i++)
1820                        (*data)[i] = value;
1821        } else {
1822                if (tdps->rtypeArray == NULL) {
1823                        if(errBoundMode < PW_REL)
1824                        {
1825#ifdef HAVE_TIMECMPR                                   
1826                                if(confparams_dec->szMode == SZ_TEMPORAL_COMPRESSION)
1827                                {
1828                                        if(multisteps->compressionType == 0)
1829                                                decompressDataSeries_double_4D(data, r1, r2, r3, r4, tdps);
1830                                        else
1831                                                decompressDataSeries_double_1D_ts(data, r1*r2*r3*r4, multisteps, tdps);                                 
1832                                }
1833                                else
1834#endif                         
1835                                        decompressDataSeries_double_4D(data, r1, r2, r3, r4, tdps);
1836                        }
1837                        else 
1838                        {
1839                                decompressDataSeries_double_3D_pwr(data, r1*r2, r3, r4, tdps);
1840                                //ToDO
1841                                //decompressDataSeries_double_4D_pwr(data, r1, r2, r3, r4, tdps);
1842                        }                                       
1843                        return;
1844                } else {
1845                        *data = (double*)malloc(sizeof(double)*dataSeriesLength);
1846                        int* rtypes;
1847                        int validLength = computeBitNumRequired(dataSeriesLength);
1848                        decompressBitArraybySimpleLZ77(&rtypes, tdps->rtypeArray, tdps->rtypeArray_size, dataSeriesLength, validLength);
1849                        size_t count = 0;
1850                        for (i = 0; i < dataSeriesLength; i++) {
1851                                if (rtypes[i] == 1)
1852                                        (*data)[i] = tdps->reservedValue;
1853                                else
1854                                        count++;
1855                        }
1856                        // get the decompressed data
1857                        double* decmpData;
1858                        if(errBoundMode < PW_REL)
1859                                decompressDataSeries_double_4D(&decmpData, r1, r2, r3, r4, tdps);
1860                        else
1861                                decompressDataSeries_double_3D_pwr(&decmpData, r1*r2, r3, r4, tdps);
1862                                //ToDo
1863                                //decompressDataSeries_double_4D_pwr(&decmpData, r1, r2, r3, r4, tdps);
1864                        // insert the decompressed data
1865                        size_t k = 0;
1866                        for (i = 0; i < dataSeriesLength; i++) {
1867                                if (rtypes[i] == 0) {
1868                                        (*data)[i] = decmpData[k++];
1869                                }
1870                        }
1871                        free(decmpData);
1872                        free(rtypes);
1873                }
1874        }
1875}
Note: See TracBrowser for help on using the repository browser.