Implementation notes Visual cryptography. ---------------------------------------------------------------------- 0. Concept Before 2022, I did most my image processing in PPM/PGM file formats. But for ICFP 2022, I thought it was finally time to work with libpng so I can operate on PNG directly. It turned out to be an OK experience, and I was wondering if there is something else I can do with libpng after the contest was over, now that I no longer have any time pressure. One thought that came to mind was visual cryptography: https://en.wikipedia.org/wiki/Visual_cryptography Which I had done before, but with text files: https://uguu.org/src_violet_c.html This time around, I plan to make use of PNG's transparency capabilities and generate images instead. ---------------------------------------------------------------------- 1. Patterns Splitting one image into two images has roughly two steps: generate a pattern of random pixels, then write pixels from original image to one of the two output images depending on pattern. For purposes of visual cryptography, a purely random pattern would be a bad choice, because the two output images would only be half as bright but otherwise still has a high semblance to the original image. If input image consists of text that are more than a few pixels high, it's very likely that the text would still be readable in the two output images. What we would prefer would be some pattern that is perhaps more blotchy. Which pattern though? There is a fairly large space of generative patterns to choose from. For many weekends, I was just writing these grayscale or black and white image generators to see which one looked best. This went on until January of 2023, and by then I have quite a few patterns that I was fairly happy about, too much for a single ASCII art, so I made a set ASCII art code with the set of five characters from Princess Principal. The spy theme seems to be a good match. (There is a more recent spy anime in 2022 of course, but maybe I will save Anya for another day). Actually, I ended up with more than five patterns and I couldn't decide on which ones to drop, so I folded two patterns into each of the five programs, selectable by compiling the same source with either C or C++ compiler. ---------------------------------------------------------------------- 2. Embedded data Generating the patterns required including a few headers, so I knew I would have a fair bit of comment space leftover after doing the layout phase. The amount of space remaining ranges between ~110 to ~240 bytes for each program, which is just about the size where I might be able to fit some small utility into each one, but not quite an interesting one. Since these programs are splitting PNGs, it would be nice if I can fit a PNG in those bytes. ~110 bytes is barely enough to fit in a blank 640x360 bitmap, and not enough room to add an ASCII to binary decoder. But if I combine all available comment space, I could fit in a non-blank PNG, with a bit of code to take care of assembling the five parts. The final image that was embedded was a small 640x360 bitmap in 548 bytes, with the ASCII to binary decoder in Ruby. I still had a few bytes left after that, so each source file also contains its own CRC32. ---------------------------------------------------------------------- 3. Testing All programs has been verified to compile and run without warnings with these environments: - gcc 11.3.0 on cygwin, with libpng 1.6.39 - clang 8.0.1 on cygwin, with libpng 1.6.39 - gcc 10.2.1 on linux, with libpng 1.6.37 - clang 11.0.1-2 on linux, with libpng 1.6.37 Embedded data has been verified to extract properly with these environments: - ruby 2.6.4p104 on cygwin - ruby 2.7.4p191 on linux - ruby 2.1.5p273 on linux I had a reasonable set of tests and scripts that I ran continuously throughout development, so I can say with high confidence that other than a few memory leaks (which were intentional), these programs should work as expected. Well, if you don't feed it bitmaps that are too large as to overflow signed 32bits, I suppose. I also made a few utilities to, make, stack, and concatenate PNG files, kind of in the same spirit as NetPBM but operates on PNGs directly. I always thought the handling of alpha channels in NetPBM was rather clumsy, and it was nice that PNG just natively supports alpha. ---------------------------------------------------------------------- 4. Finally... Doing a set of five ASCII art is five times the usual amount work, but I suddenly had more free time as of January this year, more than I ever had in the past 17 years :| Greets to my busy comrades, I wish you well.