Я пытаюсь использовать libpng для чтения png из ресурса Qt. Подвох: класс, выполняющий чтение, не должен не иметь каких-либо зависимостей от Qt.
На первом этапе прочитайте http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/#CustomRead Мне уже удалось написать функцию
read_png(istream& in)
Мне также удалось пройти старый добрый ifstream
ifstream in("abs_path_to_png/icon.png");
в read_png(..) и он успешно читает файл png. Но как получить (желательно независимый от платформы) istream из ресурса Qt? Производительность не является большой проблемой, поэтому я сначала придумал
bool Io_Qt::get_istringstream_from_QFile(QFile& qfile, istringstream& iss)
{
// [.. Some checking for existence and the file being open ..]
QString qs(qfile.readAll());
iss.str(qs.toStdString());
// I also tried: QByteArray arr(qfile.readAll()); iss.str(arr.data());
return qfile.isOpen();
}
// Someplace else iss and qfile are created like this:
istringstream iss(std::stringstream::in | std::stringstream::binary);
QFile qfile(":/res/icon.png");
qfile.open(QIODevice::ReadOnly);
На самом деле это приводит к тому, что на первый взгляд хорошо выглядит, если говорить
cout << "'" << iss.str().c_str() << "'" << endl;
я получил
'�PNG
'
Однако, похоже, есть проблема с пробелами. За
ifstream in("abs_path_to_png/icon.png");
char c;
cout << "'";
for (int j=0;j<8;j++)
{
in >> c;
cout << c;
}
cout << "'" << endl;
урожаи
'�PNG'
и хотя последний работает, первый вариант в конечном итоге приводит к тому, что функция проверки libpng png_sig_cmp(..) отклоняет мой png как недействительный. Мой первый рефлекс связан с «бинарным». Однако:
- istringstream iss(std::stringstream::in | std::stringstream::binary); чувствует себя хорошо.
- QIODevice::ReadOnly не имеет бинарного партнера.
Видишь, что я пропустил?