Невозможно использовать Boost GIL для определения типа файла изображения (исключение не обнаружено)

Мне нужно проверить, является ли файл JPEG или PNG, и я не могу доверять расширению файла, потому что это может быть неправильно. Для этого я решил использовать GIL.

Вот заголовочный файл, объявляющий (и определяющий) boost::gil::png_read_dimensions, В нем четко говорится, что boost::gil::png_read_dimensions «Выдает std :: ios_base :: fail, если местоположение не соответствует действительному файлу PNG». И действительно, это, кажется, соответствует уровню фактического поведения функций.

Проблема с boost::gil::jpeg_read_dimensions который вы можете увидеть Вот. В нем также четко указано, что «Выдает std :: ios_base :: fail, если местоположение не соответствует допустимому файлу JPEG». Тем не менее, это не так! Никаких исключений не выбрасывается и вместо libjpeg печатает в stdout или stderr и затем выходит из программы.

Смотрите следующий код:

#include <iostream>
#include <string>

#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/io/png_io.hpp>

using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ios_base;

namespace bg = boost::gil;

int main(int, char**) {
const string not_jpeg_or_png ("image.gif");

cout << "bg::png_read_dimensions:" << endl;
try {
bg::png_read_dimensions(not_jpeg_or_png);
} catch(const ios_base::failure &ib_f) {
cerr << "what: " << ib_f.what() << endl;
}

cout << "\nbg::jpeg_read_dimensions:" << endl;
try {
bg::jpeg_read_dimensions(not_jpeg_or_png);
} catch(const ios_base::failure &ib_f) {
cerr << "what: " << ib_f.what() << endl;
}

cout << "\nDone." << endl;

return 0;
}

Выход программы:

bg::png_read_dimensions:
what: png_check_validity: invalid png file: unspecified iostream_category error

bg::jpeg_read_dimensions:
Not a JPEG file: starts with 0x62 0x6c

Обратите внимание, как what: ... yadiyadiyada ... а также Done. не печатается

Я пытался сделать } catch(...) { вместо } catch(const ios_base::failure &ib_f) { чтобы убедиться, что ни одно исключение не проходит незамеченным, но без успеха. Не исключение будет брошено!

Я что-то упускаю здесь действительно очевидное …? Я делаю что-то неправильно? Есть ли обходной путь?

2

Решение

Я не понимаю, почему исключение как брошенное, очевидно, не может быть поймано. Это может быть ошибка.

Однако для выполнения задачи я бы предложил

  • libmagic или же
  • identify (из ImageMagick)

что делает то, что предлагает другой ответ.

Этот ответ содержит пример того, как использовать libmagic (который обычно присутствует в linux, но может быть собран и (статически) связан с любой другой платформой:

0

Другие решения

Самый простой способ — прочитать первые несколько бит файла и посмотреть, соответствуют ли они сигнатуре типа файла.

89 50 4E 47 0D 0A 1A 0A => PNG

FF D8 FF => JPEG

1

По вопросам рекламы [email protected]