Упаковка и распаковка данных с помощью библиотеки zlib
Упаковка и распаковка данных с помощью библиотеки zlib
Продолжаем тему упаковки и распаковки. Сегодня в качестве инструмента будет известная библиотека zlib от Jean-loup Gailly и Mark Adler, признанных профессионалов в области компрессии данных. Ну а что, по системным функциям прошлись, почему бы не пройтись по сторонним библиотекам. Тем более, что zlib используется во многих программных продуктах, и, если вдруг возникнет необходимость поковыряться в их базах, то будет уже практически готовое решение.
Скомпилированных библиотек zlib последней версии для Windows почему-то не нашлось ни на офсайте, ни в репозитории, так что пришлось заниматься сборкой исходников самостоятельно. Хорошо хоть, что авторы приложили проект для студии, уже проще. Готовую zlibwapi.dll можно взять в архиве из этой статьи.
По степени компрессии на небольших объемах данных zlib заметно уступает лидерам типа aPLib или BitBuster. На больших объемах ситуация выравнивается, разница в сжатии практически незаметна, но при этом сохраняется просто космическая скорость обработки данных в обе стороны.
Переходим к программированию. Для доступа к компрессии и декомпрессии достаточно добавить zlibwapi.dll в дистрибутив с вашим приложением и прописать в таблице импорта нужные функции. В документации сказано об основных функциях (де)компресии, а также о работе со сжатыми файлами. Разберем на примерах оба варианта, начнем с работы с данными в памяти.
Code (Assembler) : Убрать нумерацию
- ; Определить максимальный размер памяти
- ; для размещения упакованных данных
- mov [original_size],??? ; размер оригинальных данных
- invoke compressBound,[original_size]
- mov [compressed_size],eax
- ; Зарезервировать память
- invoke GlobalAlloc,GMEM_MOVEABLE,[compressed_size]
- mov [hMem],eax
- invoke GlobalLock,eax
- mov [dMem],eax
- ; Сжать данные с максимальной компрессией
- Z_BEST_COMPRESSION = 9
- invoke compress2,[dMem],compressed_size,original_data,\
- [original_size],Z_BEST_COMPRESSION
Code (Assembler) : Убрать нумерацию
- ; Зарезервировать память
- mov [original_size],??? ; размер оригинальных данных
- invoke GlobalAlloc,GMEM_MOVEABLE,[original_size]
- mov [hMem],eax
- invoke GlobalLock,eax
- mov [dMem],eax
- ; Распаковать данные
- mov [compressed_size],??? ; размер упакованных данных
- invoke uncompress,[dMem],original_size,\
- compressed_data,[compressed_size]
Code (Assembler) : Убрать нумерацию
- ; Зарезервировать память
- mov [original_size],??? ; размер оригинальных данных
- invoke GlobalAlloc,GMEM_MOVEABLE,[original_size]
- mov [hMem],eax
- invoke GlobalLock,eax
- mov [dMem],eax
- ; Распаковать данные
- mov [compressed_size],??? ; размер упакованных данных
- invoke uncompress2,[dMem],original_size,\
- compressed_data,compressed_size
Очень большое преимущество библиотеки zlib - работа напрямую с файлами, если упакованные данные должны храниться там целиком. Вам не надо самостоятельно резервировать память для загрузки содержимого файла, не надо заботиться о чтении или записи данных, всю грязную работу библиотека возьмет на себя. Функций для работы с файлами много, но для большинства ситуаций хватит четырех: gzopen, gzread / gzwrite и gzclose.
Code (Assembler) : Убрать нумерацию
- fname db 'packed.gz',0
- fmode db 'rb',0
- ...
- ...
- ; Открыть файл с упакованными данными
- invoke gzopen,fname,fmode
- mov ebx,eax
- ; Прочитать и распаковать данные
- invoke gzread,ebx,original_data,[original_size]
- ; Закрыть файл
- invoke gzclose,ebx
Code (Assembler) : Убрать нумерацию
- fname db 'packed.gz',0
- fmode db 'wb',0
- ...
- ...
- ; Создать файл-приемник упакованных данных
- invoke gzopen,fname,fmode
- mov ebx,eax
- ; Записать упакованные данные
- invoke gzwrite,ebx,original_data,[original_size]
- ; Закрыть файл
- invoke gzclose,ebx
Никаких проверок на ошибки в приведенных примерах не выполняется, оставлен только минимально необходимый код. В реальных проектах, естественно, вы должны быть готовы к любой нештатной ситуации. Функции zlib достаточно надежны в плане возможностей и информативны в плане реакции на ошибки, вам надо будет только правильно обрабатывать их статусы.
В приложении примеры программ с исходными текстами, одна из которых извлекает из памяти иконку, упакованную по алгоритму compress библиотеки zlib, и выводит ее на форму. Вторая программа загружает иконку из файла, упакованного по алгоритму gzip. Также в архиве примеры простеньких упаковщиков на основе zlib, работающих из командной строки.
Просмотров: 2160 | Комментариев: 4
Метки: Assembler, распаковка
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(13.12.2021 в 20:11):
Слова "ПОСЛЕДНЕЙ ВЕРСИИ" не считаются? По этим ссылкам выложены какие-то допотопные версии, одна другой древнее.
Petya
(13.12.2021 в 20:07):
Пара ссылок внизу главной офсайта не считаются?
ManHunter
(10.12.2021 в 15:44):
Не хлебом единым. В первую очередь я кодер, а кушать уже потом.
Гость
(10.12.2021 в 15:42):
надо побольше кулинарных рецептов, хороших и разных!
Добавить комментарий
Заполните форму для добавления комментария