I've been trying to write my own InputStream and testing trying to load png files. I eventually wrote a 'reference stream' which just loads the file as is to make sure it was working, and I discovered it seems loading anything except a png works fine, but I get an invalid header error if I load a png with it. Loading the png file with LoadFromFile works fine but I can't use that as I need a custom stream.
Here is my reference stream that works on everything (Fonts, .tgas, etc.) but not pngs:
#pragma once
#include <SFML/Graphics.hpp>
class ReferenceStream : public InputStream {
public:
ReferenceStream(string filename);
~ReferenceStream();
virtual Int64 Read(char* data, Int64 size);
virtual Int64 Seek(Int64 position);
virtual Int64 Tell();
virtual Int64 GetSize();
private:
Int64 position;
char* buffer;
Int64 bufferLen;
};
#include "ReferenceStream.h"
#include <fstream>
ReferenceStream::ReferenceStream(string filename) : position(0), buffer(nullptr), bufferLen(-1) {
ifstream file(filename, ios::binary | ios::in);
// [snipped] App-specific error handling
file.seekg(0, ios::end);
bufferLen = (Int64)file.tellg();
file.seekg(0, ios::beg);
buffer = new char[(int)bufferLen];
memset(buffer, 0, sizeof(buffer));
file.read(buffer, bufferLen);
file.close();
}
Int64 ReferenceStream::Read(char* data, Int64 size) {
if (position + size > bufferLen) {
size = bufferLen - position;
}
for (Int64 i = position; i < (position + size); i++) {
data[i-position] = buffer[i];
}
return size;
}
Int64 ReferenceStream::Seek(Int64 position) {
this->position = position;
if (position >= bufferLen) {
this->position = bufferLen - 1;
}
return this->position;
}
Int64 ReferenceStream::Tell() {
return position;
}
Int64 ReferenceStream::GetSize() {
return bufferLen;
}
ReferenceStream::~ReferenceStream() {
delete[] buffer;
}
If I save the output of reading my full stream manually to a file it creates a valid png file, so a bug in SFML or stbimage is the only thing I can come up with...