Название: qt и zlib Отправлено: alik от Февраль 15, 2016, 21:49 Добрый вечер!
Нужно распаковать данные, находящиеся в QByteArray. Данные были сжаты библиотекой ZLib. Самостоятельный поиск пока ясности не дал. Кто то пишет что нужно использовать встроенные Qcompress QUncompress, кто то пишет, что подключать ZLib библиотеку, еще QuaZip и т.д. Подскажите плиз как полегче преодолеть проблему! Название: Re: qt и zlib Отправлено: Old от Февраль 15, 2016, 21:53 QByteArray qUncompress(const QByteArray & data)
Название: Re: qt и zlib Отправлено: alik от Февраль 15, 2016, 22:02 QByteArray qUncompress(const QByteArray & data) Делаю так (нашел где то на форумах): QByteArray aInCompBytes = buffer; QByteArray aInUnCompBytes; QByteArray aInCompBytesPlusLen; int currentCompressedLen = CompressedDataLen; int currentUnCompressedLen = RawDataLen; aInCompBytes.resize(currentCompressedLen); aInCompBytesPlusLen = aInCompBytes; aInCompBytesPlusLen.prepend(QByteArray::number(currentUnCompressedLen)); aInUnCompBytes.resize(currentUnCompressedLen); aInUnCompBytes = qUncompress(aInCompBytesPlusLen); Выходной буфер пустой! (( Данные нерасжимаются Название: Re: qt и zlib Отправлено: Old от Февраль 15, 2016, 22:12 А как данные сжимались? Что там в исходном QByteArray?
Название: Re: qt и zlib Отправлено: alik от Февраль 15, 2016, 22:16 а кто нибудь вообще имел дело с zlib сжатием в QT.
В Дельфи я подключал библиотеку ZLib и работал с данными. Здесь я пока плохо ориентируюсь. Может кто подскажет как подключить библиотеку. В pro файле я записал: INCLUDEPATH += ./Packing/zlib LIBS += ./Packing/zlib -llibz Бибиотека zlib лежит у меня в подкаталоге Packing/zlib директории где сидит сам pro файл. Правильно это или надо забросить эту библиотеку в директории, где записываются компилированные файлы, типа D:\Projects\QT\build-myprog-Desktop_Qt_5_2_0_MinGW_32bit-Debug ? Название: Re: qt и zlib Отправлено: alik от Февраль 15, 2016, 22:23 А как данные сжимались? Что там в исходном QByteArray? Данные сжимались библиотекой ZLib в Delphi. В начале пакета буфера находится: "xÚì]\007wÛ:³ä9è\235\000\010\026\211¤º-w;É\227ûþÿ/{K¹ÆQ®Kl_¹À9:²£Ðärvvf\0010(\033\006Á\204r\215²\007\006Í\004#Ìå\g6jÎ\030e\031\t£²Z\036\237\234\255K\233eV;\025Ý\003\207ÁÙk\014B)Æ\230R.\005\227Êh!ùëü¢Ç\016Æ9åÞ\n$¥¤\224\021\201Åòl±Ü[̦ó\gÿñ Y\2062*¸à\214SL9%/zxôÄÏcÊ\224òR;¢2Ê\030Ó¢;ýþm=/c\014^*¡(Êvbà\227ÇïÓ®\214\010N\030gT²\034YÅ\004çÎõGÿü\w¥µ1Ä"¤rlv!N¯qÇ®\216É\036\0278Ä%|\210[Ëõ@\nÚú¶\235\034üøùmµ\030§d\213º\032\215'á?\217\025z\235X]\037}\003YüXti[b*\202ð\223¾\237ìÿ¼8_Ïæ}_\230¼(F^g\037t »È¥\217ME¬½\024~½Wï\2..." Название: Re: qt и zlib Отправлено: Swa от Февраль 16, 2016, 12:57 В pro файле я записал: INCLUDEPATH += ./Packing/zlib LIBS += ./Packing/zlib -llibz Бибиотека zlib лежит у меня в подкаталоге Packing/zlib директории где сидит сам pro файл. Правильно это или надо забросить эту библиотеку в директории, где записываются компилированные файлы, типа D:\Projects\QT\build-myprog-Desktop_Qt_5_2_0_MinGW_32bit-Debug ? Попробуй так: Код: LIBS += -L$${_PRO_FILE_PWD_}/Packing/zlib А динамическая библиотека (.dll) должна быть в каталоге с exe файлом. Название: Re: qt и zlib Отправлено: sergek от Февраль 16, 2016, 21:09 Если данные сжаты zlib, а распаковать нужно qUncompress, то в заголовке нужно поменять порядок байтов, например, так:
Код: QByteArray obj; Код: QByteArray zip=qCompress(xml); Название: Re: qt и zlib Отправлено: alik от Февраль 17, 2016, 18:31 Если данные сжаты zlib, а распаковать нужно qUncompress, то в заголовке нужно поменять порядок байтов, например, так: Код: QByteArray obj; Код: QByteArray zip=qCompress(xml); Делаю так: buffer.resize(CompressedDataLen); in.readRawData(buffer.data(), buffer.size()); // считывание данных, сжатых библиотекой ZLib //---Расжатие данных--------------------------------------------------- try { char pref[4]; memcpy(&pref, &RawDataLen, 4); // в pref записываю побайтно длину несжатых данных buffer.remove(0,4); // удаляю заголовок из данных сжатых библотекой ZLib buffer.insert(0, pref[3]); // вставляю длину несжатых данных buffer.insert(0, pref[2]); buffer.insert(0, pref[1]); buffer.insert(0, pref[0]); QByteArray RawData; RawData = qUncompress(buffer); // пытаюсь расжать данные Результат RawData - пустой Название: Re: qt и zlib Отправлено: sergek от Февраль 17, 2016, 20:18 А как я предлагал, не пробовали?
Давайте минимальный проект с исходным массивом. Название: Re: qt и zlib Отправлено: alik от Февраль 18, 2016, 12:01 А как я предлагал, не пробовали? Давайте минимальный проект с исходным массивом. RawDataLen = 50 quint8 RawData[RawDataLen] = (0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5) после сжатия массива RawData, получается следующий массив CompressedDataLen = 24 quint8 CompressedData[CompressedDataLen] = (120, 218, 99, 96, 0, 1, 70, 24, 96, 66, 0, 102, 24, 96, 65, 0, 86, 32, 0, 0, 8, 52, 0, 123) Первые 4 элемента (120, 218, 99, 96) похожи на стандартный заголовок Вообщем распаковать даже такой простой массив CompressedData с помощью QUncompress пока не получается Название: Re: qt и zlib Отправлено: Vamireh от Февраль 18, 2016, 12:20 Что-то я тут запутался что надо и что не получается. Я наоборот разжимал на C# данные, сжатые qCompress'ом. Проблем не было, единственный нюанс - qCompress добавляет в начало 4 байта. Я их просто игнорировал. Наоборот, соответственно, их надо добавить. Осталось только понять, какие они должны быть.
Название: Re: qt и zlib Отправлено: alik от Февраль 18, 2016, 12:47 RawDataLen = 50; // длина первичных данных
CompressedDataLen = 24; // длина данных сжатых библиотекой Zlib unsigned char buf[24] = {120, 218, 99, 96, 0, 1, 70, 24, 96, 66, 0, 102, 24, 96, 65, 0, 86, 32, 0, 0, 8, 52, 0, 123}; // Данные сжатые библиотекой Zlib QByteArray CompressedData; CompressedData = QByteArray::fromRawData(reinterpret_cast<char*>(buf), 24); CompressedData.remove(0,4); char tmp[4]; memcpy(&tmp, &RawDataLen, 4); CompressedData.insert(0, tmp[0]); CompressedData.insert(0, tmp[1]); CompressedData.insert(0, tmp[2]); CompressedData.insert(0, tmp[3]); RawData = qUncompress(CompressedData); Результат тот же - RawData пустой Название: Re: qt и zlib Отправлено: sergek от Февраль 18, 2016, 13:42 Еще раз. Дайте компилябельный проект.
Сжатые данные у вас откуда берутся, из файла? Его тоже добавьте. Что в архиве, знаете? И с чего взяли, что он сжат zlib? Название: Re: qt и zlib Отправлено: alik от Февраль 18, 2016, 14:29 Вот файл zlib_file.dat, сжатый стандартной библиотекой Zlib из дельфи
и сам проект. Путь к zlib_file.dat переукажите по факту. Вот на всякий случай единственная функция проекта: bool read_zlib(QString FileName) { QFile file(FileName); if (!file.open(QIODevice::ReadOnly)) return false; QDataStream in(&file); int CompressedDataLen = file.size(); // = 24 try { QByteArray CompressedData; CompressedData.resize(CompressedDataLen); in.readRawData(CompressedData.data(), CompressedData.size()); //unsigned char buf[24] = {120, 218, 99, 96, 0, 1, 70, 24, 96, 66, 0, 102, 24, 96, 65, 0, 86, 32, 0, 0, 8, 52, 0, 123}; //CompressedData = QByteArray::fromRawData(reinterpret_cast<char*>(buf), 24); //---Расжатие данных--------------------------------------------------- int RawDataLen = 50; CompressedData.remove(0,4); char tmp[4]; memcpy(&tmp, &RawDataLen, 4); CompressedData.insert(0, tmp[3]); CompressedData.insert(0, tmp[2]); CompressedData.insert(0, tmp[1]); CompressedData.insert(0, tmp[0]); QByteArray RawData; RawData = qUncompress(CompressedData); CompressedData.clear(); RawData.clear(); return true; } catch (std::exception & e) { goto finally; } finally: { in.~QDataStream(); file.close(); } } Название: Re: qt и zlib Отправлено: alik от Февраль 18, 2016, 16:52 Ребята, а как вызвать правильно функцию -
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); из встроенной библиотеки #include <QtZlib/zlib.h> ? У меня есть буферы QByteArray, как мне перейти к ByteF ? Можно писать что то типа ? QByteArray Dest, Src; uncompress(ByteF (Dest), CompressedDataLen, ByteF (Src), RawDataLen); Название: Re: qt и zlib Отправлено: alik от Февраль 18, 2016, 20:24 Все победил проблему, очень просто:
#include <QtZlib/zlib.h> unsigned char *compressBuf = new unsigned char[CompressedDataLen]; memcpy(compressBuf, buffer, CompressedDataLen); unsigned char *uncompressBuf = new unsigned char[RawDataLen]; unsigned long int compressBufLength = CompressedDataLen; unsigned long int uncompressLength = RawDataLen; int uncompressValue = uncompress(uncompressBuf, &uncompressLength, compressBuf, compressBufLength); Результирующий буфер лежит в uncompressBuf ! Название: Re: qt и zlib Отправлено: sergek от Февраль 18, 2016, 21:27 Цитировать Note: If you want to use this function to uncompress external data that was compressed using zlib, you first need to prepend a four byte header to the byte array containing the data. The header must contain the expected length (in bytes) of the uncompressed data, expressed as an unsigned, big-endian, 32-bit integer. Код: QFile file("./zlib_file.dat"); |