Geant4 Cross Reference |
1 #ifndef tools_fpng 2 #define tools_fpng 3 4 // G.Barrand: pure header version of fpng found at https://github.com/richgel999/fpng 5 // The original namespace fpng had been changed to tools::fpng to avoid 6 // clashes with potential other usage of fpng within the same software. 7 8 // fpng.h - unlicense (see end of fpng.cpp) 9 10 #include <stdlib.h> 11 #include <stdint.h> 12 #include <vector> 13 14 namespace tools { 15 namespace fpng 16 { 17 // Fast CRC-32 SSE4.1+pclmul or a scalar fallback (slice by 4) 18 const uint32_t FPNG_CRC32_INIT = 0; 19 uint32_t fpng_crc32(const void* pData, size_t size, uint32_t prev_crc32 = FPNG_CRC32_INIT); 20 21 // Fast Adler32 SSE4.1 Adler-32 with a scalar fallback. 22 const uint32_t FPNG_ADLER32_INIT = 1; 23 uint32_t fpng_adler32(const void* pData, size_t size, uint32_t adler = FPNG_ADLER32_INIT); 24 25 // ---- Compression 26 enum 27 { 28 // Enables computing custom Huffman tables for each file, instead of using the custom global tables. 29 // Results in roughly 6% smaller files on average, but compression is around 40% slower. 30 FPNG_ENCODE_SLOWER = 1, 31 32 // Only use raw Deflate blocks (no compression at all). Intended for testing. 33 FPNG_FORCE_UNCOMPRESSED = 2, 34 }; 35 36 // Fast PNG encoding. The resulting file can be decoded either using a standard PNG decoder or by the fpng_decode_memory() function below. 37 // pImage: pointer to RGB or RGBA image pixels, R first in memory, B/A last. 38 // w/h - image dimensions. Image's row pitch in bytes must is w*num_chans. 39 // num_chans must be 3 or 4. 40 bool fpng_encode_image_to_memory(const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans, std::vector<uint8_t>& out_buf, uint32_t flags = 0); 41 42 // Fast PNG encoding to the specified file. 43 bool fpng_encode_image_to_file(const char* pFilename, const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans, uint32_t flags = 0); 44 45 // ---- Decompression 46 47 enum 48 { 49 FPNG_DECODE_SUCCESS = 0, // file is a valid PNG file and written by FPNG and the decode succeeded 50 51 FPNG_DECODE_NOT_FPNG, // file is a valid PNG file, but it wasn't written by FPNG so you should try decoding it with a general purpose PNG decoder 52 53 FPNG_DECODE_INVALID_ARG, // invalid function parameter 54 55 FPNG_DECODE_FAILED_NOT_PNG, // file cannot be a PNG file 56 FPNG_DECODE_FAILED_HEADER_CRC32, // a chunk CRC32 check failed, file is likely corrupted or not PNG 57 FPNG_DECODE_FAILED_INVALID_DIMENSIONS, // invalid image dimensions in IHDR chunk (0 or too large) 58 FPNG_DECODE_FAILED_DIMENSIONS_TOO_LARGE, // decoding the file fully into memory would likely require too much memory (only on 32bpp builds) 59 FPNG_DECODE_FAILED_CHUNK_PARSING, // failed while parsing the chunk headers, or file is corrupted 60 FPNG_DECODE_FAILED_INVALID_IDAT, // IDAT data length is too small and cannot be valid, file is either corrupted or it's a bug 61 62 // fpng_decode_file() specific errors 63 FPNG_DECODE_FILE_OPEN_FAILED, 64 FPNG_DECODE_FILE_TOO_LARGE, 65 FPNG_DECODE_FILE_READ_FAILED, 66 FPNG_DECODE_FILE_SEEK_FAILED 67 }; 68 69 // Fast PNG decoding of files ONLY created by fpng_encode_image_to_memory() or fpng_encode_image_to_file(). 70 // If fpng_get_info() or fpng_decode_memory() returns FPNG_DECODE_NOT_FPNG, you should decode the PNG by falling back to a general purpose decoder. 71 // 72 // fpng_get_info() parses the PNG header and iterates through all chunks to determine if it's a file written by FPNG, but does not decompress the actual image data so it's relatively fast. 73 // 74 // pImage, image_size: Pointer to PNG image data and its size 75 // width, height: output image's dimensions 76 // channels_in_file: will be 3 or 4 77 // 78 // Returns FPNG_DECODE_SUCCESS on success, otherwise one of the failure codes above. 79 // If FPNG_DECODE_NOT_FPNG is returned, you must decompress the file with a general purpose PNG decoder. 80 // If another error occurs, the file is likely corrupted or invalid, but you can still try to decompress the file with another decoder (which will likely fail). 81 int fpng_get_info(const void* pImage, uint32_t image_size, uint32_t& width, uint32_t& height, uint32_t& channels_in_file); 82 83 // fpng_decode_memory() decompresses 24/32bpp PNG files ONLY encoded by this module. 84 // If the image was written by FPNG, it will decompress the image data, otherwise it will return FPNG_DECODE_NOT_FPNG in which case you should fall back to a general purpose PNG decoder (lodepng, stb_image, libpng, etc.) 85 // 86 // pImage, image_size: Pointer to PNG image data and its size 87 // out: Output 24/32bpp image buffer 88 // width, height: output image's dimensions 89 // channels_in_file: will be 3 or 4 90 // desired_channels: must be 3 or 4 91 // 92 // If the image is 24bpp and 32bpp is requested, the alpha values will be set to 0xFF. 93 // If the image is 32bpp and 24bpp is requested, the alpha values will be discarded. 94 // 95 // Returns FPNG_DECODE_SUCCESS on success, otherwise one of the failure codes above. 96 // If FPNG_DECODE_NOT_FPNG is returned, you must decompress the file with a general purpose PNG decoder. 97 // If another error occurs, the file is likely corrupted or invalid, but you can still try to decompress the file with another decoder (which will likely fail). 98 int fpng_decode_memory(const void* pImage, uint32_t image_size, std::vector<uint8_t>& out, uint32_t& width, uint32_t& height, uint32_t& channels_in_file, uint32_t desired_channels); 99 100 int fpng_decode_file(const char* pFilename, std::vector<uint8_t>& out, uint32_t& width, uint32_t& height, uint32_t& channels_in_file, uint32_t desired_channels); 101 102 } // namespace fpng 103 } // namespace tools 104 105 //G.Barrand specific: 106 #include "fpng.icc" 107 108 #include "sout" 109 110 #include <ostream> 111 112 namespace tools { 113 namespace fpng { 114 115 inline bool write(std::ostream& a_out, 116 const std::string& a_file, 117 unsigned char* a_buffer, 118 unsigned int a_width, 119 unsigned int a_height, 120 unsigned int a_bpp) { 121 if((a_bpp!=3)&&(a_bpp!=4)) { 122 a_out << "tools::fpng::write : bpp " << a_bpp << " not handled." << std::endl; 123 return false; 124 } 125 if(!fpng_encode_image_to_file(a_file.c_str(),a_buffer, a_width, a_height, a_bpp)) { 126 a_out << "tools::fpng::write : encode() failed for file " << sout(a_file) << "." << std::endl; 127 return false; 128 } 129 return true; 130 } 131 132 }} 133 134 #endif //tools_fpng