{"id":22396159,"url":"https://github.com/hoehrmann/pngwolf","last_synced_at":"2025-07-31T12:30:58.428Z","repository":{"id":63708736,"uuid":"1476914","full_name":"hoehrmann/pngwolf","owner":"hoehrmann","description":"`pngwolf` uses a genetic algorithm to find PNG scanline filter combinations that compress well","archived":false,"fork":false,"pushed_at":"2012-01-07T11:53:48.000Z","size":657,"stargazers_count":109,"open_issues_count":4,"forks_count":18,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-07T01:51:22.543Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://bjoern.hoehrmann.de/pngwolf/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoehrmann.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-03-14T03:47:25.000Z","updated_at":"2025-01-26T11:28:42.000Z","dependencies_parsed_at":"2022-11-24T10:10:18.777Z","dependency_job_id":null,"html_url":"https://github.com/hoehrmann/pngwolf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hoehrmann/pngwolf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoehrmann%2Fpngwolf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoehrmann%2Fpngwolf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoehrmann%2Fpngwolf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoehrmann%2Fpngwolf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoehrmann","download_url":"https://codeload.github.com/hoehrmann/pngwolf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoehrmann%2Fpngwolf/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268039843,"owners_count":24185807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-05T06:07:08.575Z","updated_at":"2025-07-31T12:30:58.150Z","avatar_url":"https://github.com/hoehrmann.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"`pngwolf` is a tool to minimize the size of PNG image files. There are\r\na number of factors that affect the size of PNG image files, such as\r\nthe number of colors in the image and whether the image data is stored\r\nas RGBA data or in the form of references to a color palette. The main\r\nfactor is the quality of the Deflate compression used to compress the\r\nimage data, which is in turn affected by the quality of the compressor\r\nand how well the data to be compressed is arranged.\r\n\r\nThe PNG format supports a number of scanline filters that transform the\r\nimage data by relating nearby pixels mathematically. Choosing the right\r\nfilters for each scanline can make the image data more compressible. It\r\nis, however, infeasible for non-trivial images to find the best filters\r\nso typical encoders rely on a couple of heuristics to find good filters.\r\n\r\n`pngwolf` employs a genetic algorithm to find better filter combinations\r\nthan traditional heuristics. It derives a couple of filter combinations\r\nheuristically, adds a couple of random combinations, and then looks how\r\nwell each combination compresses. Two very different combinations may\r\ncompress similarily well, for instance, one combination may be very good\r\nfor the first couple of scanlines, while the other may be very good for\r\nthe last couple of scanlines. So taking the beginning of one combination\r\nand the tail of the other to make a new one may result in a combination\r\nthat compresses better then the original two.\r\n\r\nThat is, in essence, what `pngwolf` does, over and over again. Further,\r\nthe most widely used PNG encoders use the zlib library for compression.\r\nThe zlib library favours speed over compression ratio in some cases, so\r\nwhatever filters are selected to aid compression, the result with zlib\r\nmay not be the smallest possible. The 7-Zip library by Igor Pavlov has\r\na Deflate encoder that favours size over speed at certain settings. So,\r\n`pngwolf` attempts to make use of both: a fast zlib setting is used to\r\nestimate how well some filter combination aids compression, and when it\r\ngets bored, it uses 7-Zip to generate the final result.\r\n\r\nDoing this `pngwolf` is able to compress some images better than other\r\noptimizers (like `OptiPNG`, `AdvanceCOMP`, `pngcrush`, and `pngout`),\r\neither because it finds better filter combinations then they do, or be-\r\ncause it uses 7-Zip's Deflate implementation (`AdvanceCOMP` uses that\r\naswell, although an older version which sometimes performs better and\r\nsometimes worse, for reasons yet to be studied). It does not attempt to\r\nmake other optimizations, like converting indexed images to RGB format.\r\n\r\nNone of the tools mentioned, including `pngwolf` follow any kind of ho-\r\nlistic approach to PNG optimization, so to get the best results they\r\nneed to be used in combination (and sometimes applying them repeatedly\r\nor in different orders provides the best results). As far as I can tell\r\nmost other tools do not try to preserve the filter combination in the\r\noriginal image, so `pngwolf` should usually be used last or second-to-\r\nlast in the optimization process.\r\n\r\nFor images that are already optimized using all the other tools, there\r\nis about `1%` further reduction to be expected from `pngwolf` for suit-\r\nable images. Still, it should be rare to find images on the Web that\r\n`pngwolf` cannot compress a little bit further.\r\n\r\nThe tool suffers from the lack of a Deflate encoder that makes it easy\r\nstore the results of data analysis (where are duplicate substrings in\r\nthe data) and combine them (if you recall the earlier example where it\r\ntakes the head of one combination and the tail of another, an encoder\r\nwould not have to analyze all of the two parts again, only where they\r\noverlap). So it can often take a long time (as in minutes) to find the\r\nbest results.\r\n\r\nRegardless of the performance deficiency `pngwolf` is well-suited as a\r\nresearch tool to come up with better heuristics for filter selection,\r\nor to extend the genetic algorithm approach to other aspects of PNG op-\r\ntimization (the main thing being considered is re-arranging the entries\r\nin color palettes so the image data compresses better). The tool logs\r\nextensive information in a YAML-based machine-readable format while it\r\nattempts to optimize images which should aid in that.\r\n\r\nIt also addresses two (other) user-interface issues I had in using the\r\nother tools, namely it allows you to make it stop trying to find better\r\noptimizations at well-specified points (such as the total time used),\r\nand if you start an optimization run but grow impatient and abort the\r\nprogram, results should not get lost, but should be stored anyway.\r\n\r\nTo compile `pngwolf` you need three additional libraries:\r\n\r\n  * GAlib http://lancet.mit.edu/ga/dist/\r\n  * 7-Zip http://www.7-zip.org/download.html (\"7-Zip Source code\")\r\n  * zlib  http://zlib.net/\r\n\r\nPut these into `galib`, `7zip`, and `zlib` sub-directories into the\r\ndirectory where pngwolf.cxx is located, and then either use the CMake\r\nutility (http://www.cmake.org/) on the `CMakeLists.txt`, or simply\r\nspecify all the files specified in `CMakeLists.txt` as input to your\r\ncompiler. The latter would look like:\r\n\r\n  % gcc -I7zip/CPP -Igalib pngwolf.cxx galib/ga/GA1DArrayGenome.C \r\n      galib/ga/GAAllele.C ... -lstdc++ -o pngwolf\r\n\r\nIf you are using 7-Zip 9.20 there are two bugs in 7-Zip that prevent\r\ngcc building https://sourceforge.net/support/tracker.php?aid=3200655\r\nit. To address that, apply the patch `sevenzip920.patch` like so:\r\n\r\n  % patch -p 0 \u003c sevenzip920.patch\r\n\r\nI've done this successfully with Visual C++ 2010 and Cygwin gcc 4.3.4.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoehrmann%2Fpngwolf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoehrmann%2Fpngwolf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoehrmann%2Fpngwolf/lists"}