Sure, you could do that, and it would not be "wrong" in the sense that any solution which gets you closer to a working game is never wrong.
But keep in mind that the PNG format is designed to store images for displaying them on a screen. You are using it for something it wasn't designed for. It might work, but you might get better results with a more tailor-made solution.
Which problems exactly does using the PNG format solve?
- Organize data into chunks
- Compress the data
First, chunk organization. Yes, the PNG format allows you to split the image data into individual IDAT
chunks. You can retrieve individual chunks of the image by seeking over all those chunks which don't interest you. But this still requires to read the length-field of each chunk and seek over it to the next chunk until you've reached the chunk you want. So you still need to read a lot of the image file even if you only care about one single chunk. It would be better if you would have some data structure which tells you where to find each chunk. But that would be something you would have to build on your own.
Also, most PNG libraries do not assume that the user would care that much about how they want the chunk organization of their PNG to look. So getting your PNG encoder to organize the PNG file exactly the way you want might be difficult. You could of course write your own PNG encoder which organizes the IDAT
chunks exactly the way you want, but then you can just as well invent your own file format.
And then you have to get your image decoder to get only that one chunk. This is again a very unusual use-case many libraries won't account for.
Or... maybe don't use chunks? Maybe your PNG library has a function like getImageData(x, y, width, height)
? So why not use that to load just the data you want? Keep in mind that when all the image data is in one compressed chunk, then the library has only one way to implement this function: Read the whole image into memory, decompress the whole image, and then extract the section you want from the decompressed data. So in this case the PNG format would really get you no benefit at all.
Then, data compression. PNG uses the well-known DEFLATE
algorithm to compress the IDAT
chunks, which you can get just as easily as a free stand-alone implementation. Before applying DEFLATE, it can optionally apply one of several different filter methods in order to make the image data even more compressible. But these filter methods are all optimized for typical real-world image data. They are unlikely to improve the compression rate much when applied to non-image data.
So what do we learn from this? It might be easier to just roll your own map format:
- Compress each map-chunk to a byte-array using a stock compression algorithm of your choice (which might or might not be
DEFLATE
)
- Create an index which tells you order and length of the compressed chunks
- Write the index to the file, followed by the chunk data
If you want to retrieve a chunk, read the index (you might want to cache it in memory so you don't need to re-read it every time you load a chunk), jump straight to the position in the file it tells you, read it, and decompress it.