szd_double.c 6.7 KB
Newer Older
T
tickduan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 *  @file szd_double.c
 *  @author Sheng Di, Dingwen Tao, Xin Liang, Xiangyu Zou, Tao Lu, Wen Xia, Xuan Wang, Weizhe Zhang
 *  @date Aug, 2016
 *  @brief 
 *  (C) 2016 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#include <stdlib.h> 
#include <stdio.h>
#include <string.h>
#include "szd_double.h"
#include "TightDataPointStorageD.h"
#include "sz.h"
#include "utility.h"
T
tickduan 已提交
17
#include "Huffman.h"
T
tickduan 已提交
18

T
tickduan 已提交
19 20
int SZ_decompress_args_double(double* newData, size_t r1, unsigned char* cmpBytes, 
				size_t cmpSize, int compressionType, double* hist_data, sz_exedata* pde_exe, sz_params* pde_params)
T
tickduan 已提交
21
{
T
tickduan 已提交
22 23
	int status = SZ_SUCCESS;
	size_t dataLength = r1;
T
tickduan 已提交
24 25 26 27 28
	
	//unsigned char* tmpBytes;
	size_t targetUncompressSize = dataLength <<3; //i.e., *8
	//tmpSize must be "much" smaller than dataLength
	size_t i, tmpSize = 12+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE;
T
tickduan 已提交
29 30 31
	unsigned char* szTmpBytes = NULL;
	bool needFree = false;

T
tickduan 已提交
32 33
	if(cmpSize!=12+4+MetaDataByteLength_double && cmpSize!=12+8+MetaDataByteLength_double)
	{
T
tickduan 已提交
34 35
		pde_params->losslessCompressor = is_lossless_compressed_data(cmpBytes, cmpSize);
		if(pde_params->szMode!=SZ_TEMPORAL_COMPRESSION)
T
tickduan 已提交
36
		{
T
tickduan 已提交
37 38
			if(pde_params->losslessCompressor!=-1)
				pde_params->szMode = SZ_BEST_COMPRESSION;
T
tickduan 已提交
39
			else
T
tickduan 已提交
40
				pde_params->szMode = SZ_BEST_SPEED;			
T
tickduan 已提交
41
		}
T
tickduan 已提交
42 43


T
tickduan 已提交
44
		if(pde_params->szMode==SZ_BEST_SPEED)
T
tickduan 已提交
45 46 47 48
		{
			tmpSize = cmpSize;
			szTmpBytes = cmpBytes;	
		}	
T
tickduan 已提交
49
		else
T
tickduan 已提交
50 51 52
		{
			if(targetUncompressSize<MIN_ZLIB_DEC_ALLOMEM_BYTES) //Considering the minimum size
				targetUncompressSize = MIN_ZLIB_DEC_ALLOMEM_BYTES; 			
T
tickduan 已提交
53
			tmpSize = sz_lossless_decompress(pde_params->losslessCompressor, cmpBytes, (unsigned long)cmpSize, &szTmpBytes, (unsigned long)targetUncompressSize+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE);			
T
tickduan 已提交
54
	        needFree = true;	
T
tickduan 已提交
55 56 57 58
		}
	}
	else
		szTmpBytes = cmpBytes;
T
tickduan 已提交
59 60 61
	
	// calc postion 
	//pde_params->sol_ID = szTmpBytes[1+3-2+14-4]; //szTmpBytes: version(3bytes), samebyte(1byte), [14]:sol_ID=SZ or SZ_Transpose		
T
tickduan 已提交
62
	//TODO: convert szTmpBytes to double array.
T
tickduan 已提交
63
	TightDataPointStorageD* tdps = NULL;
T
tickduan 已提交
64
	int errBoundMode = new_TightDataPointStorageD_fromFlatBytes(&tdps, szTmpBytes, tmpSize, pde_exe, pde_params);
T
tickduan 已提交
65 66 67 68
	if(tdps == NULL)
	{
		return SZ_FORMAT_ERR;
	}
T
tickduan 已提交
69 70 71 72

	int doubleSize = sizeof(double);
	if(tdps->isLossless)
	{
T
tickduan 已提交
73
		// *newData = (double*)malloc(doubleSize*dataLength); comment by tickduan
T
tickduan 已提交
74 75
		if(sysEndianType==BIG_ENDIAN_SYSTEM)
		{
T
tickduan 已提交
76
			memcpy(newData, szTmpBytes+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE, dataLength*doubleSize);
T
tickduan 已提交
77 78 79 80 81
		}
		else
		{
			unsigned char* p = szTmpBytes+4+MetaDataByteLength_double+exe_params->SZ_SIZE_TYPE;
			for(i=0;i<dataLength;i++,p+=doubleSize)
T
tickduan 已提交
82
				newData[i] = bytesToDouble(p);
T
tickduan 已提交
83 84
		}		
	}
T
tickduan 已提交
85
	else if(pde_params->sol_ID==SZ_Transpose)
T
tickduan 已提交
86
	{
T
tickduan 已提交
87
		getSnapshotData_double_1D(newData,dataLength,tdps, errBoundMode, 0, hist_data, pde_params);		
T
tickduan 已提交
88
	}
T
tickduan 已提交
89
	else //pde_params->sol_ID==SZ
T
tickduan 已提交
90 91 92
	{
		if(tdps->raBytes_size > 0) //v2.0
		{
T
tickduan 已提交
93
			getSnapshotData_double_1D(newData,r1,tdps, errBoundMode, 0, hist_data, pde_params);
T
tickduan 已提交
94 95 96
		}
		else //1.4.13 or time-based compression
		{
T
tickduan 已提交
97
			getSnapshotData_double_1D(newData,r1,tdps, errBoundMode, compressionType, hist_data, pde_params);
T
tickduan 已提交
98 99 100 101
		}
	}	

	free_TightDataPointStorageD2(tdps);
T
tickduan 已提交
102
	if(szTmpBytes && needFree)
T
tickduan 已提交
103 104 105 106
		free(szTmpBytes);	
	return status;
}

T
tickduan 已提交
107
void decompressDataSeries_double_1D(double* data, size_t dataSeriesLength, double* hist_data, TightDataPointStorageD* tdps) 
T
tickduan 已提交
108 109 110 111 112 113 114 115 116 117 118
{
	//updateQuantizationInfo(tdps->intervals);
	int intvRadius = tdps->intervals/2;
	size_t i, j, k = 0, p = 0, l = 0; // k is to track the location of residual_bit
								// in resiMidBits, p is to track the
								// byte_index of resiMidBits, l is for
								// leadNum
	unsigned char* leadNum;
	double interval = tdps->realPrecision*2;
	
	convertByteArray2IntArray_fast_2b(tdps->exactDataNum, tdps->leadNumArray, tdps->leadNumArray_size, &leadNum);
T
tickduan 已提交
119
	//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

	int* type = (int*)malloc(dataSeriesLength*sizeof(int));
	HuffmanTree* huffmanTree = createHuffmanTree(tdps->stateNum);
	decode_withTree(huffmanTree, tdps->typeArray, dataSeriesLength, type);
	SZ_ReleaseHuffman(huffmanTree);	
	
	unsigned char preBytes[8];
	unsigned char curBytes[8];
	
	memset(preBytes, 0, 8);

	size_t curByteIndex = 0;
	int reqBytesLength, resiBitsLength, resiBits; 
	unsigned char leadingNum;	
	double medianValue, exactData, predValue;
	
	reqBytesLength = tdps->reqLength/8;
	resiBitsLength = tdps->reqLength%8;
	medianValue = tdps->medianValue;
	
T
tickduan 已提交
140

T
tickduan 已提交
141
	int type_;
T
tickduan 已提交
142 143
	for (i = 0; i < dataSeriesLength; i++) 
	{
T
tickduan 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
		type_ = type[i];
		switch (type_) {
		case 0:
			// compute resiBits
			resiBits = 0;
			if (resiBitsLength != 0) {
				int kMod8 = k % 8;
				int rightMovSteps = getRightMovingSteps(kMod8, resiBitsLength);
				if (rightMovSteps > 0) {
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code) >> rightMovSteps;
				} else if (rightMovSteps < 0) {
					int code1 = getLeftMovingCode(kMod8);
					int code2 = getRightMovingCode(kMod8, resiBitsLength);
					int leftMovSteps = -rightMovSteps;
					rightMovSteps = 8 - leftMovSteps;
					resiBits = (tdps->residualMidBits[p] & code1) << leftMovSteps;
					p++;
					resiBits = resiBits
							| ((tdps->residualMidBits[p] & code2) >> rightMovSteps);
				} else // rightMovSteps == 0
				{
					int code = getRightMovingCode(kMod8, resiBitsLength);
					resiBits = (tdps->residualMidBits[p] & code);
					p++;
				}
				k += resiBitsLength;
			}

			// recover the exact data
			memset(curBytes, 0, 8);
			leadingNum = leadNum[l++];
			memcpy(curBytes, preBytes, leadingNum);
			for (j = leadingNum; j < reqBytesLength; j++)
				curBytes[j] = tdps->exactMidBytes[curByteIndex++];
			if (resiBitsLength != 0) {
				unsigned char resiByte = (unsigned char) (resiBits << (8 - resiBitsLength));
				curBytes[reqBytesLength] = resiByte;
			}
			
			exactData = bytesToDouble(curBytes);
T
tickduan 已提交
185
			data[i] = exactData + medianValue;
T
tickduan 已提交
186 187 188
			memcpy(preBytes,curBytes,8);
			break;
		default:
T
tickduan 已提交
189 190 191
			//predValue = 2 * data[i-1] - data[i-2];
			predValue = data[i-1];
			data[i] = predValue + (type_-intvRadius)*interval;
T
tickduan 已提交
192 193
			break;
		}
T
tickduan 已提交
194
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
195 196 197 198 199 200 201 202
	}
	
	free(leadNum);
	free(type);
	return;
}


T
tickduan 已提交
203
void getSnapshotData_double_1D(double* data, size_t dataSeriesLength, TightDataPointStorageD* tdps, int errBoundMode, int compressionType, double* hist_data, sz_params* pde_params) 
T
tickduan 已提交
204
{
T
tickduan 已提交
205 206 207
	size_t i;
	if (tdps->allSameData) {
		double value = bytesToDouble(tdps->exactMidBytes);
T
tickduan 已提交
208 209

		//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
210
		for (i = 0; i < dataSeriesLength; i++)
T
tickduan 已提交
211
			data[i] = value;
T
tickduan 已提交
212 213 214 215
	} 
	else 
	{
		decompressDataSeries_double_1D(data, dataSeriesLength, hist_data, tdps);
T
tickduan 已提交
216 217 218
	}
}