Makefile refactoring and cleanup.
[pwl6.git] / rules / images.mk
diff --git a/rules/images.mk b/rules/images.mk
new file mode 100644 (file)
index 0000000..4ef2d69
--- /dev/null
@@ -0,0 +1,63 @@
+# This is free and unencumbered software released into the public
+# domain. To the extent possible under law, the author of this file
+# waives all copyright and related or neighboring rights to it.
+
+$(call include-once.,programs.mk)
+
+XCF2PNG ?= xcf2png
+ICONUTIL := $(call command-v,iconutil icnsutil)
+
+PNGCRUSH ?= pngcrush
+PNGCRUSHFLAGS ?= -brute -blacken -reduce -q
+CRUSH.png ?= $(PNGCRUSH) $(PNGCRUSHFLAGS) -ow
+
+%.png: %.xcf
+       $(XCF2PNG) $< > $@
+
+# First: xcf2png by default calls zcat rather than gzcat. This is
+# totally always broken; non-GNU zcat forces a .Z extension on its
+# input filename. So we can't rely on xcf2png's default behavior.
+# Luckily it offers -Z for a custom decompression program.
+#
+# BUT: When Gimp saves a .xcf.gz (and related formats), it doesn't
+# truncate the file, it just writes until it's done and closes, and
+# whatever data was after that, is still after that. This is terrible
+# because it means the file never shrinks, but it's still nominally a
+# valid gzip file, according to http://www.gzip.org/#faq8.
+#
+# BUT: The suggestion to use gzip -q in the FAQ doesn't work for
+# non-GNU gzip. It shuts up the 'warning,' yes, but it still exits
+# with status code 1 (not even 2, like GNU gzip does for all
+# warnings). It does write out the data perfectly well, at least.
+#
+# BUT (of course): The non-zero exit (somewhat reasonably) makes
+# xcf2png barf and die before writing anything even though it got all
+# the data it needs.
+#
+# So: 1) use gunzip, 2) manually feed it to xcf2png, 3) hope nothing
+# is set to die based on pipe status, 4) hope that if the xcf data is
+# truly busted xcf2png will do something helpful.
+%.png: %.xcf.gz
+       gunzip -c $< | $(XCF2PNG) - > $@
+
+# https://korewanetadesu.com/make-icons.html
+.SECONDEXPANSION:
+%.icns: %.iconset $$(wildcard $$(@D)/$$*.iconset/icon_*.png)
+       $(ICONUTIL) -c icns -o $@ $<
+
+%.ico: %.iconset $$(wildcard $$(@D)/$$*.iconset/icon_*[0-9].png)
+       convert -background transparent -colors 256 $(filter-out $<,$^) $@
+
+find-iconsets = $(shell find $1 -type d -name '*.iconset')
+find-xcfs = $(shell find $1 -type f -name '*.xcf.gz' -or -name '*.xcf')
+
+iconset>icons = $(1:.iconset=.icns) $(1:.iconset=.ico)
+xcf>png = $(patsubst %.xcf,%.png,$(patsubst %.xcf.gz,%.xcf,$1))
+
+pngcrush-stampprefix ?= $(stampprefix)
+pngcrush-stampify = $(1:%.png=$(pngcrush-stampprefix)%.png.crushed)
+
+$(pngcrush-stampprefix)%.png.crushed: %.png
+       $(MKDIR) $(@D)
+       $(CRUSH.png) $<
+       touch $@