How to read PNG images without a library?

Started by
26 comments, last by FLeBlanc 11 years, 7 months ago

[quote name='Nyxenon' timestamp='1333387330' post='4927562']
I am writing an engine. It's not so hard, most of it is pretty easy for me
I still don't understand why cannot you just focus on another problem.
[/quote]

Well, it's mostly because I want to get to work on the renderer, and I want to use a texture for testing. I COULD just save a texture to the raw format, and load it that way, but eventually I'd need to load PNGs. I've decided to just use XNA to write a test renderer to see how well it performs so I can optimize it, then I'll write it in C++.
Advertisement
Wait, you're going to write a test renderer in XNA, optimize it, then write it in C++? For the love of all that's holy, why? Why bother with the "write it in C++" step at all, and undo all that effort you just spent to optimize it for XNA?

It seems to me like you ought to sit down and think about exactly what it is you want to accomplish. You seem to be heading down a path that's going to waste some time. First of all, given what I've read in this thread so far, you simply do not know enough about the language(s) to optimize anything. Optimization is often a trap in and of itself, since beginners rarely write code that challenges modern hardware, and if they do it's more along the lines of "choose a more optimal algorithm" than it is "optimize this algorithm". Second of all, if you do want to write a renderer, then the place to start is not with PNG loading code. This is a bad place to start. As many others have indicated, loading PNGs is a solved problem. The work is done for you. That is many, many lines of code that you do not have to write. Why in the name of Pete would you waste your time writing PNG loading code, rather than writing the renderer that you want to write?

Allow me to tell you a story. Once upon a time, I needed to write some code to pack a bunch of sprite rectangles tightly into a texture. So I googled rectangle packing, and I stumbled upon some algorithms. I knew just enough about the languages at the time to be able to adapt the code to my needs without fully understanding what it was doing. Eventually, I got to the point where I did understand it, but not by studying that code. I got there by writing game code, learning more about the language as I went. I somehow knew that studying rectangle packing code until I understood it completely was not the optimal route to becoming a better programmer. I also understood that spending a whole bunch of time writing my own packing code, when there was packing code readily available, was not going to get me closer to finishing my game. It would just be a waste of time, and I waste enough time as it is.
Really after everyone is essentially repeating the same mantra, I'm not sure why you're so interested in writing a PNG loader. Does it PROVE something to yourself? To anyone else? What are you trying to get out of it? Knowledge? Knowledge for what? How often are you going to need to write a custom PNG loader if your lifetime, even with a professional job?

As has been said-the virtue of being a good coder is knowing not to reinvent the wheel, you're almost insulting the work of the people that spent all their time creating these libraries and releasing them for us to use. Put them to use, carry their torch on to the next step in the race and make something new. If you were wanting to write a PNG loader just to write a PNG loader, to devote all your time to making a wonderful PNG loader for others to use or something like that, I'm sure you'd have more support. As is, you seem to just be wanting to write one to prove you can, even though you shouldn't.

Really I see this sort of thing come up with new coders all the time, and I tell them exactly what the truth is: Do you have to make EVERYTHING yourself? Did you build the stove you cook your food on in the morning? The bed you sleep on? The house you live in? Have you ever made anything and used a tool? A screwdriver or a hammer someone else made? In retrospect you're doing exactly that, you're assuming people will look down on you or something if you don't do the work of the world and make everything from scratch.

Keep in mind, the last paragraph doesn't necessarily apply to your level of skill or thinking or such like that, I don't know enough about you to comment on that. The point was that I have that come up so often I just have to point out what I respond with, if only to give a glimpse at the reasoning behind what everyone is telling you.

I strongly suggest against .tga nowadays, it's just outdated. RLE compression is pretty much a joke. They have been superceded by png as far as I understand.

TGA is fine for some use cases. So long as you stick to 32-bit uncompressed it's going to go directly into any reasonable texture creation function call without any CPU-side pre-processing required. Yes, the files are larger, but if you're in a postion where they're already on the HD then file size is really the least of your worries. PNG offers good compression without quality loss for sure, but they're slow to load and so can lead to a poorer end-user experience.

The formats I'd personally recommend are DDS or TGA. TGA during content creation or when DXT compression artefacts are too objectionable, DDS for everything else. Any other format is really not necessary and only creates extra unwanted work in your program.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

As far as I recall, uncompressed PNGs load just as fast as TGA.
I sort of agree however with your rationale and yes, I understand setting the compression bar on each step might be a small workflow hiccup.

Previously "Krohm"

I think people are being a little narrow-minded on this thread. I certainly agree that if you need a PNG loader for a project of your own, you should use libpng or whatever existing library. Coding it yourself is the logical equivalent of coding your own graphics driver and API, as well as your operating system, and of course building your own hardware from tin can scraps (good luck with that).

That said, if he wanted to learn how to read PNG's without using a library, it is a good exercise in learning to stick to specifications (and PNG is definitely not the easiest spec out there but it's far from being the hardest either). There is nothing wrong in coding a more or less advanced PNG loader just out of curiosity and of learning how to achieve that goal.

So if you have a deadline to meet or just want to get your project off the ground ASAP, then use an existing library because it'll be less of a headache (and it's not like PNG loading is a cornerstone of your game). But if you are doing it for fun and curiosity... carry on, it's good practice.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

I can't believe most people in this thread. PNG has a very clear specification. The structure of any PNG file after the signature is a sequence of chunks. The chunk structure is composed of 4 elements, each one well documented in the specification. http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html

To read a PNG file you just have to read each chunk and any C or C++ programmer can write code for that. Of course, to uncompress image data you better use a library, that's why libpng needs libz.

So the PNG spec is actually very easy to understand and IMHO libpng is unnecesaryly complex.
This old thing again? It was dead, why'd you bring it back?

This topic is closed to new replies.

Advertisement