Мне нужно проверить, является ли файл 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) {
чтобы убедиться, что ни одно исключение не проходит незамеченным, но без успеха. Не исключение будет брошено!
Я что-то упускаю здесь действительно очевидное …? Я делаю что-то неправильно? Есть ли обходной путь?
Я не понимаю, почему исключение как брошенное, очевидно, не может быть поймано. Это может быть ошибка.
Однако для выполнения задачи я бы предложил
libmagic
или же identify
(из ImageMagick)что делает то, что предлагает другой ответ.
Этот ответ содержит пример того, как использовать libmagic (который обычно присутствует в linux, но может быть собран и (статически) связан с любой другой платформой:
Самый простой способ — прочитать первые несколько бит файла и посмотреть, соответствуют ли они сигнатуре типа файла.
89 50 4E 47 0D 0A 1A 0A => PNG
FF D8 FF => JPEG