int simpleCompress(elzma_file_format format, const unsigned char * inData, size_t inLen, unsigned char ** outData, size_t * outLen) { int rc = 0; elzma_compress_handle hand; /* allocate compression handle */ hand = elzma_compress_alloc(); assert(hand != NULL); rc = elzma_compress_config(hand, ELZMA_LC_DEFAULT, ELZMA_LP_DEFAULT, ELZMA_PB_DEFAULT, 5, (1 << 20) /* 1mb */, format, inLen); if (rc != ELZMA_E_OK) { elzma_compress_free(&hand); return rc; } /* now run the compression */ { struct dataStream ds; ds.inData = inData; ds.inLen = inLen; ds.outData = NULL; ds.outLen = 0; rc = elzma_compress_run(hand, inputCallback, (void *) &ds, outputCallback, (void *) &ds, NULL, NULL); if (rc != ELZMA_E_OK) { if (ds.outData != NULL) free(ds.outData); elzma_compress_free(&hand); return rc; } *outData = ds.outData; *outLen = ds.outLen; } return rc; }
/////////////////////////////////////////////////////////////////////////// // Packages the files into a binary package. /////////////////////////////////////////////////////////////////////////// void Binpressor::Package() { if (m_descriptors.empty()) return; std::cout << "Packaging File(s)..." << std::endl; _UINT totalSize = 0; _UINT headerSize = 0; for (auto it = m_descriptors.begin(); it != m_descriptors.end(); ++it) { totalSize += atoi((*it)->size); headerSize += NAME_BUFFER + EXT_BUFFER + SIZE_BUFFER; } std::ofstream fstream; fstream.open("package.bin", std::fstream::out | std::fstream::binary); if (fstream.is_open()) { // Write header data char majVersion[4]; memset(majVersion, 0, 4); sprintf_s(majVersion, 4, "%i", MAJOR_VERSION); char minVersion[4]; memset(minVersion, 0, 4); sprintf_s(minVersion, 4, "%i", MINOR_VERSION); char nameBuffer[8]; memset(nameBuffer, 0, 8); sprintf_s(nameBuffer, 8, "%i", NAME_BUFFER); char extBuffer[8]; memset(extBuffer, 0, 8); sprintf_s(extBuffer, 8, "%i", EXT_BUFFER); char sizeBuffer[8]; memset(sizeBuffer, 0, 8); sprintf_s(sizeBuffer, 8, "%i", SIZE_BUFFER); fstream.write(majVersion, 4); fstream.write(minVersion, 4); fstream.write(nameBuffer, 8); fstream.write(extBuffer, 8); fstream.write(sizeBuffer, 8); auto it = m_descriptors.begin(); while (it != m_descriptors.end()) { Descriptor* descriptor = *it; _UINT totalWritten = 0; fstream.write(descriptor->name, NAME_BUFFER); fstream.write(descriptor->ext, EXT_BUFFER); int oldSize = strtoul(descriptor->size, NULL, 0); dataStream ds; ds.inData = descriptor->data; ds.inLen = strtoul(descriptor->size, NULL, 0); ds.outData = NULL; ds.outLen = 0; std::cout << "\33\r[Compressing - 0%] " << descriptor->name << descriptor->ext; elzma_compress_handle handle = elzma_compress_alloc(); progressStruct pCtx; std::stringstream fName; fName << descriptor->name << descriptor->ext; pCtx.fileName = fName.str(); pCtx.totalSize = ds.inLen; elzma_compress_run(handle, inputCallback, (void *) &ds, outputCallback, (void *) &ds, elzmaProgressFunc, &pCtx); memset(descriptor->size, 0, SIZE_BUFFER); sprintf_s(descriptor->size, SIZE_BUFFER, "%i", ds.outLen); delete[] descriptor->data; descriptor->data = new char[ds.outLen]; memcpy(descriptor->data, ds.outData, ds.outLen); elzma_compress_free(&handle); fstream.write(descriptor->size, SIZE_BUFFER); _UINT fsize = strtoul(descriptor->size, NULL, 0); std::streamoff startPos = fstream.tellp(); while (totalWritten < fsize) { _UINT bytesToWrite = WRITE_STEP; if (totalWritten + bytesToWrite > fsize) bytesToWrite = fsize - totalWritten; fstream.seekp(startPos + totalWritten); fstream.write(descriptor->data, bytesToWrite); totalWritten += bytesToWrite; std::cout << "\33\r[Writing - "; std::cout << (_UINT)((float)totalWritten / (float)fsize * 100.0f) << "%] "; std::cout << descriptor->name << descriptor->ext << " - " << oldSize << " -> " << ds.outLen; } std::cout << std::endl; delete[] descriptor->data; delete descriptor; it = m_descriptors.erase(it); } fstream.close(); std::cout << std::endl; std::cout << "Packaging complete." << std::endl << std::endl; std::cout << "Data size: " << totalSize << " bytes." << std::endl; std::cout << "Header size: " << headerSize << " bytes." << std::endl; std::cout << "Total size: " << totalSize + headerSize << " bytes." << std::endl; } else { std::cout << "ERROR: Could not open file for writing:" << std::endl; std::cout << "package.bin" << std::endl; } }