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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как избежать краша в libjpeg при открытии некорректного файла?  (Прочитано 4488 раз)
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« : Декабрь 25, 2012, 13:49 »

Вот код:

Код
C++ (Qt)
static void error_exit (j_common_ptr cinfo)
{
Q_UNUSED (cinfo)
qDebug() << Q_FUNC_INFO;
}
 
static void output_message (j_common_ptr cinfo)
{
Q_UNUSED (cinfo)
qDebug() << Q_FUNC_INFO;
}
 
static void emit_message (j_common_ptr cinfo, int msg_level)
{
Q_UNUSED (cinfo)
Q_UNUSED (msg_level)
qDebug() << Q_FUNC_INFO;
}
 
static void format_message (j_common_ptr cinfo, char *buffer)
{
Q_UNUSED (cinfo)
Q_UNUSED (buffer)
qDebug() << Q_FUNC_INFO;
}
 
static void reset_error_mgr (j_common_ptr cinfo)
{
qDebug() << Q_FUNC_INFO;
cinfo->err->num_warnings = 0;
cinfo->err->msg_code = 0;
}
 

Код
C++ (Qt)
bool JpegFormat::load (const QByteArray &data, const QSize &size)
{
Q_UNUSED (size)
qDebug() << Q_FUNC_INFO;
 
jpeg_decompress_struct decompressStruct;
jpeg_error_mgr error;
 
decompressStruct.err = jpeg_std_error (&error);
jpeg_CreateDecompress (&decompressStruct,
       JPEG_LIB_VERSION,
sizeof (decompressStruct));
error.error_exit = error_exit;
error.emit_message = emit_message;
error.output_message = output_message;
error.format_message = format_message;
error.reset_error_mgr = reset_error_mgr;
 
auto inBuf = reinterpret_cast<const unsigned char *> (data.constData());
jpeg_mem_src (&decompressStruct,
const_cast<unsigned char *> (inBuf),
data.size());
 
if (jpeg_read_header (&decompressStruct, true) != JPEG_HEADER_OK) {
jpeg_destroy_decompress (&decompressStruct);
return false;
}
 
decompressStruct.out_color_space = JCS_GRAYSCALE;
jpeg_start_decompress (&decompressStruct);
 
size_ = QSize (decompressStruct.image_width, decompressStruct.image_height);
data_.fill (0,
decompressStruct.image_width * decompressStruct.image_height
  );
auto outBuf = reinterpret_cast<unsigned char *> (data_.data());
 
while (decompressStruct.output_scanline < decompressStruct.image_height) {
jpeg_read_scanlines (&decompressStruct, &outBuf, 1);
outBuf += decompressStruct.image_width;
}
 
jpeg_finish_decompress (&decompressStruct);
jpeg_destroy_decompress (&decompressStruct);
 
return true;
}
 

В jpeg_start_decompress происходит падение, как этого избежать? Файл во вложении.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #1 : Декабрь 25, 2012, 14:24 »

честно скажу что с libjpeg ни разу не работал, но вот в голову такая мысль пришла, а что если проверять файл на наличие

0xFFD8 и 0xFFD9 - стало быть начало и конец jpg файла ? Хотя может есть более верное решение  В замешательстве
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #2 : Декабрь 25, 2012, 14:27 »

jpeg_read_header нормально отрабатывает, значит, хидер корректен, по идее.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #3 : Декабрь 25, 2012, 14:44 »

А как падения избежать-то хочется? Что бы написало "вы подсунули плохой JPEG" и продолжало ждать нормального JPEG или всё же пыталось бы распаковать хоть что-то из битого JPEG?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #4 : Декабрь 25, 2012, 14:46 »

Первый вариант. То есть, просто должно сказать, что файл не корректен.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #5 : Декабрь 25, 2012, 16:00 »

Тогда, видимо, надо почитать документацию на libjpeg в разделе Error handling.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #6 : Декабрь 26, 2012, 10:58 »

Решение подсказано на linux.org.ru
Код
C++ (Qt)
struct JpegError : public jpeg_error_mgr {
jmp_buf jmpBuffer;
};
 
static void error_exit (j_common_ptr cinfo)
{
JpegError *error = static_cast<JpegError *> (cinfo->err);
longjmp (error->jmpBuffer, 1);
}
//-------------------------------
bool JpegFormat::load (const QByteArray &data, const QSize &size)
{
Q_UNUSED (size)
 
jpeg_decompress_struct decompressStruct;
JpegError error;
 
decompressStruct.err = jpeg_std_error (&error);
 
error.error_exit = error_exit;
 
#if 0
error.emit_message = emit_message;
error.output_message = output_message;
error.format_message = format_message;
error.reset_error_mgr = reset_error_mgr;
#endif //0
 
if (!setjmp (error.jmpBuffer)) {
jpeg_CreateDecompress (&decompressStruct,
  JPEG_LIB_VERSION,
  sizeof (decompressStruct)
 );
 
auto inBuf = reinterpret_cast<const unsigned char *> (data.constData());
jpeg_mem_src (&decompressStruct,
 const_cast<unsigned char *> (inBuf),
 data.size());
 
if (jpeg_read_header (&decompressStruct, true) != JPEG_HEADER_OK) {
jpeg_destroy_decompress (&decompressStruct);
return false;
}
 
decompressStruct.out_color_space = JCS_GRAYSCALE;
jpeg_start_decompress (&decompressStruct);
 
size_ = QSize (decompressStruct.image_width, decompressStruct.image_height);
data_.fill (0,
decompressStruct.image_width * decompressStruct.image_height
  );
auto outBuf = reinterpret_cast<unsigned char *> (data_.data());
 
while (decompressStruct.output_scanline < decompressStruct.image_height) {
jpeg_read_scanlines (&decompressStruct, &outBuf, 1);
outBuf += decompressStruct.image_width;
}
 
jpeg_finish_decompress (&decompressStruct);
jpeg_destroy_decompress (&decompressStruct);
}
 
 
return !data_.isEmpty ();
}
 
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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