Local .xz files: parse uncompressed size for better progress reports

This commit is contained in:
Floris Bos 2023-09-25 21:13:22 +02:00
parent 269e43ced5
commit e8931b7b8f
4 changed files with 47 additions and 1 deletions

1
debian/changelog vendored
View file

@ -9,6 +9,7 @@ rpi-imager (1.7.6) unstable; urgency=medium
* Workaround for ArchLinux's lsblk labeling internal SD card readers * Workaround for ArchLinux's lsblk labeling internal SD card readers
(mmcblk0) as non-removable storage. (mmcblk0) as non-removable storage.
* Allow drag-dropping image files to Imager. * Allow drag-dropping image files to Imager.
* Local .xz files: parse uncompressed size for better progress reports.
-- Floris Bos <bos@je-eigen-domein.nl> Sat, 23 Sep 2023 19:47:40 +0200 -- Floris Bos <bos@je-eigen-domein.nl> Sat, 23 Sep 2023 19:47:40 +0200

View file

@ -352,5 +352,5 @@ else()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo)
endif() endif()
include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR}) include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${LIBLZMA_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${QT}::Core ${QT}::Quick ${QT}::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) target_link_libraries(${PROJECT_NAME} PRIVATE ${QT}::Core ${QT}::Quick ${QT}::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS})

View file

@ -14,6 +14,7 @@
#include "wlancredentials.h" #include "wlancredentials.h"
#include <archive.h> #include <archive.h>
#include <archive_entry.h> #include <archive_entry.h>
#include <lzma.h>
#include <random> #include <random>
#include <QFileInfo> #include <QFileInfo>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
@ -242,6 +243,8 @@ void ImageWriter::startWrite()
_extrLen = _downloadLen; _extrLen = _downloadLen;
else if (lowercaseurl.endsWith(".zip")) else if (lowercaseurl.endsWith(".zip"))
_parseCompressedFile(); _parseCompressedFile();
else if (lowercaseurl.endsWith(".xz"))
_parseXZFile();
} }
if (_devLen && _extrLen > _devLen) if (_devLen && _extrLen > _devLen)
@ -648,6 +651,47 @@ void ImageWriter::_parseCompressedFile()
qDebug() << "Parsed .zip file containing" << numFiles << "files, uncompressed size:" << _extrLen; qDebug() << "Parsed .zip file containing" << numFiles << "files, uncompressed size:" << _extrLen;
} }
void ImageWriter::_parseXZFile()
{
QFile f(_src.toLocalFile());
lzma_stream_flags opts = { 0 };
_extrLen = 0;
if (f.size() > LZMA_STREAM_HEADER_SIZE && f.open(f.ReadOnly))
{
f.seek(f.size()-LZMA_STREAM_HEADER_SIZE);
QByteArray footer = f.read(LZMA_STREAM_HEADER_SIZE);
lzma_ret ret = lzma_stream_footer_decode(&opts, (const uint8_t *) footer.constData());
if (ret == LZMA_OK && opts.backward_size < 1000000 && opts.backward_size < f.size()-LZMA_STREAM_HEADER_SIZE)
{
f.seek(f.size()-LZMA_STREAM_HEADER_SIZE-opts.backward_size);
QByteArray buf = f.read(opts.backward_size+LZMA_STREAM_HEADER_SIZE);
lzma_index *idx;
uint64_t memlimit = UINT64_MAX;
size_t pos = 0;
ret = lzma_index_buffer_decode(&idx, &memlimit, NULL, (const uint8_t *) buf.constData(), &pos, buf.size());
if (ret == LZMA_OK)
{
_extrLen = lzma_index_uncompressed_size(idx);
qDebug() << "Parsed .xz file. Uncompressed size:" << _extrLen;
}
else
{
qDebug() << "Unable to parse index of .xz file";
}
lzma_index_end(idx, NULL);
}
else
{
qDebug() << "Unable to parse footer of .xz file";
}
f.close();
}
}
bool ImageWriter::isOnline() bool ImageWriter::isOnline()
{ {
return _online || !_embeddedMode; return _online || !_embeddedMode;

View file

@ -181,6 +181,7 @@ protected:
#endif #endif
void _parseCompressedFile(); void _parseCompressedFile();
void _parseXZFile();
QString _pubKeyFileName(); QString _pubKeyFileName();
QString _privKeyFileName(); QString _privKeyFileName();
QString _sshKeyDir(); QString _sshKeyDir();