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