FPR_DATA* GetFPRData(const char* replayPath, int* nElements) {
    REPLAY_FOOTER footer;
    FILE* fpReplay = fopen(replayPath, "rb");
    fpos_t posBegin;
    fgetpos(fpReplay, &posBegin);
    int fileSize = FileSize(fpReplay);
    fpos_t posFooter = posBegin + fileSize - sizeof(REPLAY_FOOTER);
    fsetpos(fpReplay, &posFooter);
    fread(&footer, sizeof(REPLAY_FOOTER), 1, fpReplay);

    // check if the footer is valid
    if (footer.magic1 != MAGIC_1 || footer.magic2 != MAGIC_2 || footer.magic3 != MAGIC_3) {
        *nElements = 0;
        return 0;
    }

    // read the compressed data
    unsigned char* pCompressedData = (unsigned char*)malloc(footer.sizeOfData);
    fpos_t posData = posFooter - footer.sizeOfData;
    fsetpos(fpReplay, &posData);
    fread(pCompressedData, footer.sizeOfData, 1, fpReplay);
    fclose(fpReplay);

    // uncompress the data
    long uncompressedSize = 1;
    unsigned char* pUncompressedData = (unsigned char*)malloc(uncompressedSize);
    int nErr = ezuncompress( pUncompressedData, &uncompressedSize, pCompressedData, footer.sizeOfData );
    if ( nErr == EZ_BUF_ERROR ) {
        free(pUncompressedData);
        pUncompressedData = (unsigned char*)malloc(uncompressedSize); // enough room now
        nErr = ezuncompress( pUncompressedData, &uncompressedSize, pCompressedData, footer.sizeOfData );
    }
    switch (nErr) {
        case EZ_NO_ERROR:
        break;
        case EZ_STREAM_ERROR:   //	-2	pDest is NULL
            MessageBox(0,"easyzlib: pDest is NULL.","ERROR.",0);
            break;
        case EZ_DATA_ERROR:	    // -3	corrupted pSrc passed to ezuncompress
            MessageBox(0,"easyzlib: corrupted pSrc passed to ezuncompress.","ERROR.",0);
            break;
        case EZ_MEM_ERROR:	    // -4	out of memory
            MessageBox(0,"easyzlib: out of memory.","ERROR.",0);
            break;
        case EZ_BUF_ERROR:	    // -5	pDest length is not enough
            MessageBox(0,"easyzlib: pDest length is not enough.","ERROR.",0);
            break;
        default:
            MessageBox(0,"Wrong Error code for easyzlib.","ERROR.",0);
            break;
    }

    FPR_DATA* pData = (FPR_DATA*)pUncompressedData;
    *nElements = uncompressedSize / sizeof(FPR_DATA);
    return pData;
}
IxaBOOL uncompressSwfZlib(IxaUI8* ptrDest, const IxaUI32 destLen, const IxaUI8* ptrSrc, const IxaUI32 srcLen) {
    //Ixaya-swf depends on a method to uncompress ZLIB data.
    //For this demo you can download EasyZLIB ("easyzlib.h" and "easyzlib.c")
    //and copy them into "ixaya-swf/src/c/" folder. http://www.firstobject.com/easy-zlib-c++-xml-compression.htm
    long destLenLng = destLen;
    if(0 == ezuncompress(ptrDest, &destLenLng, ptrSrc, srcLen)) {
        return IXA_TRUE;
    }
    return IXA_FALSE;
}
Exemple #3
0
int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int *flags, uint8 **image) {
	if (zim[0] != 'Z' || zim[1] != 'I' || zim[2] != 'M' || zim[3] != 'G') {
		ELOG("Not a ZIM file");
		return 0;
	}
	memcpy(width, zim + 4, 4);
	memcpy(height, zim + 8, 4);
	memcpy(flags, zim + 12, 4);

	int num_levels = 1;
	int image_data_size[ZIM_MAX_MIP_LEVELS];
	if (*flags & ZIM_HAS_MIPS) {
		num_levels = log2i(*width < *height ? *width : *height) + 1;
	}
	int total_data_size = 0;
	for (int i = 0; i < num_levels; i++) {
		if (i > 0) {
			width[i] = width[i-1] / 2;
			height[i] = height[i-1] / 2;
		}
		switch (*flags & ZIM_FORMAT_MASK) {
		case ZIM_RGBA8888:
			image_data_size[i] = width[i] * height[i] * 4; 
			break;
		case ZIM_RGBA4444:
		case ZIM_RGB565:
			image_data_size[i] = width[i] * height[i] * 2;
			break;
		case ZIM_ETC1:
			{
				int data_width = width[i];
				int data_height = height[i];
				if (data_width < 4) data_width = 4;
				if (data_height < 4) data_height = 4;
				image_data_size[i] = data_width * data_height / 2;
				break;
			}
		default:
			ELOG("Invalid ZIM format %i", *flags & ZIM_FORMAT_MASK);
			return 0;
		}
		total_data_size += image_data_size[i];
	}

	if (total_data_size == 0)
	{
		ELOG("Invalid ZIM data size 0");
		return 0;
	}

	image[0] = (uint8 *)malloc(total_data_size);
	for (int i = 1; i < num_levels; i++) {
		image[i] = image[i-1] + image_data_size[i-1];
	}

	if (*flags & ZIM_ZLIB_COMPRESSED) {
		long outlen = (long)total_data_size;
		if (Z_OK != ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)datasize - 16)) {
			free(*image);
			*image = 0;
			return 0;
		}
		if (outlen != total_data_size) {
			ELOG("Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size);
		}
	} else {
		memcpy(*image, zim + 16, datasize - 16);
		if (datasize - 16 != (size_t)total_data_size) {
			ELOG("Wrong size data in ZIM: %i vs %i", (int)(datasize-16), (int)total_data_size);
		}
	}
	return num_levels;
}
/// if we pack, compress, encode on the way in, that means, therefore, we
/// need to decode, uncompress, then unpack on our way out. Right?
///
/// This function will base64-DECODE the string contents, then uncompress them using
/// zlib, and then unpack the result using whatever is the default packer (MsgPack, Protobuf, etc).
/// 
/// I originally added compression because message sizes were too big. Now I'm adding packing, 
/// to solve any issues of binary compatibility across various platforms.
//
bool OTASCIIArmor::GetAndUnpackString(OTString & strData, bool bLineBreaks) const //bLineBreaks=true
{	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	strData.Release();
	
	if (GetLength() < 1)
	{
		return true;
	}
	// --------------------------------------------------------------
	pData = OTCrypto::It()->Base64Decode(this->Get(), &outSize, bLineBreaks);
//	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
		// -------------------------------------------
		// EASY ZLIB
		//
		long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.)
		unsigned char* pDest = new unsigned char [nDestLen+10]; // For safety.
		
		OT_ASSERT(NULL != pDest);
		
		int nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) );
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = new unsigned char [nDestLen]; // enough room now
			
			OT_ASSERT(NULL != pDest);
			
			nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) );
		}
		
		// Now we're done with this memory, let's free it.
		delete [] pData; pData=NULL;
		// ----------------------------------------
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("Buffer error in OTASCIIArmor::GetAndUnpackString\n");
		}
		else if ( nErr == EZ_STREAM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("pDest is NULL in OTASCIIArmor::GetAndUnpackString\n");
		}
		else if ( nErr == EZ_DATA_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OTLog::vError("corrupted pSrc passed to ezuncompress OTASCIIArmor::GetAndUnpackString, size: %d\n", outSize);
			OT_FAIL;
		}
		else if ( nErr == EZ_MEM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_FAIL_MSG("Out of memory in OTASCIIArmor::GetAndUnpackString\n");
		}
		// ---------------------------------------
		// PUT THE PACKED BUFFER HERE, AND UNPACK INTO strData
		// --------------------------------------------------------
		OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either.
		
		OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up.
		OT_ASSERT(NULL != pBuffer);
		OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // This will make sure buffer is deleted later.
		
		const size_t theDestLen = nDestLen;
		
		pBuffer->SetData(pDest, // const unsigned char *
						 theDestLen);

		delete [] pDest; pDest=NULL; 
		// -----------------------------
		OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING));
		OT_ASSERT(NULL != pOTDBString);
		OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // clean up this string.
		
		bool bUnpacked = pPacker->Unpack(*pBuffer, *pOTDBString);
		// ----------------------
		if (false == bUnpacked)
		{
			OTLog::Error("Failed unpacking string in OTASCIIArmor::GetAndUnpackString.\n");
			
			return false;
		}
		// --------------------------------------------------------
		// This enforces the null termination. (using the 2nd parameter as nEnforcedMaxLength)
		strData.Set(pOTDBString->m_string.c_str(), static_cast<uint32_t> (pOTDBString->m_string.length()));
		
		return true;
	}
	else 
	{
		OTLog::Error("OTASCIIArmor::GetAndUnpackString: NULL pData while base64-decoding pData.\n");
		return false;
	}
}
bool OTASCIIArmor::GetString(OTString & theData, bool bLineBreaks) const //bLineBreaks=true
{	
	return GetAndUnpackString(theData, bLineBreaks);
	
	
	
	
	
	size_t		outSize	= 0;
	uint8_t *	pData	= NULL;
	
	theData.Release();
	
	if (GetLength() < 1) {
		return true;
	}
	
	pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0));
	
	if (pData)
	{
		long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.)
		unsigned char* pDest = new unsigned char [nDestLen+10]; // For safety.
		
		OT_ASSERT(NULL != pDest);
		
		int nErr = ezuncompress( pDest, &nDestLen, pData, outSize );
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = new unsigned char [nDestLen]; // enough room now
			
			OT_ASSERT(NULL != pDest);
			
			nErr = ezuncompress( pDest, &nDestLen, pData, outSize );
		}
		
		// Now we're done with this memory, let's free it.
		delete [] pData; pData=NULL;
		
		// ----------------------------------------
		
		if ( nErr == EZ_BUF_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_ASSERT_MSG(false, "Buffer error in OTASCIIArmor::GetString\n");
			return false; // not really necessary but just making sure.
		}
		else if ( nErr == EZ_STREAM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_ASSERT_MSG(false, "pDest is NULL in OTASCIIArmor::GetString\n");
			return false; // not really necessary but just making sure.
		}
		else if ( nErr == EZ_DATA_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OTLog::vError("corrupted pSrc passed to ezuncompress OTASCIIArmor::GetString, size: %d\n", outSize);
			
			OT_ASSERT(false);
			
			return false; // not really necessary but just making sure.
		}
		else if ( nErr == EZ_MEM_ERROR )
		{
			delete [] pDest;
			pDest = NULL;
			
			OT_ASSERT_MSG(false, "Out of memory in OTASCIIArmor::GetString\n");
			return false; // not really necessary but just making sure.
		}
		
		// This enforces the null termination. (using the extra parameter nDestLen as nEnforcedMaxLength)
		theData.Set((const char*)pDest, nDestLen);
		
		delete [] pDest; pDest=NULL; 
		return true;
	}
	else 
	{
		OTLog::Error("NULL pData while base64_decodeing pData.\n");
		return false;
	}
}