Reading part of an image without parsing whole file. What file format and library to use?
In our current project, we are running into memory problems since we need to load too many image files. The current system is loading plain uncompressed Microsoft BMP files, so this is the obvious problem.
So, we are looking for a file format that
- is fast to parse (must run on an embedded Linux system)
- can read some part of the image without decoding the whole file
- uses lossless compression (no 8-bit color tables, please)
- includes a full alpha channel (not just a bitmask as in GIF)
- compiles and runs on Linux and Windows
- can be used in a commercial application (LGPL is fine)
- can be exported to using Photoshop
My first guess was PNG, but I am not sure if I can parse part开发者_开发问答 of an image without decoding the whole file. Do you have any better idea or some experiences to share?
(My impression is that you are facing ram pressure rather than storage limitations - if I'm wrong about that please disregard this)
Compression will save storage space, but I don't think it's necessarily going to help (and could even be counterproductive) to reducing your ram footprint, since you (or at least the OS) end up copying compressed data into ram and then decompressing it to even more ram.
If you have a fairly raw bitmap format, it's a simple matter to calculate the file offset of any pixels of interest, and fseek() there and get a small amount of data. A packed format that combines the colors/channels together could be even better, especially if it's a format directly useful for your output (display or algorithm or whatever).
So a possibility would be to either identify an existing format that is, or write a routine for pre-processing images into a packed bitmap format directly usable by your output, and figure out how to make this a plug in to photoshop, or write a bulk converter tool plugged into whatever writes the flash cards or other storage devices used by your embedded system (you might look at coding it as an output driver to imagemagick in order to get that packages' input format flexibility). The embedded end of your code then becomes extremely simple and memory efficient since it only moves into ram the data it actually needs (modulo O/S buffered read size, but those buffers should get recycled behind the scenes)
JPEG using the ijg library will work. Have a look here and here.
Briefly:
- entropy decode JPEG image
- get the DCT coefficients of the blocks you're interested in
- IDCT only the blocks that you need
The catch is you still have to entropy-decode the entire file, but that's only a fraction of the full decoding pipeline (IDCT of the entire image is what takes the most time). So you have to pass over the entire file, but you're not really "decoding the whole file".
Since you're concerned about memory, you'll probably be relieved that the ijg JPEG decoder has a number of memory managers for working on systems with varying memory requirements. You'll have to consult the documentation for that (it's part of the distributable, I couldn't immediately find a link online).
You can specify a low quantization parameter for nearly-lossless encoding (practically indistinguishable to the human eye) or just skip the quantization step altogether if you're after perfectly lossless encoding.
The only requirement I'm not sure that JPEG can satisfy is the alpha channel. Although, if you just store that as another color channel in the image, the JPEG decoder probably won't care.
精彩评论