richgel999 / fpng Goto Github PK
View Code? Open in Web Editor NEWSuper fast C++ .PNG writer/reader
Super fast C++ .PNG writer/reader
I don't manage to compile fpng on my Apple MacBook Pro M1 (ARM). I get the following compilation error:
fpng.cpp:304:22: error: invalid output constraint '+b' in asm
__asm__("cpuid;" : "+b"(ebx), "+a"(eax), "+c"(ecx), "=d"(edx));
System:
$ uname -a
Darwin macbookpro 21.2.0 Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000 arm64
/Library/Developer/CommandLineTools/usr/bin/c++ --version
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Any help appreciated! Thanks.
There's lodepng and stb_image numbers, but Wuffs is faster than both.
https://github.com/randy408/libspng is another "single file C library" contender, if you haven't already seen it.
fpng is great, I am adding it to Xmake's package management repository, it requires a valid version number to do the version of the package, and then download the specified tar.gz through the version number. like this, v1.0, v1.0.1, ...
Although even if there is no version number, I can also implement it through git commit + fake version, but this is not recommended.
I hope that fpng can have a good version tag list, thank you very much.
Hello, so i want to flip the image, but i dont know what is the function.
can you help me how to flip the image?
Sorry if my grammar is bad
❓ Maybe add CImg
(https://github.com/dtschump/CImg) and libiio
(https://github.com/mnhrdt/iio) in test?
I was looking over the source code, and I noticed this oddity in the code for detecting chunk type
Lines 2520 to 2526 in b964f65
for (uint32_t i = 0; i < 4; i++)
{
const uint8_t c = pChunk->m_type[0];
It appears that it's checking for non-alphabetical characters in the chunk type string, but it's only repeatedly checking that that's true for the first character in the type. I suspect m_type[0]
was meant to be m_type[i]
I don't believe that this would cause problems, since the other checks should still reject any not-recognized chunk types
There is not such thing as 'public domain' in legal term in many countries, so Creative Commons Zero v1.0 Universal was a license attempt to make text is close as possible to that idea
Just reference it and place SPDX-License-Identifier: CC0-1.0 in the code
Adler-32 and CRC-32 computations are fast with SIMD, but if you just want the fastest possible PNG decoder (e.g. to compare to QOI's speed), ignoring the checksums can be even faster.
For decode (not encode, obviously), IIUC fpng already skips computing/verifying Adler-32 always and CRC-32 sometimes (depending on FPNG_DISABLE_DECODE_CRC32_CHECKS).
Some of the other libraries (lodepng and stb_image) also do this automatically. Wuffs needs to opt in, with a one-liner patch:
diff --git a/src/fpng_test.cpp b/src/fpng_test.cpp
index afc3f77..7302146 100644
--- a/src/fpng_test.cpp
+++ b/src/fpng_test.cpp
@@ -683,6 +683,7 @@ static void* wuffs_decode(void* pData, size_t data_len, uint32_t &width, uint32_
wuffs_png__decoder* pDec = wuffs_png__decoder__alloc();
if (!pDec)
return nullptr;
+ wuffs_png__decoder__set_quirk_enabled(pDec, WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
wuffs_base__image_config ic;
wuffs_base__io_buffer src = wuffs_base__ptr_u8__reader((uint8_t *)pData, data_len, true);
Being header only will make it much easier to integrate into projects.
fpng's top-level README.md says "the [emphasis added] 184 QOI test images (note 182 of the qoi test images don't have alpha channels, so this is almost entirely a 24bpp test)".
QOI updated its test suite a month ago (phoboslab/qoi#69). The new suite contains 2848 images.
Hey! So I am I'm new to all of this in terms of C. I am just a web dev and trying to figure out how to maybe compress PNG images to be usable (Size of File for Speed) on web. Was looking at this and QOI. But this one looks a lot more promising due to it being compatible with PNG decoders already. Anyway, I am doing the Testing section and trying to convert my PNG to FPNG but I am just getting a bigger file of my original PNG or the same size.
Am I do doing it right?
// CMD Line in ./fpng_main/bin
./fpng.exe -s test.png
Is there something else I need to be doing? Sorry again, I am a complete newbie to this type of stuff lol
Hi, thanks for the great library. I had a need to use this from python, so I wrote python
bindings that seem to have a good speedup over opencv-python's imwrite/imencode.
I published the interface here, with the same license as this project: https://github.com/qrmt/fpng-python
Perhaps someone else will find find use for the bindings (and possibly review it), so I thought I'd post it here. Cheers!
Hello!
I'm trying to add FPNG to our image error metric called FLIP (https://github.com/NVlabs/flip/) because we need faster PNG loading.
Unfortunately, I cannot load the first image I tried with:
The code exits on line 3033 in fpng.cpp:
if ((idat_ofs) || (!found_fdec_chunk))
return FPNG_DECODE_NOT_FPNG;
The cause is that found_fdec_chunk==false
.
Any ideas on what can be wrong? The image can be loaded by stbi_image.h
and PhotoShop.
Thanks in advance!
/Tomas
Hello!
We packaging fpng in Conan (conan-io/conan-center-index#22823) and I would like to ask if would be possible to distributed fng as a pre-built library.
The README is clear about single file: https://github.com/richgel999/fpng?tab=readme-ov-file#fpng
fpng is a very fast C++ .PNG image reader/writer for 24/32bpp images. It's a single source file with no dependencies on any other library. fpng.cpp was written to see just how fast you can write .PNG's without sacrificing too much compression
Is it correct to affirm that a library including: fpng.cpp
and fpng.h
, could be built?
I could open a PR adding such feature in case positive to the follow idea.
Regards.
Thank you for providing this great encoder.
I have wrapped it into a Java Library and also ran benchmark against other fast Java PNG Encoders. Your implementation is doing great (despite the JNA overhead and the expensive RGBA byte array composition).
Hi Rich! Thanks for developing fpng.
Is there a recommended contact point (for instance, an email address or a secure bug tracker) to responsibly disclose potential security vulnerabilities to the fpng project?
If it's not too much trouble, it could be nice to have a SECURITY.md
file to answer questions like this in the future; GitHub can display these in the Security tab.
Thanks!
--Neil
Greetings!
I am compiling and running this lib on GitHub MacOS Runner (macos latest
, x64).
In general everything seems to work, but occasionally the tests segfaults:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGILL (0x4) at pc=0x00000001014c3a93, pid=1342, tid=9731
#
# JRE version: OpenJDK Runtime Environment Temurin-11.0.21+9 (11.0.21+9) (build 11.0.21+9)
# Java VM: OpenJDK 64-Bit Server VM Temurin-11.0.21+9 (11.0.21+9, mixed mode, tiered, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# C [libfpng.dylib+0x4a93] fpng::fpng_adler32(void const*, unsigned long, unsigned int)+0xc3
This happens in maybe 6/10 runs. When it happens then always at the same call of fpng::fpng_adler32(void const*, unsigned long, unsigned int)+0xc3
. Please see an example: https://github.com/manticore-projects/fpng-java/actions/runs/6976419875/job/18984960630
I run the very same example also on Windows and Linux and on those GitHub Runners, everything works rock solid.
Also the code would fail on fpng::encode_memory
when my pointers or memories were wrongly allocated.
Can you please provide and hint or idea, why/how this fails on MacOS -- but always sometimes? Test images and settings are static/stable and do not change.
Thank you already and best!
heap-buffer-overflow has occurred when running program fpng_test in function fpng_get_info_internal at fpng.cpp:3011:36
commit 7298d34590a00921df8c0305869e9143e400a1bb (HEAD -> main, origin/main, origin/HEAD)
Author: Rich Geldreich <[email protected]>
Date: Tue Dec 5 01:27:30 2023 -0500
$ git clone https://github.com/richgel999/fpng.git
$ cd fpng
Need to modify the 'CMakeLists.txt:32' to enable ASAN
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address -g -O0")
$ mkdir build && cd build
$ cmake ../
$ make
$ /fpng_test -f ./poc
=================================================================
==6813==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x608000000076 at pc 0x562a3a38b4bb bp 0x7fffa4951300 sp 0x7fffa49512f0
READ of size 4 at 0x608000000076 thread T0
#0 0x562a3a38b4ba in fpng_get_info_internal /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng.cpp:3011
#1 0x562a3a38c0ac in fpng::fpng_decode_memory(void const*, unsigned int, std::vector<unsigned char, std::allocator<unsigned char> >&, unsigned int&, unsigned int&, unsigned int&, unsigned int) /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng.cpp:3099
#2 0x562a3a4d3822 in main /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng_test.cpp:1098
#3 0x7fa146029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#4 0x7fa146029e3f in __libc_start_main_impl ../csu/libc-start.c:392
#5 0x562a3a379d14 in _start (/home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/bin/fpng_test+0x20d14)
0x608000000077 is located 0 bytes to the right of 87-byte region [0x608000000020,0x608000000077)
allocated by thread T0 here:
#0 0x7fa1468b61e7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
#1 0x562a3a39ada9 in __gnu_cxx::new_allocator<unsigned char>::allocate(unsigned long, void const*) /usr/include/c++/11/ext/new_allocator.h:127
#2 0x562a3a39a4c8 in std::allocator_traits<std::allocator<unsigned char> >::allocate(std::allocator<unsigned char>&, unsigned long) /usr/include/c++/11/bits/alloc_traits.h:464
#3 0x562a3a3998f3 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_allocate(unsigned long) /usr/include/c++/11/bits/stl_vector.h:346
#4 0x562a3a398649 in std::vector<unsigned char, std::allocator<unsigned char> >::_M_default_append(unsigned long) /usr/include/c++/11/bits/vector.tcc:635
#5 0x562a3a39740a in std::vector<unsigned char, std::allocator<unsigned char> >::resize(unsigned long) /usr/include/c++/11/bits/stl_vector.h:940
#6 0x562a3a4cf533 in read_file_to_vec(char const*, std::vector<unsigned char, std::allocator<unsigned char> >&) /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng_test.cpp:205
#7 0x562a3a4d374e in main /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng_test.cpp:1086
#8 0x7fa146029d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/du4t/Desktop/FuzzTarget/fpng/reproduce/fpng/src/fpng.cpp:3011 in fpng_get_info_internal
Shadow bytes around the buggy address:
0x0c107fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c107fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c107fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c107fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c107fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c107fff8000: fa fa fa fa 00 00 00 00 00 00 00 00 00 00[07]fa
0x0c107fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==6813==ABORTING
Does this library work well on Android (if compiled using NDK)?
❓ Maybe clean repo?
$ git clone [email protected]:richgel999/fpng.git
$ cd fpng
$ git filter-branch --force --index-filter "git rm --cached --ignore-unmatch *.qoi" --prune-empty --tag-name-filter cat -- --all
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
Rewrite 9fad7d93d9b23ade59276a9e25ecaf8be45b3dc5 (2/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 5f3d874a6d838f668bd01a1c9bacf909455f3ba5 (3/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 4934bd832f66c0d83e74724ef74f41352086033d (4/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite ad003486b32f2a2de02bd7bf27f7929c77d77450 (5/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 99d8f93240a24e62bab83d6d9ac7b14899d03141 (6/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 3d5e2598a3a95b61ff812a7409fa7b3a8f0990cf (7/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite af180bffa43cbdbeb8cebc400e799468a0eb3d2d (8/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite fb46604b56652f1313cd0c93d8be3a7645be29a8 (9/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 83b54820e0f0e82bbadfcd9d81fcfbe5b629f599 (10/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite ce637ad28caa147232916e905b13930e1ba504e9 (11/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 540c2b5f4bd4004c33aa71d5ee90433c786fe1ea (12/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite b75f2290027350f7e4cb7d0cf063e94ad3dc09ac (13/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite c1953aff389dbda4cfef43443fe1edb43a293701 (14/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 3292ceaf0bc599c5c13394a65548364a1642266c (15/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 1f62a7ae4d43cf412fa90132752643d8dc373f9f (16/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite f55421f1e9b46610d9d9914c61ea5460a3cc699c (17/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite a011faa73413f82c82ce283927eebac97f929f0f (18/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 009ab0deca2ed74b7b69cfea5ecb7dbe62e91cf8 (19/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 8b4515342a12a1784db143a9db647881f31007b4 (20/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite ff60a4fd6c9af8510417bcba569738d8991a2cb0 (21/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite a1864802167782f700bd15ba3b4c497cc978af07 (22/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 2f10f60f9c842f4bd5645b84ead836a9ec26a142 (23/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 782059869438bbf16e1cce2f012409e3bfed172a (24/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite a651b054896d862934a3bd79e78cb770ec14d11c (25/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 6b9ca2755f15c40ce54025c31c9f94af431f2763 (26/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite b12cb639087e5527b815fefde0a04e58fcf58bfc (27/29) (0 seconds passed, remaining 0 predicted) rm 'qoi.qoi'
Rewrite 29f97115cc90872fe5bae43cbdc8213a53abf42b (29/29) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/main' was rewritten
Ref 'refs/remotes/origin/main' was rewritten
WARNING: Ref 'refs/remotes/origin/main' is unchanged
Ref 'refs/tags/initial' was rewritten
$ git gc --prune=now --aggressive
$ git repack -a -d -f --depth=250 --window=250
$ git shortlog -s -n
$ git push origin --force --all
$ git push origin --force --tags
Current repo size: 528.00KiB.
Expected repo size: 528 - 333(qoi.qoi) = 195.00KiB
PS: I can do this on my fork for demonstration. Need to?
Apologies for asking a maybe stupid question:
How exactly is const void* pImage
Array supposed to look like? And how to create this array from a Java Image?
From the Python implementation, I can see that a 3 dimensional array is used, however in my understanding a Raster Image has only 2 dimensions?
Any hint or helping hand will be much appreciated, thank you!
Hi Rich,
(I sent an email about this issue, but I guess it didn't reach you)
fpng is really efficient and interesting work. Congratulations !
However, to cover most of png usual features (and according my need), I think it would be great to add the following support/features :
I think that I can add the support of resolution and icc profile, keeping the code fast and the API simple (just passing an
extra pointer for optional tags, that can be extend to other tags in the future)...
Do you think you may extend your code in the future to support indexed images ?
Best regards
Sébastien Léon
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.