#+TITLE: C ECL SDL2 PNG
#+AUTHOR: screwtape
I want to twiddle 8 bit png channels.

I want to perform arbitrary (nonlinear) functions on pixels, but am not
interested in reading or writing unknown png chunks or interlacing etc.

* Install dependencies

#+begin_src sh
 pkg_add sdl2 sdl2_image ecl feh
#+end_src
 reimagine this for your package manager; it's probably similar. (apt install)

* Get the lisp and test empty png

#+begin_src sh
 mkdir png-test && cd png-test
 printf "/users/screwtape/common-lisp/png-pixels.lisp\n" | nc sdf.org 70 > png-pixels.lisp
 printf "/users/screwtape/common-lisp/png-pixel-make.lisp\n" | nc sdf.org 70 > png-pixel-make.lisp
 printf "/users/screwtape/common-lisp/png-pixel-test.lisp\n" | nc sdf.org 70 > png-pixel-test.lisp
 printf "/users/screwtape/common-lisp/empty.png\n" | nc sdf.org 70 > empty.png
#+end_src

* Start ECL
#+begin_src sh
 ecl
#+end_src

* Do eet

#+begin_src lisp
 (load #p"png-pixel-make.lisp")
 (load #p"png-pixels.fas")
 (load #p"png-pixel-test.lisp")
 (ext:system "feh empty.png & feh noisy.png")
 (si:quit)
#+end_src

* Whys and wherefores
 Because I want access to uint8 pixel colors, but not arbitrary png
 functionality, I will use SDL2_image, which wraps libpng [and its zlib dep]
 to load and save them as SDL2_Surface structs. Then, I will read and write
 the pixels of the surface, and save it. The PNG is assumed sRGB color.

** Some things I decided not to do
  SDL2 normally expects you to be blitting (efficiently copying rectangles of
  pixels between) two surfaces, with a blend rule. This is useful for mixing
  images by their alphas or moving and overlaying them in an animation, but
  implies the alpha channel is already set, and does not really imply pixel
  level control. Further, it's slow if you are using accelerated graphics
  (because accelerated graphics involves silly memcopies for common usage).

  Another thing I am not doing is using libpng directly, since I am only
  interested in loading, reading and writing pixels, and saving. These
  behaviours are exposed by SDL2_image and the many various png re/configs are
  mostly out of sight.

  A third thing that I could do instead is write a little scriptfu for GIMP's
  tinyscheme image editing engine. GIMP is a titanically large dependency, and
  I have the feeling that its functionality has gotten monotonically worse
  since its 1997 inception ("what if we used embedded tinyscheme to compose
  scriptable reuseable high level image operations"). I'm not confident that
  all GIMP's developers know that that's the point.

  Fourthly, several obvious optimizations are missing here: Between each pixel
  access, control returns to ECL. This is compounded by not taking the time
  to compile png-pixel-test.lisp to a fas file.