С.И.Хашин
Работать можно напрямую, просто добавляя необходимый код в свой проект,
можно подключить статическую библиотеку (lib).
jpgs.h - заголовочный файл
jpgs.cpp - реализация.
jpeg\*.h, *.c - файлы библиотеки jpeglib (Tom Lane)
lzma\*.h, *.c - файлы библиотеки LzmaLib (Igor Pavlov)
Библиотека скомпилирована в шести вариантах. Это пришлось сделать потому, что нужны отдельные Debug- и Release-версии в режимах x86 и x64. Кроме того, оказалось, что Visual Studio 2010 и Visual Studio 2015 имеют разные форматы библиотек и не понимают друг друга.
Файл | Версия Visual Studio | x86/x64 | Debug/Release |
---|---|---|---|
jpgsD8610.lib | 2010 | x86 | Debug |
jpgsR8610.lib | 2010 | x86 | Release |
jpgsD86.lib | 2015 | x86 | Debug |
jpgsR86.lib | 2015 | x86 | Release |
jpgsR64.lib | 2015 | x64 | Debug |
jpgsD64.lib | 2015 | x64 | Release |
Замечание. При компиляции библиотеки можно создавать отдельный файл базы данных программы (PDB),
но есть возможность просто включить всё необходимое в lib-файл. Он получится больше по размеру,
но при этом не надо заботиться о расположении pdb-файла.
Эта возможность включается в
Project → Properties → C/C++ → General → Debug Information Format → C7 Compatible.
Для включения библиотеки в свой проект вначале подключается заголовочный файл библиотеки:
#include "..\\lib\\jpgs.h" // работа с jpeg
Затем сообщаем линковщику, где найти саму библиотетку (lib-файл).
Учитывая большое количество версий, это не так просто:
#ifdef _WIN64 #ifdef _DEBUG #pragma comment(lib, "../lib/jpgsD64.lib") #else #pragma comment(lib, "../lib/jpgsR64.lib") #endif #else #if _MSC_VER ==1600 // Visual C++ 2010 #ifdef _DEBUG #pragma comment(lib, "../lib/jpgsD8610.lib") #else #pragma comment(lib, "../lib/jpgsR8610.lib") #endif #else // Visual C++ 2015 #ifdef _DEBUG #pragma comment(lib, "../lib/jpgsD86.lib") #else #pragma comment(lib, "../lib/jpgsR86.lib") #endif #endif // #if _MSC_VER ==1600 // Visual C++ 2010 #endif
Структура каталогов при этом предполагается такая:
Parent\util \*.h,*.cpp - здесь размещаются все описанные модули └───\lib \*.lib - здесь должны лежать все *.lib -файлы
Для работы с jpeg-файлами используется библиотека LibJpeg Тома Лейна (Tom Lane).
// сохранить/прочитать изображение в/из формате jpg int jpegs_save( BYTE * buf, int mx, int my, const char *filename, int level ); int jpegs_load( BYTE *&buf, int &mx, int &my, const char *filename );
Параметр качества (level) сжатия - целое число лежащее в
пределах от 1 до 100. Число 100 соответствует максимальному качеству, 1 - наименьшему.
Качество 0.60 соответствует стандарту качества ключевых кадров "DVD-видео".
В целом изображение очень хорошее, но при внимательном взгляде можно заметить погрешности.
Качество 0.80 вполне достаточно почти всегда. Погрешности можно заметить
лишь около резких перепадов цветов и при очень внимательном взгляде.
Если вы собираететь в дальнейшем обрабатывать изображения, есть смысл взять большее качество.
Функции служат для записи RGB-буфера в jpeg-файл и для чтения.
Библиотека скомпилирована в шести вариантах. Это пришлось сделать потому, что нужны отдельные Debug- и Release-версии в режимах x86 и x64. Кроме того, оказалось, что Visual Studio 2010 и Visual Studio 2015 имеют разные форматы библиотек и не понимают друг друга.
Файл | Версия Visual Studio | x86/x64 | Debug/Release |
---|---|---|---|
lzmaD8610.lib | 2010 | x86 | Debug |
lzmaR8610.lib | 2010 | x86 | Release |
lzmaD86.lib | 2015 | x86 | Debug |
lzmaR86.lib | 2015 | x86 | Release |
lzmaR64.lib | 2015 | x64 | Debug |
lzmaD64.lib | 2015 | x64 | Release |
Замечание. При компиляции библиотеки можно создавать отдельный файл базы данных программы (PDB),
но есть возможность просто включить всё необходимое в lib-файл. Он получится больше по размеру,
но при этом не надо заботиться о расположении pdb-файла.
Эта возможность включается в
Project → Properties → C/C++ → General → Debug Information Format → C7 Compatible.
Для включения библиотеки в свой проект вначале подключается заголовочный файл библиотеки:
#include "..\\lib\\lzmas.h" // работа с lzma
Затем сообщаем линковщику, где найти саму библиотетку (lib-файл).
Учитывая большое количество версий, это не так просто:
#ifdef _WIN64 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD64.lib") #else #pragma comment(lib, "../lib/lzmaR64.lib") #endif #else #if _MSC_VER ==1600 // Visual C++ 2010 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD8610.lib") #else #pragma comment(lib, "../lib/lzmaR8610.lib") #endif #else // Visual C++ 2015 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD86.lib") #else #pragma comment(lib, "../lib/lzmaR86.lib") #endif #endif // #if _MSC_VER ==1600 // Visual C++ 2010 #endif
Структура каталогов при этом предполагается такая:
Parent\util \*.h,*.cpp - здесь размещаются все описанные модули └───\lib \*.lib - здесь должны лежать все *.lib -файлы
В библиотеку включены всего две функци:
// buf(size) сжать в lzma-буфер z_buf длины z_len int lzma_code(BYTE * buf, int size, BYTE *&z_buf, int &z_len); // buf(size) распаковать из lzma-буфера z_buf длины z_len int lzma_decode(BYTE *&buf, int &size, BYTE * z_buf, int z_len);
Приведем небольшой пример программы.
В начале файла подключение библиотеки:
#include "..\\lib\\lzmas.h"// функции библиотеки #ifdef _WIN64 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD64.lib") #else #pragma comment(lib, "../lib/lzmaR64.lib") #endif #else #if _MSC_VER ==1600 // Visual C++ 2010 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD8610.lib") #else #pragma comment(lib, "../lib/lzmaR8610.lib") #endif #else // Visual C++ 2015 #ifdef _DEBUG #pragma comment(lib, "../lib/lzmaD86.lib") #else #pragma comment(lib, "../lib/lzmaR86.lib") #endif #endif // #if _MSC_VER ==1600 // Visual C++ 2010 #endif //----------------------
При таком подключении в свойствах проекта указывать библиотеку не требуется.
А теперь пример работы с библиотекой:
const int N = 1000000; BYTE *b = new BYTE[N], *z_buf, *b2; int z_len, code, N2; for (int i = 0; i < N; i++) b[i] = 3 + i + i*i; printf("%3d %3d %3d %3d %3d %3d \n", b[0], b[1], b[N / 2], b[2 * N / 3], b[N - 2], b[N - 1]); code = h_graph_code_lzma(b, N, z_buf, z_len); // сжимаем b в буфер z_buf printf("z_len = %d\n", z_len); code = h_graph_deco_lzma(b2, N2, z_buf, z_len); // распаковываем z_buf в b2 printf("%3d %3d %3d %3d %3d %3d \n", b2[0], b2[1], b2[N / 2], b2[2 * N / 3], b2[N - 2], b2[N - 1]); delete[]b2; delete[]z_buf; delete[]b;
И результат работы:
3 5 35 17 69 195 z_len = 489 3 5 35 17 69 195
Библиотека jpgs ничего не знает про матрицы.
Модуль imatr_jpg дает интерфейс библиотеки с классами матриц:
imatr_jpg.h - заголовочный файл
imatr_jpg.cpp - реализация.
Чтение jpeg-файлов в матрицу:
int loadGrey(matr &a, const char *fname); int loadRGB(matr &a, const char *fname); // упакован RGB цвет в один элемент матрицы int loadRGB(matr3 &a, const char *fname); // прочитать в 3-матрицу
int saveGrey(matr &a, const char *fname, int q); // сохранить с качеством q, 0 <=q <=100 int saveRGB(matr &a, const char *fname, int q); // сохранить из упакованной матрицы int saveRGB(matr3 &a, const char *fname, int q); // сохранить 3-матрицу
Замечание.Во всех указанных выше фунциях можно в имени файла задать файл с расширением bmp. При этом при сохранении файла параметр q (качество) игнорируется.