/* * LZMA compressed segment format(simplified) * ------------------------------------------ * Offset Size Description * 0 1 Special LZMA properties for compressed data * 1 4 Dictionary size (little endian) * 13 Compressed data * * Derived from http://docs.bugaco.com/7zip/lzma.txt * We do not store the uncompressed chunk size here. It is stored in * our chunk header. */ int lzma_compress(void *src, uint64_t srclen, void *dst, uint64_t *dstlen, int level, uchar_t chdr, int btype, void *data) { SizeT props_len = LZMA_PROPS_SIZE; SRes res; Byte *_dst; CLzmaEncProps *props = (CLzmaEncProps *)data; SizeT dlen; if (*dstlen < LZMA_PROPS_SIZE) { lzerr(SZ_ERROR_DESTLEN, 1); return (-1); } if (PC_SUBTYPE(btype) == TYPE_COMPRESSED_ZPAQ) return (-1); props->level = level; _dst = (Byte *)dst; *dstlen -= LZMA_PROPS_SIZE; dlen = *dstlen; res = LzmaEncode(_dst + LZMA_PROPS_SIZE, &dlen, (const uchar_t *)src, srclen, props, (uchar_t *)_dst, &props_len, 0, NULL, &g_Alloc, &g_Alloc); *dstlen = dlen; if (res != 0) { lzerr(res, 1); return (-1); } *dstlen += LZMA_PROPS_SIZE; return (0); }
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, unsigned char *outProps, size_t *outPropsSize, int level, /* 0 <= level <= 9, default = 5 */ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ int lc, /* 0 <= lc <= 8, default = 3 */ int lp, /* 0 <= lp <= 4, default = 0 */ int pb, /* 0 <= pb <= 4, default = 2 */ int fb, /* 5 <= fb <= 273, default = 32 */ int numThreads, /* 1 or 2, default = 2 */ int algo /* 0 = fast, 1 = normal */ ) { CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = level; props.dictSize = dictSize; props.lc = lc; props.lp = lp; props.pb = pb; props.fb = fb; props.numThreads = numThreads; props.algo = algo; return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, NULL, &g_Alloc, &g_Alloc); }
bool CCCrypto::compressData( const unsigned char* pInData, unsigned int nInSize, unsigned char* pOutData, unsigned int& nOutSize ) { if ( nOutSize <= sizeof(stHead) ) return false; nOutSize -= sizeof(stHead); unsigned int propsSize = LZMA_PROPS_SIZE; CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = 1; // props.dictSize = 1 << 26; // 64 MB // props.fb = 64; // props.level = 1; // props.dictSize = 1 << 12; // props.algo = 0; props.writeEndMark = 0; // 0 or 1 stHead* phead = (stHead*)pOutData; int res = LzmaEncode( &(pOutData[sizeof(stHead)]), (SizeT*)&nOutSize, pInData, nInSize, &props, (phead->m_szPorp), (SizeT*)&propsSize, props.writeEndMark, NULL, &SzAllocForLzma, &SzAllocForLzma ); // 隐含的要求pOutData必须大于LZMA_PROPS_SIZE+4 if ( res == SZ_OK && propsSize == LZMA_PROPS_SIZE ) { nOutSize += sizeof(stHead); phead->m_szPorp[3] ^= 5; phead->m_OriginalSize = nInSize^1002; phead->m_sign = '@Fml'; phead->m_nRandomValue = rand()%256; for ( unsigned i = 0; i < 16 && i < nOutSize; i ++ ) { pOutData[sizeof(stHead)+i] ^= 6636; } return true; } return false; }
int64_t lzbench_lzma_compress(char *inbuf, size_t insize, char *outbuf, size_t outsize, size_t level, size_t, size_t) { char rs[800] = { 0 }; CLzmaEncProps props; int res; size_t headerSize = LZMA_PROPS_SIZE; SizeT out_len = outsize - LZMA_PROPS_SIZE; LzmaEncProps_Init(&props); props.level = level; LzmaEncProps_Normalize(&props); /* p->level = 5; p->dictSize = p->mc = 0; p->reduceSize = (UInt64)(Int64)-1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; p->writeEndMark = 0; */ res = LzmaEncode((uint8_t*)outbuf+LZMA_PROPS_SIZE, &out_len, (uint8_t*)inbuf, insize, &props, (uint8_t*)outbuf, &headerSize, 0/*int writeEndMark*/, NULL, &g_Alloc, &g_Alloc); if (res != SZ_OK) return 0; // printf("out_len=%u LZMA_PROPS_SIZE=%d headerSize=%d\n", (int)(out_len + LZMA_PROPS_SIZE), LZMA_PROPS_SIZE, (int)headerSize); return LZMA_PROPS_SIZE + out_len; }
uint8_t* encodeLZMA(System* s, avian::util::Alloc* a, uint8_t* in, unsigned inSize, unsigned* outSize) { const unsigned PropHeaderSize = 5; const unsigned HeaderSize = 13; unsigned bufferSize = inSize * 2; uint8_t* buffer = static_cast<uint8_t*>(a->allocate(bufferSize)); LzmaAllocator allocator(a); CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = 9; props.writeEndMark = 1; ICompressProgress progress = {myProgress}; SizeT propsSize = PropHeaderSize; int32_t inSize32 = inSize; memcpy(buffer + PropHeaderSize, &inSize32, 4); SizeT outSizeT = bufferSize; int result = LzmaEncode(buffer + HeaderSize, &outSizeT, in, inSize, &props, buffer, &propsSize, 1, &progress, &(allocator.allocator), &(allocator.allocator)); expect(s, result == SZ_OK); *outSize = outSizeT + HeaderSize; uint8_t* out = static_cast<uint8_t*>(a->allocate(*outSize)); memcpy(out, buffer, *outSize); a->free(buffer, bufferSize); return out; }
EFI_STATUS EFIAPI LzmaCompress ( CONST UINT8 *Source, UINT32 SourceSize, UINT8 *Destination, UINT32 *DestinationSize, UINT32 DictionarySize ) { SRes LzmaResult; CLzmaEncProps props; SizeT propsSize = LZMA_PROPS_SIZE; SizeT destLen = SourceSize + SourceSize / 3 + 128; if (*DestinationSize < (UINT32)destLen) { *DestinationSize = (UINT32)destLen; return EFI_BUFFER_TOO_SMALL; } LzmaEncProps_Init(&props); props.dictSize = DictionarySize; props.level = 9; props.fb = 273; LzmaResult = LzmaEncode( (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), &destLen, Source, (SizeT)SourceSize, &props, (UINT8*)Destination, &propsSize, props.writeEndMark, &g_ProgressCallback, &SzAllocForLzma, &SzAllocForLzma); *DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE); SetEncodedSizeOfBuf(SourceSize, Destination); if (LzmaResult == SZ_OK) { return EFI_SUCCESS; } else { return EFI_INVALID_PARAMETER; } }
bool zmodifyer::compress( unsigned char const * src, size_t srcLen, unsigned char * dest, size_t & destLen, int level /* = 5 */ ) { if( !src || !dest || destLen < 10 ) return false; CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = level; props.algo = 0; props.lc = 3; props.lp = 0; props.pb = 2; static const unsigned int kb = 1024; if( srcLen > 1024 * 1024 * kb ) { props.dictSize = 16 * 1024 * kb; props.fb = 32; } else if( srcLen > 1024 * kb ) { props.dictSize = 4 * 1024 * kb; props.fb = 16; } else if( srcLen > kb ) { props.dictSize = 64 * kb; props.fb = 8; } else { props.dictSize = 64 * kb; props.fb = 8; } props.numThreads = 2; size_t outPropsSize = 5; int result = LzmaEncode(dest+10, &destLen, src, srcLen, &props, dest, &outPropsSize, 0, NULL, &alloctator, &alloctator); *(dest+5) = (unsigned char)outPropsSize; *(unsigned int*)(dest+6) = srcLen; destLen += 10; return (result == SZ_OK) ? true : false; }
int LzmaCompress(char *in_data, int in_size, char *out_data, int out_size, unsigned long *total_out) { CLzmaEncProps props; size_t headerSize = LZMA_PROPS_SIZE; int ret; SizeT outProcess; LzmaEncProps_Init(&props); props.algo = 1; outProcess = out_size - LZMA_PROPS_SIZE; ret = LzmaEncode(out_data+LZMA_PROPS_SIZE, &outProcess, in_data, in_size, &props, out_data, &headerSize, 0, NULL, &g_Alloc, &g_Alloc); *total_out = outProcess + LZMA_PROPS_SIZE; return ret; }
EFI_STATUS LzmaCompress ( IN UINT8 *Source, IN UINT32 SourceSize, IN UINT8 *Destination, IN OUT UINT32 *DestinationSize ) { SRes LzmaResult; CLzmaEncProps props; SizeT propsSize = LZMA_PROPS_SIZE; SizeT destLen = SourceSize + SourceSize / 3 + 128; if (*DestinationSize < destLen) { *DestinationSize = destLen; return EFI_BUFFER_TOO_SMALL; } LzmaEncProps_Init(&props); props.dictSize = LZMA_DICTIONARY_SIZE; props.level = 9; props.fb = 273; LzmaResult = LzmaEncode( (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), &destLen, (VOID*)Source, SourceSize, &props, (UINT8*)Destination, &propsSize, props.writeEndMark, &g_ProgressCallback, &SzAllocForLzma, &SzAllocForLzma); *DestinationSize = destLen + LZMA_HEADER_SIZE; SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); if (LzmaResult == SZ_OK) { return EFI_SUCCESS; } else { return EFI_INVALID_PARAMETER; } }
static bool Compress(const char *uncompressed, size_t uncompressedSize, char *compressed, size_t *compressedSize) { ISzCrtAlloc lzmaAlloc; CrashIf(*compressedSize < uncompressedSize + 1); if (*compressedSize < uncompressedSize + 1) return false; if (*compressedSize < LZMA_HEADER_SIZE) goto StoreUncompressed; CLzmaEncProps props; LzmaEncProps_Init(&props); // always apply the BCJ filter for speed (else two or three compression passes would be required) size_t lzma_size = (size_t)-1; uint8_t *bcj_enc = (uint8_t *)malloc(uncompressedSize); if (bcj_enc) { memcpy(bcj_enc, uncompressed, uncompressedSize); UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(bcj_enc, uncompressedSize, 0, &x86State, 1); } SizeT outSize = *compressedSize - LZMA_HEADER_SIZE; SizeT propsSize = LZMA_PROPS_SIZE; SRes res = LzmaEncode((Byte *)compressed + LZMA_HEADER_SIZE, &outSize, bcj_enc ? bcj_enc : (const Byte *)uncompressed, uncompressedSize, &props, (Byte *)compressed + 1, &propsSize, TRUE /* add EOS marker */, NULL, &lzmaAlloc, &lzmaAlloc); if (SZ_OK == res && propsSize == LZMA_PROPS_SIZE) lzma_size = outSize + LZMA_HEADER_SIZE; free(bcj_enc); if (lzma_size < uncompressedSize + 1) { compressed[0] = bcj_enc ? 1 : 0; *compressedSize = lzma_size; } else { StoreUncompressed: compressed[0] = (uint8_t)-1; memcpy(compressed + 1, uncompressed, uncompressedSize); *compressedSize = uncompressedSize + 1; } return true; }
void* CBAWMeshWriter::compressWithLzma(const void* _input, size_t _inputSize, size_t& _outComprSize) const { ISzAlloc alloc{&asset::LzmaMemMngmnt::alloc, &asset::LzmaMemMngmnt::release}; SizeT propsSize = LZMA_PROPS_SIZE; UInt32 dictSize = _inputSize; // next nearest (to input size) power of two times two --dictSize; for (uint32_t p = 1; p < 32; p <<= 1) dictSize |= dictSize>>p; ++dictSize; dictSize <<= 1; // Lzma props: https://stackoverflow.com/a/21384797/5538150 CLzmaEncProps props; LzmaEncProps_Init(&props); props.dictSize = dictSize; props.level = 5; // compression level [0;9] props.algo = 0; // fast algo: a little worse compression, a little less loading time props.lp = 2; // 2^2==sizeof(float) const SizeT heapSize = _inputSize + LZMA_PROPS_SIZE; uint8_t* data = (uint8_t*)_IRR_ALIGNED_MALLOC(heapSize,_IRR_SIMD_ALIGNMENT); SizeT destSize = heapSize; SRes res = LzmaEncode(data+propsSize, &destSize, (const Byte*)_input, _inputSize, &props, data, &propsSize, props.writeEndMark, NULL, &alloc, &alloc); if (res != SZ_OK) { _IRR_ALIGNED_FREE(data); data = (uint8_t*)const_cast<void*>(_input); destSize = _inputSize; #ifdef _DEBUG os::Printer::log("Failed to compress (lzma). Blob exported without compression.", ELL_WARNING); #endif } _outComprSize = destSize + propsSize; return data; }
void lzmaCompress( unsigned char* destBuf, int &destSize, unsigned char *srcBuf, int srcSize, int compressionLevel ) { SizeT propsSize = LZMA_PROPS_SIZE; SizeT lzmaDestSize = (SizeT)destSize; CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = compressionLevel; //compression level //props.dictSize = 1 << 16; //props.dictSize = 1 << 24; props.writeEndMark = 1; // 0 or 1 int res = LzmaEncode( destBuf+LZMA_PROPS_SIZE, &lzmaDestSize, srcBuf, srcSize, &props, destBuf, &propsSize, props.writeEndMark, &g_ProgressCallback, &SzAllocForLzma, &SzAllocForLzma); destSize = (int)lzmaDestSize + LZMA_PROPS_SIZE; cout << "COMPRESSED " << srcSize << " BYTES DOWN TO " << destSize << endl; if(res != SZ_OK || propsSize != LZMA_PROPS_SIZE) { cout << "ERROR COMPRESSING DATA\n"; cout << res << ',' << propsSize << endl; exit(1); } }
int main( int argc, const char * argv[] ) { if ( argc != 2 ) { fprintf( stderr, "Usage: %s <file to vzip>\n", argv[0] ); return -1; } const char * pszInFileName = argv[1]; FILE * pInFile = fopen( pszInFileName, "rb" ); if ( !pInFile ) { fprintf( stderr, "Error: unable to open \"%s\"\n", pszInFileName ); return -1; } static const size_t uFileNameBufLen = PATH_MAX; char pszOutFileName[uFileNameBufLen]; memcpy( pszOutFileName, pszInFileName, strlen( pszInFileName ) ); strncat( pszOutFileName, ".vz", strlen( ".vz" ) ); FILE * pOutFile = fopen( pszOutFileName, "wb" ); if ( !pOutFile ) { fprintf( stderr, "Error: unable to open \"%s\"\n", pszOutFileName ); return -1; } fseek( pInFile, 0, SEEK_END ); size_t uInFileLen = ftell( pInFile ); fseek( pInFile, 0, SEEK_SET ); fseek( pOutFile, 0, SEEK_SET ); struct VZHeader header = { }; header.V = 'V'; header.Z = 'Z'; header.version = 'a'; time_t now; time( &now ); header.rtime_created = (uint32_t)now; struct VZFooter footer = { }; footer.size = (uint32_t)uInFileLen; footer.z = 'z'; footer.v = 'v'; char * pRawData = (char *)malloc( uInFileLen ); fread( pRawData, 1, uInFileLen, pInFile ); footer.crc = crc32(0, pRawData, uInFileLen ); size_t uCompressedBufferSize = uInFileLen + ( uInFileLen / 3 ) + 128; char * pCompressedData = (char *)malloc( uCompressedBufferSize ); SizeT uCompressedDataLen = uCompressedBufferSize - LZMA_PROPS_SIZE; SizeT uLzmaPropsLen = LZMA_PROPS_SIZE; ISzAlloc allocator = { SzAlloc, SzFree }; CLzmaEncProps props; SRes result = LzmaEncode( (Byte *)pCompressedData + LZMA_PROPS_SIZE, &uCompressedDataLen, (Byte *)pRawData, uInFileLen, &props, (Byte *)pCompressedData, &uLzmaPropsLen, props.writeEndMark, NULL, &allocator, &allocator ); int iRetVal = 0; if (result != SZ_OK) { fprintf(stderr, "Error compressing data: %d", result); iRetVal = -1; } fseek( pOutFile, 0, SEEK_SET ); fwrite( &header, 1, sizeof( header ), pOutFile) ; fwrite( pCompressedData, 1, uLzmaPropsLen + uCompressedDataLen, pOutFile ); fwrite( &footer, 1, sizeof( footer ), pOutFile ); fflush( pOutFile ); free( pCompressedData ); free( pRawData ); fclose( pInFile ); fclose( pOutFile ); return 0; }
static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize) { SRes res; size_t inSize = (size_t)fileSize; Byte *inBuffer = 0; Byte *outBuffer = 0; Byte *filteredStream = 0; size_t outSize; CLzmaEncProps props; LzmaEncProps_Init(&props); LzmaEncProps_Normalize(&props); if (inSize != 0) { inBuffer = (Byte *)MyAlloc(inSize); if (inBuffer == 0) return SZ_ERROR_MEM; } else { return SZ_ERROR_INPUT_EOF; } if (SeqInStream_Read(inStream, inBuffer, inSize) != SZ_OK) { res = SZ_ERROR_READ; goto Done; } // we allocate 105% of original size + 64KB for output buffer outSize = (size_t)fileSize / 20 * 21 + (1 << 16); outBuffer = (Byte *)MyAlloc(outSize); if (outBuffer == 0) { res = SZ_ERROR_MEM; goto Done; } { int i; for (i = 0; i < 8; i++) outBuffer[i + LZMA_PROPS_SIZE] = (Byte)(fileSize >> (8 * i)); } if (mConType != NoConverter) { filteredStream = (Byte *)MyAlloc(inSize); if (filteredStream == 0) { res = SZ_ERROR_MEM; goto Done; } memcpy(filteredStream, inBuffer, inSize); if (mConType == X86Converter) { { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(filteredStream, (SizeT) inSize, 0, &x86State, 1); } } } { size_t outSizeProcessed = outSize - LZMA_HEADER_SIZE; size_t outPropsSize = LZMA_PROPS_SIZE; res = LzmaEncode(outBuffer + LZMA_HEADER_SIZE, &outSizeProcessed, mConType != NoConverter ? filteredStream : inBuffer, inSize, &props, outBuffer, &outPropsSize, 0, NULL, &g_Alloc, &g_Alloc); if (res != SZ_OK) goto Done; outSize = LZMA_HEADER_SIZE + outSizeProcessed; } if (outStream->Write(outStream, outBuffer, outSize) != outSize) res = SZ_ERROR_WRITE; Done: MyFree(outBuffer); MyFree(inBuffer); MyFree(filteredStream); return res; }
/*static */ void Compress_LZMA( char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer, int * /* pCmpType */, int /* nCmpLevel */) { ICompressProgress Progress; CLzmaEncProps props; ISzAlloc SzAlloc; Byte * destBuffer; SizeT destLen = *pcbOutBuffer; SizeT srcLen = cbInBuffer; Byte encodedProps[LZMA_PROPS_SIZE]; size_t encodedPropsSize = LZMA_PROPS_SIZE; SRes nResult; // Fill the callbacks in structures Progress.Progress = LZMA_Callback_Progress; SzAlloc.Alloc = LZMA_Callback_Alloc; SzAlloc.Free = LZMA_Callback_Free; // Initialize properties LzmaEncProps_Init(&props); // Perform compression destBuffer = (Byte *)pbOutBuffer + LZMA_HEADER_SIZE; destLen = *pcbOutBuffer - LZMA_HEADER_SIZE; nResult = LzmaEncode(destBuffer, &destLen, (Byte *)pbInBuffer, srcLen, &props, encodedProps, &encodedPropsSize, 0, &Progress, &SzAlloc, &SzAlloc); if(nResult != SZ_OK) return; // If we failed to compress the data if(destLen >= (SizeT)(*pcbOutBuffer - LZMA_HEADER_SIZE)) return; // Write "useFilter" variable. Blizzard MPQ must not use filter. *pbOutBuffer++ = 0; // Copy the encoded properties to the output buffer memcpy(pbOutBuffer, encodedProps, encodedPropsSize); pbOutBuffer += encodedPropsSize; // Copy the size of the data *pbOutBuffer++ = (unsigned char)(srcLen >> 0x00); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x08); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x10); *pbOutBuffer++ = (unsigned char)(srcLen >> 0x18); *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; *pbOutBuffer++ = 0; // Give the size of the data to the caller *pcbOutBuffer = (unsigned int)(destLen + LZMA_HEADER_SIZE); }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int level, UInt32 dictSize, int filterMode) { ISzAlloc g_Alloc = { SzAlloc, SzFree }; size_t outSize2 = *destLen; Byte *filteredStream; Bool useFilter; int mainResult = SZ_ERROR_OUTPUT_EOF; CLzmaEncProps props; LzmaEncProps_Init(&props); props.level = level; props.dictSize = dictSize; *destLen = 0; if (outSize2 < LZMA86_HEADER_SIZE) return SZ_ERROR_OUTPUT_EOF; { int i; UInt64 t = srcLen; for (i = 0; i < 8; i++, t >>= 8) dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; } filteredStream = 0; useFilter = (filterMode != SZ_FILTER_NO); if (useFilter) { if (srcLen != 0) { filteredStream = (Byte *)MyAlloc(srcLen); if (filteredStream == 0) return SZ_ERROR_MEM; memcpy(filteredStream, src, srcLen); } { UInt32 x86State; x86_Convert_Init(x86State); x86_Convert(filteredStream, srcLen, 0, &x86State, 1); } } { size_t minSize = 0; Bool bestIsFiltered = False; /* passes for SZ_FILTER_AUTO: 0 - BCJ + LZMA 1 - LZMA 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. */ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; int i; for (i = 0; i < numPasses; i++) { size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; size_t outPropsSize = 5; SRes curRes; Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); if (curModeIsFiltered && !bestIsFiltered) break; if (useFilter && i == 0) curModeIsFiltered = True; curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, curModeIsFiltered ? filteredStream : src, srcLen, &props, dest + 1, &outPropsSize, 0, NULL, &g_Alloc, &g_Alloc); if (curRes != SZ_ERROR_OUTPUT_EOF) { if (curRes != SZ_OK) { mainResult = curRes; break; } if (outSizeProcessed <= minSize || mainResult != SZ_OK) { minSize = outSizeProcessed; bestIsFiltered = curModeIsFiltered; mainResult = SZ_OK; } } } dest[0] = (Byte)(bestIsFiltered ? 1 : 0); *destLen = LZMA86_HEADER_SIZE + minSize; } if (useFilter) MyFree(filteredStream); return mainResult; }
Vector<uint8_t> Image::serialize() const { Vector<uint8_t> result; #define A(...) appendToVector(result, __VA_ARGS__); //imageinfo A(info.architecture); A(info.baseAddress); A(info.entryPoint); A(info.flag); A(info.platformData); A(info.platformData1); A(info.size); A(fileName); A(static_cast<uint32_t>(exports.size())); for(auto &i : exports) { A(i.address); A(i.forward); A(i.name); A(i.nameHash); A(i.ordinal); } A(static_cast<uint32_t>(sections.size())); for(auto &i : sections) { A(i.name); A(i.baseAddress); A(i.size); A(i.flag); } A(static_cast<uint32_t>(imports.size())); for(auto &i : imports) { A(i.libraryName); A(static_cast<uint32_t>(i.functions.size())); for(auto &j : i.functions) { A(j.iat); A(j.name); A(j.nameHash); A(j.ordinal); } } A(static_cast<uint32_t>(relocations.size())); for(auto &i : relocations) A(i); for(auto &i : sections) { A(i.data->get(), i.data->size()); if((i.flag & SectionFlagCode) && i.data->size() > 5) { uint8_t *codeStart = result.end() - i.data->size(); for(size_t j = 0; j < i.data->size() - 5; j ++) { if(codeStart[j] == 0xE8 || codeStart[j] == 0xE9) //call rel32, jmp rel32 { *reinterpret_cast<int32_t *>(codeStart + j + 1) += (j + 5); j += 4; } else if(codeStart[j] == 0x0f && (codeStart[j + 1] >= 0x80 && codeStart[j + 1] <= 0x8f)) //conditional jmp rel32 { *reinterpret_cast<int32_t *>(codeStart + j + 2) += (j + 6); j += 5; } } } } A(header->get(), header->size()); #undef A CLzmaEncProps props; LzmaEncProps_Init(&props); props.numThreads = 1; LzmaEncProps_Normalize(&props); uint32_t sizeSize = sizeof(uint32_t) * 2; uint32_t propsSize = LZMA_PROPS_SIZE; uint32_t outSize = result.size() + result.size() / 40 + (1 << 12); //igor recommends (http://sourceforge.net/p/sevenzip/discussion/45798/thread/dd3b392c/) Vector<uint8_t> compressed(outSize + propsSize + sizeSize); LzmaEncode(&compressed[propsSize + sizeSize], &outSize, &result[0], result.size(), &props, &compressed[sizeSize], &propsSize, 0, nullptr, &g_Alloc, &g_Alloc); *reinterpret_cast<uint32_t *>(&compressed[0]) = result.size(); *reinterpret_cast<uint32_t *>(&compressed[sizeof(uint32_t)]) = outSize; compressed.resize(outSize + propsSize + sizeSize); return compressed; }