Skip to main content
GameDev.net gamedev.net
🔒 Locked

PNG and ifstream

Started by tKircher Sep 2, 2009 at 8:21 PM 5 replies 3.1k views
Original Post
tKircher
tKircher
While trying to load flat bytes (unsigned char) from a PNG file, I realized i was using the clunky old fread() and FILE* combination, which seemed sort of inelegant compared to the more C++ ifstreams. So, in trying to convert to it, i realized that i'd never read flat bytes using that method, and that, (surprise surprise) there's no method to do it. I tried using reinterpret_cast, but it just errored out during the read. I tried a quick hack to this effect..
//unsigned char inValue
//ifstream* in

in->read((char*)&inValue);
Thinking myself clever, it ran and didn't crash. Oh, but the best part, it gave incorrect results. For whatever reason, it doesn't give me the same bit pattern as fread() did, and also doesn't line up to what PNG specification says should be the initial bytes. Is there any way to read flat bytes without writing a novella of workaround code, or should I just go back to fread() and deal with it?
shadowcomplex
shadowcomplex
Why not read the entire file into a buffer, and then parse the buffer however you want?

 //Open file blah blah ... //Move to end of file  //to retrieve size filein.seekg (0, ios::end); length = filein.tellg(); //reset location filein.seekg (0, ios::beg); buffer = new char [length]; //read in file filein.read (buffer,length);  //Close/free stream blah blah blah ... //Do buffer parsing if( buffer[0] == 0 )   //blah blah blah //All finished? Great! delete[] buffer;
Buckeye
Buckeye
Maybe I'm missing your real question. But, how about:
ifstream f;unsigned char b;f.open("your file", ios_base::in | ios_base::binary);f >> b;f.close();

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
the_edd
the_edd
Quote:
Original post by tKircher
Is there any way to read flat bytes without writing a novella of workaround code, or should I just go back to fread() and deal with it?


Using at std::ifstream and its read() method is correct. Make sure to open the stream with the ios::binary flag. A reinterpret_cast may indeed be needed if reading in to an array of unsigned char.

If you can't get it to work, post the problematic code.

If you want the decompressed raster, you might be interested in this library.
Bregma
Bregma
Might I suggest using std::vector as your buffer and a std::istreambuf_iterator to move the bytes between the persistent store and your buffer.
#include <cerrno>#include <cstring>#include <fstream>#include <iostream>#include <iterator>#include <string>#include <vector>const std::string filename("somefile.png");int main(){  using namespace std;  ifstream istr(filename.c_str());  if (!istr)  {    cerr << "error " << errno << " opening " << filename << ": "         << strerror(errno)) << "\n";    return 1;  }  vector<char> buffer(istreambuf_iterator<char>(istr),                      istreambuf_iterator<char>());  cout << "file size is " << buffer.size() << "\n";  // interpret bytes of PNG file here ....}
Stephen M. Webb
Professional Free Software Developer
Krohm
Krohm
What's the deal against fread and friends really? They have been delivering since essentially the beginning. Are you really asking this just for checking the initial png signature?
Previously "Krohm"
Zahlman
Zahlman
Quote:
Original post by tKircher
So, in trying to convert to it, i realized that i'd never read flat bytes using that method, and that, (surprise surprise) there's no method to do it.


What? Sure there is. You're even attempting to use it in your "quick hack": the .read() member function. (Except that it is supposed to take 2 arguments, the second one being a length.

Unless by "flat" you mean something beyond my comprehension....

Quote:
I tried using reinterpret_cast, but it just errored out during the read.


What did you cast, and how did it "error out"?

Quote:
I tried a quick hack to this effect..


*** Source Snippet Removed ***


Thinking myself clever, it ran and didn't crash. Oh, but the best part, it gave incorrect results.


Well, of course 'inValue' only holds one byte :)

Quote:
For whatever reason, it doesn't give me the same bit pattern as fread() did, and also doesn't line up to what PNG specification says should be the initial bytes.


Did you verify the file contents with a hex editor?
Did you remember to open the stream in binary mode by passing std::ios::binary to its constructor?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.