Russian Qt Forum
Ноябрь 25, 2024, 01:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: qt и zlib  (Прочитано 10956 раз)
alik
Гость
« : Февраль 15, 2016, 21:49 »

Добрый вечер!

Нужно распаковать данные, находящиеся в QByteArray.
Данные были сжаты библиотекой ZLib.

Самостоятельный поиск пока ясности не дал.
Кто то пишет что нужно использовать встроенные Qcompress QUncompress, кто то пишет, что подключать ZLib библиотеку, еще QuaZip и т.д.

Подскажите плиз как полегче преодолеть проблему!
« Последнее редактирование: Февраль 15, 2016, 22:01 от alik » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Февраль 15, 2016, 21:53 »

QByteArray qUncompress(const QByteArray & data)
Записан
alik
Гость
« Ответ #2 : Февраль 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);


Выходной буфер пустой! ((
Данные нерасжимаются
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Февраль 15, 2016, 22:12 »

А как данные сжимались? Что там в исходном QByteArray?
Записан
alik
Гость
« Ответ #4 : Февраль 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 ?
Записан
alik
Гость
« Ответ #5 : Февраль 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
Записан
Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #6 : Февраль 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
LIBS  += -llibz

А динамическая библиотека (.dll) должна быть в каталоге с exe файлом.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #7 : Февраль 16, 2016, 21:09 »

Если данные сжаты zlib, а распаковать нужно qUncompress, то в заголовке нужно поменять порядок байтов, например, так:
Код:
QByteArray obj;
QByteArray pref=obj.left(4);
// сжатые данные (little-endian -> big-endian)
obj[0]=pref[3];
obj[1]=pref[2];
obj[2]=pref[1];
obj[3]=pref[0];
QByteArray deflate =  qUncompress(obj);
И наоборот, если жмете qCompress, а распаковываете с помощью zlib, то
Код:
QByteArray zip=qCompress(xml);
QByteArray pref=zip.left(4);
// big-endian -> little-endian
zip[0]=pref[3];
zip[1]=pref[2];
zip[2]=pref[1];
zip[3]=pref[0];
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
alik
Гость
« Ответ #8 : Февраль 17, 2016, 18:31 »

Если данные сжаты zlib, а распаковать нужно qUncompress, то в заголовке нужно поменять порядок байтов, например, так:
Код:
QByteArray obj;
QByteArray pref=obj.left(4);
// сжатые данные (little-endian -> big-endian)
obj[0]=pref[3];
obj[1]=pref[2];
obj[2]=pref[1];
obj[3]=pref[0];
QByteArray deflate =  qUncompress(obj);
И наоборот, если жмете qCompress, а распаковываете с помощью zlib, то
Код:
QByteArray zip=qCompress(xml);
QByteArray pref=zip.left(4);
// big-endian -> little-endian
zip[0]=pref[3];
zip[1]=pref[2];
zip[2]=pref[1];
zip[3]=pref[0];


Делаю так:


            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 - пустой
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #9 : Февраль 17, 2016, 20:18 »

А как я предлагал, не пробовали?
Давайте минимальный проект с исходным массивом.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
alik
Гость
« Ответ #10 : Февраль 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 пока не получается
Записан
Vamireh
Гость
« Ответ #11 : Февраль 18, 2016, 12:20 »

Что-то я тут запутался что надо и что не получается. Я наоборот разжимал на C# данные, сжатые qCompress'ом. Проблем не было, единственный нюанс - qCompress добавляет в начало 4 байта. Я их просто игнорировал. Наоборот, соответственно, их надо добавить. Осталось только понять, какие они должны быть.
Записан
alik
Гость
« Ответ #12 : Февраль 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 пустой
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #13 : Февраль 18, 2016, 13:42 »

Еще раз. Дайте компилябельный проект.
Сжатые данные у вас откуда берутся, из файла? Его тоже добавьте.
Что в архиве, знаете? И с чего взяли, что он сжат zlib?
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
alik
Гость
« Ответ #14 : Февраль 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();
    }
}
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 23.