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; }
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; } }