13 changed files with 240 additions and 115 deletions
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#include "QGCLZMA.h" |
||||
|
||||
#include <QFile> |
||||
#include <QDir> |
||||
#include <QtDebug> |
||||
|
||||
#include "lzma.h" |
||||
|
||||
bool QGCLZMA::inflateLZMAFile(const QString& lzmaFilename, const QString& decompressedFilename) |
||||
{ |
||||
bool success = true; |
||||
const int cBuffer = 1024 * 5; |
||||
unsigned char inputBuffer[cBuffer]; |
||||
unsigned char outputBuffer[cBuffer]; |
||||
lzma_stream lzmaStrm = LZMA_STREAM_INIT; |
||||
|
||||
QFile inputFile(lzmaFilename); |
||||
if (!inputFile.open(QIODevice::ReadOnly)) { |
||||
qWarning() << "QGCLZMA::inflateLZMAFile: open input file failed" << lzmaFilename << inputFile.errorString(); |
||||
return false; |
||||
} |
||||
|
||||
QFile outputFile(decompressedFilename); |
||||
if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { |
||||
qWarning() << "QGCLZMA::inflateLZMAFile: open input file failed" << outputFile.fileName() << outputFile.errorString(); |
||||
return false; |
||||
} |
||||
|
||||
// UINT64_MAX - used as much memory as needed to decode
|
||||
int lzmaRetCode = lzma_alone_decoder(&lzmaStrm, UINT64_MAX); |
||||
if (lzmaRetCode != LZMA_OK) { |
||||
qWarning() << "QGCLZMA::inflateLZMAFile: lzma_alone_decoder failed:" << lzmaRetCode; |
||||
return false; |
||||
} |
||||
|
||||
// When LZMA_CONCATENATED flag was used when initializing the decoder,
|
||||
// we need to tell lzma_code() when there will be no more input.
|
||||
// This is done by setting action to LZMA_FINISH instead of LZMA_RUN
|
||||
// in the same way as it is done when encoding.
|
||||
//
|
||||
// When LZMA_CONCATENATED isn't used, there is no need to use
|
||||
// LZMA_FINISH to tell when all the input has been read, but it
|
||||
// is still OK to use it if you want. When LZMA_CONCATENATED isn't
|
||||
// used, the decoder will stop after the first .xz stream. In that
|
||||
// case some unused data may be left in lzmaStrm.next_in.
|
||||
lzma_action action = LZMA_RUN; |
||||
|
||||
lzmaStrm.next_in = nullptr; |
||||
lzmaStrm.avail_in = 0; |
||||
lzmaStrm.next_out = nullptr; |
||||
lzmaStrm.avail_out = cBuffer; |
||||
|
||||
do { |
||||
lzmaStrm.avail_in = static_cast<unsigned>(inputFile.read((char*)inputBuffer, cBuffer)); |
||||
if (lzmaStrm.avail_in == 0) { |
||||
break; |
||||
} |
||||
lzmaStrm.next_in = inputBuffer; |
||||
|
||||
do { |
||||
lzmaStrm.avail_out = cBuffer; |
||||
lzmaStrm.next_out = outputBuffer; |
||||
|
||||
lzmaRetCode = lzma_code(&lzmaStrm, action); |
||||
if (lzmaRetCode != LZMA_OK && lzmaRetCode != LZMA_STREAM_END) { |
||||
qWarning() << "QGCLZMA::inflateLZMAFile: inflate failed:" << lzmaRetCode; |
||||
goto Error; |
||||
} |
||||
|
||||
unsigned cBytesInflated = cBuffer - lzmaStrm.avail_out; |
||||
qint64 cBytesWritten = outputFile.write((char*)outputBuffer, static_cast<int>(cBytesInflated)); |
||||
if (cBytesWritten != cBytesInflated) { |
||||
qWarning() << "QGCLZMA::inflateLZMAFile: output file write failed:" << outputFile.fileName() << outputFile.errorString(); |
||||
goto Error; |
||||
|
||||
} |
||||
} while (lzmaStrm.avail_out == 0); |
||||
} while (lzmaRetCode != LZMA_STREAM_END); |
||||
|
||||
Out: |
||||
lzma_end(&lzmaStrm); |
||||
|
||||
return success; |
||||
|
||||
Error: |
||||
success = false; |
||||
goto Out; |
||||
} |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
/****************************************************************************
|
||||
* |
||||
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
* |
||||
* QGroundControl is licensed according to the terms in the file |
||||
* COPYING.md in the root of the source code directory. |
||||
* |
||||
****************************************************************************/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <QString> |
||||
|
||||
class QGCLZMA |
||||
{ |
||||
public: |
||||
/// Decompresses the specified file to the specified directory
|
||||
/// @param lzmaFilename Fully qualified path to lzma file
|
||||
/// @param decompressedFilename Fully qualified path to for file to decompress to
|
||||
static bool inflateLZMAFile(const QString& lzmaFilename, const QString& decompressedFilename); |
||||
}; |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue