PNG is an image format that began development in 1995 and is still widely used today, known for lossless compression and support for transparent pixels. However, this article does not view the image format from a conventional perspective, but instead examines PNG from the perspective of "glitch," exploring what exploitable characteristics it has.
First, it is necessary to understand PNG's CRC32 checksum mechanism. This checksum is used to confirm whether an image is corrupted. Once corruption is detected, ordinary viewers will refuse to display the image. Therefore, the simple method of directly rewriting part of the binary data with a text or binary editor cannot generate glitches (it will fail completely). In other words, the PNG format itself is difficult to glitch. Glitches must be created according to the PNG specification to avoid failure. This means that after decoding the CRC32, the data must be rewritten, and the checksum must be recalculated and appended to the edited data.
Second, attention must be paid to the PNG transcoding process. The encoding process can be simplified into four states, and each state can become a glitch target. However, glitching the first "Raw Data" state is equivalent to glitching a BMP and, strictly speaking, does not count as PNG glitching; the last "Formatted PNG" state cannot take effect because of the checksum mechanism. Therefore, PNG glitches can be produced when "Filtered Data" or "Compressed Data" is manipulated.
When Filtered Data is glitched, it presents a unique effect: petal-like patterns scatter around the image. When the same filter is applied to every scanline, the differences between different filters become obvious. Compressed Data glitches, on the other hand, carry the characteristics of the Deflate compression algorithm itself, presenting an effect similar to snowflake noise.
In addition to the transcoding process, elements such as transparent pixels and interlacing also affect the appearance of glitches. The factor that most determines the appearance of glitches is the filter. A filter converts the uncompressed pixel data of each scanline through a specific algorithm to improve compression efficiency. There are five filters in total: the four algorithms Sub, Up, Average, and Paeth, as well as None (no filter applied). PNG images usually apply the most suitable filter to each scanline before compression, so actual PNGs use a combination of all five filters. These filters usually only affect compression efficiency, and the output is always the same. But when the filtered data is damaged, the output shows obvious differences. For optimized images that combine all five filters, it is difficult to identify filter differences; but when the same single filter is applied to every scanline and then glitched, the differences become very obvious.
Each filter has a different glitch effect: when "None" (no filter) is applied) is raw data corruption, where each pixel is isolated, and rewriting a single byte will not produce a large-scale effect. When "Sub" is applied, the target pixel references the pixel to its right, and the corruption pattern avalanches to the right. When "Up" is applied, the reference direction is up and down. When "Average" is applied, the reference is in the diagonal direction, showing a meteor-like trail starting from the damaged pixel, with a soft gradient; the result lacks a glitch feel and is the most delicate part of PNG glitching. When "Paeth" is applied, the algorithm is the most complex, and the glitch effect is also the most complex: even if the fewest bytes are rewritten, the affected range is very large, and the contours of people in the original image are preserved but strongly destroyed; this is the dominant effect of PNG glitching.
Compressed Data glitching produces a blizzard effect, making the original graphic hard to recognize, occasionally leaving residual filter effects, and the image is often completely destroyed. When glitching images that contain transparent pixels, transparency becomes an effect, and the Average filter in particular seems to gradually blend transparent pixels. The handling of clusters of 100% transparent pixels is the same as that of solid-color areas. The Up filter is often used for solid-color areas. Newer general-purpose image formats may switch compression schemes depending on whether the image is a solid-color area or a complex image such as a photograph, so testing glitches with images that contain solid-color areas is an effective method; WebP is one example. PNG interlacing is based on the 8x8-pixel Adam7 algorithm, divided into seven passes. When glitching an interlaced PNG, this algorithm can be observed intuitively, and the stitching effect can also be confirmed, and the angle narrows under the Average filter.
PNG is very simple compared with JPEG or other new image formats; the filter algorithm is like a toy, and the compression method is the same as old-style Zip compression. But it is precisely this simple format that exhibits an astonishing range of glitch variations. Explaining JPEG glitches may require only one example, but explaining PNG glitches requires many different types of samples. PNG was originally developed as a replacement format for GIF, but in terms of glitching, GIF is too poor compared with PNG. PNG offers a rich set of results, long hidden behind the barrier of checksums.
Appendix A introduces the PNGlitch library. The author released a small PNG glitch script in 2010; at the time it merely removed CRC32 and re-added it after glitching the internal data. After that, the author continued to rewrite the script, making improved versions for his own work, and in 2014 decided to turn the experience into a library, and the Ruby library PNGlitch was born. All glitch images in this article were made using this library. Using this library requires users to have some knowledge of the Ruby language.
In simple usage, the glitch method handles compressed and decompressed data as a single string instance, which is convenient but may use enormous amounts of memory. When there are memory problems, you can use IOWrite code instead of String. PNGlitch also provides an each_scanline method for per-scanline operations. The glitch method sometimes corrupts the byte representing the filter type, potentially outputting files that some viewers cannot open; the each_scanline method is safer and uses less memory, but takes longer than the glitch method.
In complex operations, scanline data consists of pixel data and a filter type value. Users can rewrite pixel data with Scanline#replace_data, or process it like String#gsub! with Scanline#gsub!. Running the command can confirm the filter types of a PNG file; internally, None, Sub, Up, Average, and Paeth are represented by numeric values 0 through 4 respectively. each_scanline can also be used to check each filter type. In the example, each filter type can be changed to 3 (Average); change_filter will correctly apply the new filter type, and since the filter is recalculated and the PNG is correctly formatted, this will not cause glitches, and the resulting image looks identical to the naked eye. However, filter differences have a large impact on glitches; the outputs of the two examples are completely different, and the difference lies in the filter.
The above code examples all operate on the "Filtered Data" state. When users want to glitch "Compressed Data", they must use the glitch_after_compress method. The PNGlitch library is released as open source:https://github.com/ucnv/pnglitch
Appendix B is a PNG glitch catalog, listing glitch variants not covered in the main text, revealing the broad diversity of PNG glitch expressions. Three simple methods for corrupting data are defined. Five filter types are listed: Sub, Up, Average, Paeth, and optimized combined filters. 120 combination patterns are shown, covering whether alpha is present, whether interlacing is used, and which state is glitched. The generation script is attached at the end.
Appendix C discusses incorrect filters. A PNG scanline consists of a combination of a filter type byte and filtered pixel data. Deliberately creating incorrect combinations is another PNG glitch technique. The image above was generated by code. In PNGlitch, the graft method is used to attach an incorrect filter type to a scanline. This technique makes it easy to examine the differences in glitch effects among filters. The next five images are the results of applying a certain filter type byte to each scanline without modifying the scanline data. What happens if an incorrect filter is implemented? PNGlitch is designed to allow users to freely change the filter method, so the results in that state can be tested. An ordinary viewer using the standard filter method decodes a PNG image encoded with a unique filter method, which may produce algorithmic glitches. The image below is part of such a generated image.