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

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

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

T
tickduan 已提交
108
void decompressDataSeries_double_1D(double* data, size_t dataSeriesLength, double* hist_data, TightDataPointStorageD* tdps) 
T
tickduan 已提交
109 110 111 112 113 114 115 116 117 118 119
{
	//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 已提交
120
	//*data = (double*)malloc(sizeof(double)*dataSeriesLength); comment by tickduan
T
tickduan 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

	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 已提交
141

T
tickduan 已提交
142
	int type_;
T
tickduan 已提交
143 144
	for (i = 0; i < dataSeriesLength; i++) 
	{
T
tickduan 已提交
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 185
		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 已提交
186
			data[i] = exactData + medianValue;
T
tickduan 已提交
187 188 189
			memcpy(preBytes,curBytes,8);
			break;
		default:
T
tickduan 已提交
190 191 192
			//predValue = 2 * data[i-1] - data[i-2];
			predValue = data[i-1];
			data[i] = predValue + (type_-intvRadius)*interval;
T
tickduan 已提交
193 194
			break;
		}
T
tickduan 已提交
195
		//printf("%.30G\n",data[i]);
T
tickduan 已提交
196 197 198 199 200 201 202 203
	}
	
	free(leadNum);
	free(type);
	return;
}


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

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