RfidResearchGroup / proxmark3

Iceman Fork - Proxmark3
http://www.icedev.se
GNU General Public License v3.0
3.65k stars 981 forks source link

[WIP] Use GDlib in Waveshare ePapers command #2237

Closed socram8888 closed 6 months ago

socram8888 commented 6 months ago

This PR overhauls the image loading and processing steps in the Waveshare ePaper command. Namely:

Using GDlib for image loading and saving

This considerably simplifies the code base, and allows loading PNG, JPEGs, etc... as well as possibly automagically scaling the images to send, simplifying command usage.

This is an optional dependency, so compiling would be still possible, albeit without the Waveshare command. It is available in pretty much every existing Linux distribution, as it is used by PHP.

Pending is its integration with CMakeFiles.txt, which would allow automatically downloading it if not present in the running machine, and have BMP/GIF support without any other dependency when crosscompiling for ie Windows.

Overhauled image dithering

The image dithering step has been totally reimplemented using a simpler code, moved to a dedicated file, and made generic for any palette.

The current system uses a weighted RGB Euclidean distance matching. While relatively simple, this is a poor choice as the RGB color space is not a uniform color space.

The new dithering algorithm uses the same Euclidean distance matching, but rather in the YCbCr color space, which results in in a much, much better accuracy for non-black and white images, as shown here:

Original: Original

Weighted RGB (old, left) vs YCbCr (new, right) for white/black/red: sp200_r_rgb sp200_r_ycbcr

Weighted RGB (old, left) vs YCbCr (new, right) for white/black/red/yellow: sp200_ry_rgb sp200_ry_ycbcr

Original: yuv

Weighted RGB (old, left) vs YCbCr (new, right) for white/black/red: yuv_r_rgb yuv_r_ycbcr

Weighted RGB (old, left) vs YCbCr (new, right) for white/black/red/yellow: yuv_ry_rgb yuv_ry_ycbcr

The results are as saved by the -s switch of the cmdhfwaveshare command. Note there is also some kind of bug with the current implementation that causes those black and white spots to be displayed.

github-actions[bot] commented 6 months ago

You are welcome to add an entry to the CHANGELOG.md as well

iceman1001 commented 6 months ago

Cool PR,

Some points below, as I see it now you remove all old code and introduce a dependency.
I think we can keep the old code for when that dependency is not there or choosing to compile without the GD flag. Then we never loose support for it.

  1. we use calloc.
  2. old code support.
socram8888 commented 6 months ago

The reason why I preferred to remove it instead of commenting it out, is that as shown in the images, the current code is bugged and causes weird splotches to appear in the resulting image. That, and the whole reason I am doing this is that I want to port the Yalatech NFC e-ink code I have in Python, and that will for sure not work with the existing image dithering and loading code.

GDlib can be compiled as mentioned as an automatic library in CMake much like Jansson, which allows basic BMP and GIF loading with no other extra dependency, just like it currently does using the legacy code.

Regarding calloc, I'll replace the malloc with that. I preferred to use malloc since the contents of the array are immediately overwritten by the YCbCr colors, so data is never read until after initialized.

Regarding "old code support", what do you mean? Adding an alias between "load" and "loadbmp"?

iceman1001 commented 6 months ago

Regarding calloc, our code style is to use calloc.

Regarding Non support on system w/o GDlib,

Remember this project compiles on many different OS, and if I understand this PR correct there is no support for waveshare if we don't have the new dependency. That is why I say we can still have support on all current platforms if we keep the old code when compiling on systems that doesn't have GDLib. We never loose support for waveshare that way.

Like this case where I am trying to compile it on a Raspberry pi.
image

image

Even if I could install GDlib on the pi, I don't know how it would look like for termux, android, macos or iOS builds.

iceman1001 commented 6 months ago

After installing libgd-dev, sudo apt install libgd-dev

its detected, compiles, image

but not shown in the client.

I figure the HAVE_GD variable isn't set?

socram8888 commented 6 months ago

Remember this project compiles on many different OS, and if I understand this PR correct there is no support for waveshare if we don't have the new dependency. That is why I say we can still have support on all current platforms if we keep the old code when compiling on systems that doesn't have GDLib. We never loose support for waveshare that way.

But please note the current code is sorta broken: 294713636-8a3d84f9-7383-44ca-844b-f680effca60c Those spots are not supposed to be there. The images are getting corrupted somewhere in the current BMP loading/processing.

Even if I could install GDlib on the pi, I don't know how it would look like for termux, android, macos or iOS builds.

I've already checked - GDlib is available in brew for Mac, available in termux and, as soon as I am done ironing out the CMake issues, will be embedded in cross compilation for iOS.

iceman1001 commented 6 months ago

Need to add the new dep to the gh actions and update the documentation too in order to make a smooth transition.

socram8888 commented 6 months ago

I've now added the library to the documentation, a pertaining changelog, updated all pipelines, and also tested locally on my Windows PC that it builds properly using CMake and Makefiles, using WSL1 and Msys, and embedding it whereas supported.

I will be receiving the 7.5" Waveshare screen soon to test the changes, but in the meantime if you could also test it on your screen, that would be nice.

iceman1001 commented 6 months ago

Excellent!

I notice the help text needs to be updated too.

iceman1001 commented 6 months ago

and then we have the cmakefiles under client/experimantal_lib and client/experimental_client_with_swig which also needs to be updated.

socram8888 commented 6 months ago

I notice the help text needs to be updated too.

Fixed in dccb404329ba294d0cedce7a4733dfb9e6741ebd.

and then we have the cmakefiles under client/experimantal_lib and client/experimental_client_with_swig which also needs to be updated.

Fixed in 48afba02cfa36e763f1f05a64187622735596dd9.

I have also added support in d27669f22cd6a90f17889b7d357027dead51fa76 to convert images using the previously existing -s option, but without having a Proxmark present, so I could add a new test case to pm3_tests.sh. This causes the ProxSpace build to fail, but it's expected as gd is not present so the test fails.

iceman1001 commented 6 months ago

Great!

I managed to upload an image to my waveshare device. You think now that we use GD, can we also enable resizing?....

iceman1001 commented 6 months ago

Still one malloc left
uint8_t * colormap8 = malloc(width8 * gdImageSY(img));

iceman1001 commented 6 months ago

I think its almost ready to be merged.