kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=8ac8041adf865525644125599a104f23a3dd286e

commit 8ac8041adf865525644125599a104f23a3dd286e
Author: Kim Woelders <[email protected]>
Date:   Mon Nov 11 19:22:02 2019 +0100

    Test: Add some minimal regression testing
---
 Makefile.am                 |   6 +-
 configure.ac                |   5 +-
 test/.gitignore             |   4 +
 test/Makefile.am            |  53 ++++++++
 test/images/icon-64.argb    |   2 +
 test/images/icon-64.bmp     | Bin 0 -> 12426 bytes
 test/images/icon-64.ff      | Bin 0 -> 32784 bytes
 test/images/icon-64.ff.bz2  | Bin 0 -> 9050 bytes
 test/images/icon-64.ff.gz   | Bin 0 -> 14295 bytes
 test/images/icon-64.gif     | Bin 0 -> 4038 bytes
 test/images/icon-64.ico     | Bin 0 -> 16958 bytes
 test/images/icon-64.ilbm    | Bin 0 -> 12938 bytes
 test/images/icon-64.jpeg    | Bin 0 -> 2454 bytes
 test/images/icon-64.jpg     | Bin 0 -> 2454 bytes
 test/images/icon-64.jpg.mp3 | Bin 0 -> 137421 bytes
 test/images/icon-64.png     | Bin 0 -> 6179 bytes
 test/images/icon-64.ppm     |   4 +
 test/images/icon-64.tga     | Bin 0 -> 12306 bytes
 test/images/icon-64.tiff    | Bin 0 -> 6212 bytes
 test/images/icon-64.webp    | Bin 0 -> 784 bytes
 test/images/icon-64.xbm     |  46 +++++++
 test/images/icon-64.xpm     | 296 ++++++++++++++++++++++++++++++++++++++++++++
 test/test_file.cpp          | 193 +++++++++++++++++++++++++++++
 test/test_load.cpp          | 174 ++++++++++++++++++++++++++
 test/test_save.cpp          | 154 +++++++++++++++++++++++
 25 files changed, 935 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 40eec91..666d516 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,11 @@ AUTOMAKE_OPTIONS = foreign
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = src data doc
+if BUILD_TEST
+SUBDIRS_TEST = test
+endif
+
+SUBDIRS = src data doc $(SUBDIRS_TEST)
 
 CLEANFILES = $(PACKAGE).spec
 
diff --git a/configure.ac b/configure.ac
index 58972ec..8c8b0b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_CANONICAL_BUILD
 AC_CANONICAL_HOST
 
-AM_INIT_AUTOMAKE(1.6 dist-xz)
+AM_INIT_AUTOMAKE(1.6 dist-xz -Wno-portability)
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 AM_CONDITIONAL(SRC_IS_GIT, test -d $srcdir/.git)
@@ -12,6 +12,7 @@ AM_CONDITIONAL(SRC_IS_GIT, test -d $srcdir/.git)
 AC_C_BIGENDIAN
 AC_PROG_CC
 AM_PROG_AS
+AC_PROG_CXX
 
 AC_C_CONST
 
@@ -388,6 +389,7 @@ else
 fi
 AM_CONDITIONAL(BUILD_ID3_LOADER, test "$id3_ok" = yes)
 
+AM_CONDITIONAL(BUILD_TEST, false)
 
 EC_C_WARNINGS()
 EC_C_VISIBILITY(yes)
@@ -407,6 +409,7 @@ data/Makefile
 data/fonts/Makefile
 data/images/Makefile
 doc/Makefile
+test/Makefile
 README
 ])
 AC_OUTPUT
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..375cb30
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,4 @@
+/*.d
+/images/empty.*
+/images/nonex.*
+/images/icon-64.*.*
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..f804f39
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,53 @@
+# Unit test makefile
+#
+noinst_PROGRAMS = $(GTESTS)
+
+ GTEST_LIBS = -lgtest -lstdc++
+
+ GTESTS  = test_file
+ GTESTS += test_load
+ GTESTS += test_save
+
+ AM_CFLAGS  = -Wall -Wextra -Werror -Wno-unused-parameter
+ AM_CFLAGS += $(CFLAGS_ASAN)
+
+ AM_CXXFLAGS = $(AM_CFLAGS)
+
+ AM_CPPFLAGS  = -I $(top_builddir) -I $(top_srcdir)/src/lib
+ AM_CPPFLAGS += -D SRC_DIR='"$(top_srcdir)"'
+ AM_CPPFLAGS += -D BUILD_TEST=1
+
+# Must have proper -lImlib2 on all progs
+ LIBS  = -L$(top_builddir)/src/lib -lImlib2
+ LIBS += $(GTEST_LIBS)
+
+vpath %.c   $(top_srcdir)/src/lib
+
+test_file_SOURCES = test_file.cpp file.c
+test_file_LDADD = $(LIBS)
+
+test_load_SOURCES = test_load.cpp
+test_load_LDADD = $(LIBS)
+
+test_save_SOURCES = test_save.cpp
+test_save_LDADD = $(LIBS)
+
+ TESTS_RUN = $(addprefix run-, $(GTESTS))
+
+ TEST_ENV = IMLIB2_LOADER_PATH=$(top_builddir)/src/modules/loaders/.libs
+
+ VG_PROG = valgrind --leak-check=full
+
+all-local: run
+
+.PHONY: run $(TESTS_RUN)
+run: $(TESTS_RUN)
+$(TESTS_RUN): run-%: %
+       $(TEST_ENV) ./$* $(RUN_OPTS)
+
+ TESTS_RUN_VG = $(addprefix run-vg-, $(GTESTS))
+
+.PHONY: run-vg $(TESTS_RUN_VG)
+run-vg: $(TESTS_RUN_VG)
+$(TESTS_RUN_VG): run-vg-%: %
+       $(TEST_ENV) $(VG_PROG) ./$* $(RUN_OPTS)
diff --git a/test/images/icon-64.argb b/test/images/icon-64.argb
new file mode 100644
index 0000000..6d87c8c
--- /dev/null
+++ b/test/images/icon-64.argb
@@ -0,0 +1,2 @@
+ARGB 64 64 0
+��������������������������������������������������������������������������������������������������������������������^n�tPb�tPb�sPa�sOa�qN_������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������~��yRd�b0G�i5M�k6O�h4M�f4M�b3K�`3J�`2I�^0G�[,D�W(@�R";�L4�G/�Y1D��jx�������������������������������������������������������������������������
 [...]
 �6 
��ht��������������������������������������������������������������������������iw�ͻ��Ѻ��ʰ��α��̬��ɦ��ž����������������������������������������������������������������������������������������������������������������������l~�Wl�oDZ�`1I�R";�G/�=%�5
�6 
��ht������������������������������������������������������������������]m�μ��Ӿ��ε��ϴ��ͮ��ɦ��Ğ����������������������������������������������������������������������������������������������������������������������u���gz�~Wl�qF\�c5M�V'?�K3�B)�8
!�5
�6 
��������������������������������������������������������������gu�ɶ������ѹ��Ҹ��ΰ��Ȧ��ĝ������������������������������������������������������������������������������������������������������}���z���w���r���j|��_s�{Rg�pD[�d6N�X)A�N6�E,�<$�5
�5
�6 
������������������������������������������������������t����������ѻ��ֽ��ϳ��ɨ��Ğ����������y���t���r���q���q���u���t���s���s���r���s���t���u���v���v���v���v���v���v���v���u���u���u���s���r���p���m���j|��ex��^r�~Uj�vKa�l@W�b4L�X)A�N6�F.�?&�5
�5
�6
�C.��������������������������������������������������x������Ҿ��վ��Ժ��ˬ��Š�����������t���m���h~��cz��bz��d{��ez��cw��dx��fz��i|��j~��k��l��l���m���m���m���m���m���m���l���k��k~��j~��h|��fz��cw��_s��Zo�}Tj�wMb�pDZ�h;R�_1I�W'?�N6�F.�?'�6
 �5
�5
�6 
�iKX������������������������������������������]n���������ӽ������α��Ƥ�����������t���i���by��\t��Tl��Qi��Ul��Yp��[r��[q��^s��`v��aw��cx��dy��dz��dz��e{��e{��e{��e{��dz��dz��cy��bx��`w��_u��]s��Yp��Vm�}Rh�yLc�sF]�l>V�e6N�\-E�T$<�L4�F-�@'�7
!�5
�5
�5
�7!�������������������������������������������������ҽ������Թ��ɩ�����������~���h~��_v��Rk�yF_�wE^�|Jc�Og��Sk��Um��Sk��Vm��Xp��Zq��[s��\t��]t��^u��^u��^v��^u��]u��]u��\t��\s��[r��Yq��Wo��Um��Rj�}Og�yJc�uE^�p@Y�j9S�c2L�\*D�T#<�L4�E,�?'�6
 �5
�5
�5
�5
�D/����������������������������������j{�������������־��ϲ��à�����������o���\t�{E^�q<V�s=X�u@Z�yD_�}Ic��Mg��Pj�~Mg�Oi��Qk��Sl��Tn��Uo��Vp��Wp��Wq��Wq��Wq��Wq��Vp��Vo��Uo��Sm��Rl��Pj�Nh�|Ke�yHb�vD^�r@Z�m;U�h5P�b/J�[(C�U"<�N5�G.�@'�6
 �5
�5
�5
�5
�7!���������������������������������ĩ������տ������Ӹ��ɪ�����������|���[r�q;T�n8R�p8T�q:U�s<X�w@\�{D`�~Hd��Kg�~Je�|Je�~Lg��Mi��Oj��Pk��Pl��Qm��Qm��Qm��Qm��Ql��Ql��Pl��Oj��Ni��Lh�~Jf�|Hd�zFa�wC_�t?[�p;W�l7R�g2M�a,H�\&B�U!<�P6�I0�B)�9#�7!�5
�5
�5
�6 
�D0��������������������������v��������������־��ϱ��ġ�����������d{�m7Q�m6P�n6Q�o6R�p7T�r9U�v<Y�z@]�}Ca�Fd�Gd�{Ea�}Gd�~He��Jg��Jh��Kh��Li��Lj��Lj��Lj��Li��Li��Kh��Jg�If�~Gd�|Ec�zCa�xA^�u>[�r;X�o7T�k3Q�f/L�a*G�\%B�W
 <�Q7�K1�C*�>'�<%�9"�6 �5
�5
�7!���������������������п��ħ��������������Ӹ��˪�����������cz��Ha�l6P�m5P�m4P�o4Q�p4R�q6T�u9X�y=[�|?_�~Bb��Ed�{B`�{Ca�}Dc�~Ed��Fe��Gf��Hg��Hg��Hh��Hg��Hg��Gf��Gf��Fe�~Ed�}Cb�{Ba�y?^�w=\�t;Z�q8W�n4S�j1O�f-K�b)G�]$B�X
 =�S8�M3�E,�B+�@(�=&�:$�8!�5
�6 
�Q.>�������������������������������������в��ǣ�������h{��Oe�~E_�m6P�n4P�n3P�o2Q�p2Q�q4T�u8W�x:Z�|=]�~?`��Ab�~Ab�{?_�|Aa�~Bb�Cc��Dd��De��De��Ee��Ee��De��De��Cd�Bc�~Ab�|@`�{>_�y<]�v:[�t8X�q5U�n2R�k/N�g+K�c(G�^$B�Z!>�U:�M3�J1�G.�D,�B*�?'�<%�9#�6
 
�9#���������������������������������׽��έ��ĝ���r���Vk��Oe�{D]�o6Q�n4P�o2P�o1P�p1Q�r3T�v6V�y8Y�|;\�~=_��?a��Ac�|=_�|>`�~?a�@b��Ac��Bd��Bd��Bd��Bd��Bd��Ad��Ac�@b�~?a�}=`�{<^�y:\�w8Z�t6W�r3U�o1R�k.N�h+K�d(G�`%C�\"@�U:�P6�N4�K2�H0�
 [...]
\ No newline at end of file
diff --git a/test/images/icon-64.bmp b/test/images/icon-64.bmp
new file mode 100644
index 0000000..916cf94
Binary files /dev/null and b/test/images/icon-64.bmp differ
diff --git a/test/images/icon-64.ff b/test/images/icon-64.ff
new file mode 100644
index 0000000..d0e3514
Binary files /dev/null and b/test/images/icon-64.ff differ
diff --git a/test/images/icon-64.ff.bz2 b/test/images/icon-64.ff.bz2
new file mode 100644
index 0000000..69d8668
Binary files /dev/null and b/test/images/icon-64.ff.bz2 differ
diff --git a/test/images/icon-64.ff.gz b/test/images/icon-64.ff.gz
new file mode 100644
index 0000000..d66bbf3
Binary files /dev/null and b/test/images/icon-64.ff.gz differ
diff --git a/test/images/icon-64.gif b/test/images/icon-64.gif
new file mode 100644
index 0000000..40448c3
Binary files /dev/null and b/test/images/icon-64.gif differ
diff --git a/test/images/icon-64.ico b/test/images/icon-64.ico
new file mode 100644
index 0000000..91a30e3
Binary files /dev/null and b/test/images/icon-64.ico differ
diff --git a/test/images/icon-64.ilbm b/test/images/icon-64.ilbm
new file mode 100644
index 0000000..30a1160
Binary files /dev/null and b/test/images/icon-64.ilbm differ
diff --git a/test/images/icon-64.jpeg b/test/images/icon-64.jpeg
new file mode 100644
index 0000000..5bcfc3e
Binary files /dev/null and b/test/images/icon-64.jpeg differ
diff --git a/test/images/icon-64.jpg b/test/images/icon-64.jpg
new file mode 100644
index 0000000..5bcfc3e
Binary files /dev/null and b/test/images/icon-64.jpg differ
diff --git a/test/images/icon-64.jpg.mp3 b/test/images/icon-64.jpg.mp3
new file mode 100755
index 0000000..537cee1
Binary files /dev/null and b/test/images/icon-64.jpg.mp3 differ
diff --git a/test/images/icon-64.png b/test/images/icon-64.png
new file mode 100644
index 0000000..82e60b7
Binary files /dev/null and b/test/images/icon-64.png differ
diff --git a/test/images/icon-64.ppm b/test/images/icon-64.ppm
new file mode 100644
index 0000000..e316685
--- /dev/null
+++ b/test/images/icon-64.ppm
@@ -0,0 +1,4 @@
+P6
+64 64
+255
+��������������������������������������������������������������������������������Т�����n^bPtbPtaPsaOs_Nq�����������������������������������������������������������������������������������������������������������������������������������������������������������܋~�dRyG0bM5iO6kM4hM4fK3bJ3`I2`G0^D,[@(W;"R4L/GD1Yxj�����������������������������������������������������������������������������������������������������������������������������������dRycN|s]�r\�s\�v`�ze��m��t��y��x��r��n�zg�r^�hS|
 [...]
7 
6th�������������������������������������������������������wi�»�úѻ�ʾ�κ�̵�ɮ�§�������������������������������������������������������������������������������������~l�lWZDoI1`;"R/G%=
5 
6th�������������������������������������������������m]�ļ�ƾ������ϻ�͵�ɮ�Ġ��������������������������������������������������������������������������������������u�zg�lW~\FqM5c?'V3K)B!
8
5 
6���������������������������������������������ug�������ù�øҽ�ε�Ȯ�ġ�������������������������������������������������������������������������}��z��w��r�|j�s_�gR{[DpN6dA)X6N,E$<
5
5 
6����������������������������������������t�������Ļ�ǽֿ�Ϸ�ɮ�Ħ�����y��t��r��q��q��u��t��s��s��r��s��t��u��v��v��v��v��v��v��v��u��u��u��s��r��p��m�|j�xe�r^�jU~aKvW@lL4bA)X6N.F&?
5
5
6.C�����������������������������������Άx����ƾ�Ǿ�źԹ�˰�ŧ������t��m�~h�zc�zb�{d�ze�wc�xd�zf�|i�~j�k�l��l��m��m��m��m��m��m��l�k�~k�~j�|h�zf�wc�s_�oZ�jT}bMwZDpR;hI1_?'W6N.F'?
 
6
5
5 
6XKi������������������������������n]�������ƽ���׽�β�ƨ������t��i�yb�t\�lT�iQ�lU�pY�r[�q[�s^�v`�wa�xc�yd�zd�zd�{e�{e�{e�{e�zd�zd�yc�xb�w`�u_�s]�pY�mV�hR}cLy]FsV>lN6eE-\<$T4L-F'@!
7
5
5
5!7������������������������������������Ž����ĹԶ�ɫ������~�~h�v_�kR�_Fy^EwcJ|gOkS�mU�kS�mV�pX�qZ�s[�t\�t]�u^�u^�v^�u^�u]�u]�t\�s\�r[�qY�oW�mU�jR�gO}cJy^EuY@pS9jL2cD*\<#T4L,E'?
 
6
5
5
5
5/D������������������������{j����������Ǿֽ�Ϯ�ã������o�t\�^E{V<qX=sZ@u_DycI}gM�jP�gM~iOkQ�lS�nT�oU�pV�pW�qW�qW�qW�qW�pV�oV�oU�mS�lR�jP�hNeK|bHy^DvZ@rU;mP5hJ/bC([<"U5N.G'@
 
6
5
5
5
5!7������������������������������ǿ����¸Ӷ�ɧ������|�r[�T;qR8nT8pU:qX<s\@w`D{dH~gK�eJ~eJ|gL~iM�jO�kP�lP�mQ�mQ�mQ�mQ�lQ�lQ�lP�jO�iN�hL�fJ~dH|aFz_Cw[?tW;pR7lM2gH,aB&\<!U6P0I)B#9!7
5
5
5 
60D�������������������v����������Ǿּ�Ϯ�ğ�����{d�Q7mP6mQ6nR6oT7pU9rY<v]@zaC}dFdGaE{dG}eH~gJ�hJ�hK�iL�jL�jL�jL�iL�iL�hK�gJ�fIdG~cE|aCz^Ax[>uX;rT7oQ3kL/fG*aB%\<
 W7Q1K*C'>%<"9 6
5
5!7���������������ǿг�����������¸Ӷ�˨�����zc�aH�P6lP5mP4mQ4oR4pT6qX9u[=y_?|bB~dE�`B{aC{cD}dE~eF�fG�gH�gH�hH�gH�gH�fG�fG�eF�dE~bC}aB{^?y\=wZ;tW8qS4nO1jK-fG)bB$]=
 X8S3M,E+B(@&=$:!8
5 
6>.Q��������������������������ٽ�б�Ǣ��{h�eO�_E~P6mP4nP3nQ2oQ2pT4qW8uZ:x]=|`?~bA�bA~_?{aA|bB~cCdD�eD�eD�eE�eE�eD�eD�dC�cBbA~`@|_>{]<y[:vX8tU5qR2nN/kK+gG(cB$^>!Z:U3M1J.G,D*B'?%<#9
 
6#9�����������訛����������ǽ׺�έ�Ćr�kV�eO�]D{Q6oP4nP2oP1oQ1pT3rV6vY8y\;|_=~a?�cA�_=|`>|a?~b@cA�dB�dB�dB�dB�dB�dA�cA�b@a?~`=}^<{\:yZ8wW6tU3rR1oN.kK+hG(dC%`@"\:U6P4N2K0H-F+C)@&=#:#9�y���������پ�����������øն�˖��t_�lV�gO�]E|Q7nR5qR3qR2qR1qU4tW6wZ9z]:}_=b>�d@�c@�`=~a>b?�c@�dA�dA�dA�dA�dA�d@�c
 [...]
\ No newline at end of file
diff --git a/test/images/icon-64.tga b/test/images/icon-64.tga
new file mode 100644
index 0000000..751f955
Binary files /dev/null and b/test/images/icon-64.tga differ
diff --git a/test/images/icon-64.tiff b/test/images/icon-64.tiff
new file mode 100644
index 0000000..4cf8b25
Binary files /dev/null and b/test/images/icon-64.tiff differ
diff --git a/test/images/icon-64.webp b/test/images/icon-64.webp
new file mode 100644
index 0000000..ee988d8
Binary files /dev/null and b/test/images/icon-64.webp differ
diff --git a/test/images/icon-64.xbm b/test/images/icon-64.xbm
new file mode 100644
index 0000000..15c9652
--- /dev/null
+++ b/test/images/icon-64.xbm
@@ -0,0 +1,46 @@
+#define icon-64_width 64
+#define icon-64_height 64
+static char icon-64_bits[] = {
+  0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 
+  0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x5F, 0xFF, 0x0F, 0x00, 0x00, 
+  0x00, 0x00, 0xB8, 0x05, 0xE1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 
+  0x00, 0xFE, 0x00, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0xF8, 0x03, 0x00, 
+  0x00, 0xA0, 0x0A, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x30, 0x01, 0x00, 
+  0x00, 0xF0, 0x0F, 0x00, 0x00, 0x48, 0x94, 0x00, 0x00, 0xF8, 0x3F, 0x00, 
+  0x00, 0x0C, 0x02, 0x45, 0x94, 0xA0, 0x7F, 0x00, 0x00, 0x40, 0x58, 0x54, 
+  0x81, 0xD5, 0xFF, 0x00, 0x00, 0x51, 0xA5, 0xAB, 0x5A, 0xFA, 0xFF, 0x00, 
+  0x80, 0x80, 0x7E, 0x2C, 0xAF, 0xFB, 0xFF, 0x01, 0x00, 0xA8, 0xC5, 0xF7, 
+  0xE9, 0xEE, 0xFF, 0x03, 0x40, 0xE1, 0xFF, 0xFE, 0x7B, 0xFF, 0xFF, 0x07, 
+  0x20, 0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xD4, 0xFF, 0xFF, 
+  0xFF, 0xFF, 0xFF, 0x0F, 0x10, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 
+  0x10, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0xFC, 0xFF, 0xFF, 
+  0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 
+  0x04, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0xFF, 0xFF, 0xFF, 
+  0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 
+  0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x40, 0xF6, 0x9F, 0x99, 
+  0x97, 0xBB, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xFF, 
+  0x00, 0xE6, 0x3D, 0x5A, 0x2B, 0xE8, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 
+  0xBF, 0xFD, 0xFF, 0xFF, 0xA0, 0xFD, 0xEF, 0xDE, 0x6B, 0xFA, 0xFF, 0xFF, 
+  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF7, 0x00, 0x40, 0x44, 0x04, 
+  0x04, 0x42, 0xD8, 0xFE, 0x10, 0xF7, 0xFF, 0xAB, 0xAF, 0xED, 0xFE, 0xFF, 
+  0xC8, 0xEC, 0xDE, 0xFE, 0xFD, 0xFF, 0xFF, 0xFF, 0x80, 0x1A, 0x01, 0x22, 
+  0x00, 0x44, 0x58, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 
+  0x08, 0xD8, 0xC4, 0xC2, 0x45, 0x64, 0xB5, 0xD1, 0x50, 0x5F, 0x7F, 0x7D, 
+  0xFD, 0xDF, 0xFF, 0x6F, 0x90, 0xFA, 0xE7, 0x16, 0xA6, 0xDD, 0xFF, 0x56, 
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00, 
+  0x00, 0x00, 0x40, 0x40, 0xA0, 0xFC, 0xDF, 0x0E, 0x58, 0xFB, 0x7F, 0x26, 
+  0xA0, 0xFF, 0xF5, 0x05, 0x6E, 0xDD, 0xBF, 0x23, 0x40, 0x5A, 0x5F, 0xBD, 
+  0xD5, 0xBB, 0xFF, 0x20, 0x40, 0xA5, 0x6F, 0x5E, 0x96, 0xEE, 0x3F, 0x11, 
+  0xA0, 0xFE, 0x95, 0xA1, 0x69, 0xA9, 0x57, 0x10, 0x50, 0xBA, 0x5E, 0x16, 
+  0x40, 0xB0, 0x7D, 0x00, 0x80, 0xDD, 0xA9, 0x52, 0x06, 0xE8, 0x1F, 0x08, 
+  0x00, 0x7B, 0x4A, 0x13, 0x01, 0x60, 0x1F, 0x04, 0x80, 0xD5, 0x27, 0x84, 
+  0x00, 0xC0, 0x16, 0x00, 0x00, 0x5F, 0xB9, 0x02, 0x00, 0x90, 0x06, 0x02, 
+  0x00, 0xFE, 0x06, 0x00, 0x00, 0x60, 0x07, 0x01, 0x00, 0xFE, 0x5D, 0x00, 
+  0x00, 0xC0, 0x05, 0x00, 0x00, 0x5C, 0x01, 0x01, 0x00, 0x50, 0x02, 0x00, 
+  0x00, 0xF0, 0x16, 0x00, 0x00, 0xA0, 0x43, 0x00, 0x00, 0xA0, 0x4B, 0x00, 
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x00, 0xA0, 0x00, 0x00, 
+  0x00, 0x00, 0x17, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 
+  0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x84, 0x00, 0x00, 
+  0x00, 0x00, 0x20, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/test/images/icon-64.xpm b/test/images/icon-64.xpm
new file mode 100644
index 0000000..bf80b7b
--- /dev/null
+++ b/test/images/icon-64.xpm
@@ -0,0 +1,296 @@
+/* XPM */
+static char *icon_64[] = {
+/* columns rows colors chars-per-pixel */
+"64 64 226 2 ",
+"   c #1F0D35",
+".  c #200E36",
+"X  c #230F3B",
+"o  c #25113C",
+"O  c #28163E",
+"+  c #2C1544",
+"@  c #2E1C44",
+"#  c #2A1342",
+"$  c #331B4C",
+"%  c #301A47",
+"&  c #381D52",
+"*  c #36234B",
+"=  c #3B2354",
+"-  c #3E2855",
+";  c #432B5B",
+":  c #41255B",
+">  c #47335C",
+",  c #4A2C65",
+"<  c #492A65",
+"1  c #4C3363",
+"2  c #4C3467",
+"3  c #51356D",
+"4  c #533B6B",
+"5  c #513A67",
+"6  c #543472",
+"7  c #563971",
+"8  c #593C74",
+"9  c #5D3C7B",
+"0  c #583576",
+"q  c #502E6D",
+"w  c #603E7E",
+"e  c #57446C",
+"r  c #5C4473",
+"t  c #5E437A",
+"y  c #5E4D71",
+"u  c #5F516F",
+"i  c #614D75",
+"p  c #62437D",
+"a  c #654B7C",
+"s  c #684E7F",
+"d  c #65517A",
+"f  c #6A547D",
+"g  c #6A5B7C",
+"h  c #635375",
+"j  c #6C607D",
+"k  c #623F80",
+"l  c #644381",
+"z  c #664A82",
+"x  c #694C83",
+"c  c #6D4E89",
+"v  c #6C5383",
+"b  c #6E5B82",
+"n  c #6D538B",
+"m  c #705786",
+"M  c #725C86",
+"N  c #71528E",
+"B  c #745C8B",
+"V  c #755592",
+"C  c #785694",
+"Z  c #755C93",
+"A  c #795B94",
+"S  c #7C559D",
+"D  c #7E5A9C",
+"F  c #76628A",
+"G  c #7A648D",
+"H  c #7C6A8D",
+"J  c #746684",
+"K  c #7B6394",
+"L  c #7E6A92",
+"P  c #7C6499",
+"I  c #7F7091",
+"U  c #7F57A3",
+"Y  c #805C9E",
+"T  c #806D93",
+"R  c #846C9C",
+"E  c #82659D",
+"W  c #847395",
+"Q  c #86739B",
+"!  c #88759A",
+"~  c #8C7C9B",
+"^  c #857894",
+"/  c #825CA3",
+"(  c #855FA9",
+")  c #8563A4",
+"_  c #8866A7",
+"`  c #866BA2",
+"'  c #896CA4",
+"]  c #8965AA",
+"[  c #8D6AAB",
+"{  c #8661A9",
+"}  c #906EAE",
+"|  c #8B74A4",
+" . c #8E7AA6",
+".. c #8C72A7",
+"X. c #9273AD",
+"o. c #947BAC",
+"O. c #927CA7",
+"+. c #8F69B2",
+"@. c #8C66B0",
+"#. c #916BB5",
+"$. c #946EB9",
+"%. c #9574B3",
+"&. c #9876B7",
+"*. c #997BB5",
+"=. c #9671BA",
+"-. c #9975BC",
+";. c #9D7CBB",
+":. c #977AB0",
+">. c #A07FBF",
+",. c #9E7BC1",
+"<. c #9C75C4",
+"1. c #A27DC4",
+"2. c #92899E",
+"3. c #8F839C",
+"4. c #9383A3",
+"5. c #9582AB",
+"6. c #9981AF",
+"7. c #9B8CAB",
+"8. c #978BA4",
+"9. c #9E90AC",
+"0. c #9D96A7",
+"q. c #9C82B3",
+"w. c #9E8CB3",
+"e. c #9E82B9",
+"r. c #9885B3",
+"t. c #9F90B0",
+"y. c #A095AE",
+"u. c #A39AAD",
+"i. c #A18DB6",
+"p. c #A183BC",
+"a. c #A58BBC",
+"s. c #A58BBB",
+"d. c #A293B3",
+"f. c #A99DB5",
+"g. c #A593BC",
+"h. c #A994BD",
+"j. c #AB9CBB",
+"k. c #A599B2",
+"l. c #ADA1BC",
+"z. c #ACA5B4",
+"x. c #B2A8BD",
+"c. c #A585C2",
+"v. c #A78AC2",
+"b. c #AA8CC3",
+"n. c #AC8DCA",
+"m. c #A784CA",
+"M. c #AD94C3",
+"N. c #AD9BC3",
+"B. c #AE92CA",
+"V. c #AF98C8",
+"C. c #B19BC5",
+"Z. c #B195CB",
+"A. c #B49ACB",
+"S. c #B298C8",
+"D. c #AE8BD2",
+"F. c #B495D4",
+"G. c #B99ED2",
+"H. c #B89BD5",
+"J. c #AEA0C3",
+"K. c #B3A3C4",
+"L. c #B6ACC3",
+"P. c #B8ADC4",
+"I. c #B5A4C9",
+"U. c #B9A3CD",
+"Y. c #B6A9C9",
+"T. c #BBABCC",
+"R. c #BCB4C4",
+"E. c #BDB2CC",
+"W. c #BFBAC6",
+"Q. c #BCA4D2",
+"!. c #BEAAD1",
+"~. c #BEA3DA",
+"^. c #BEB1D0",
+"/. c #C0B5CE",
+"(. c #C4BBCD",
+"). c #C1ACD4",
+"_. c #C4ACDB",
+"`. c #C0A5DD",
+"'. c #C4B3D4",
+"]. c #C5BBD3",
+"[. c #C8BCD5",
+"{. c #C6B2DA",
+"}. c #C9B5DB",
+"|. c #CCBCDB",
+" X c #C8B7D7",
+".X c #D0BFDD",
+"XX c #CAB4E1",
+"oX c #CEBAE1",
+"OX c #D1BEE3",
+"+X c #C6ADE0",
+"@X c #C7C1CD",
+"#X c #C8C2CF",
+"$X c #CBC2D5",
+"%X c #CFC8D6",
+"&X c #CDC3DA",
+"*X c #C7C0D0",
+"=X c #D1C5DD",
+"-X c #D3CBDC",
+";X c #D0CAD7",
+":X c #DAD6DE",
+">X c #D6D2DB",
+",X c #D4C3E3",
+"<X c #D6CBE2",
+"1X c #D9CDE4",
+"2X c #DBCCE9",
+"3X c #D7C7E7",
+"4X c #DCD3E5",
+"5X c #DED9E3",
+"6X c #DED3EA",
+"7X c #DFD8E8",
+"8X c #E1DCE6",
+"9X c #E1D5EB",
+"0X c #E4DBEC",
+"qX c #E8DFEF",
+"wX c #E7DDF0",
+"eX c #E3E1E6",
+"rX c #E6E3EA",
+"tX c #E9E4ED",
+"yX c #EBE8EE",
+"uX c #EBE4F1",
+"iX c #EEE9F3",
+"pX c #F1EDF6",
+"aX c #F3EFF8",
+"sX c #F3F1F4",
+"dX c #FFFFFF",
+"fX c #F7F5F9",
+/* pixels */
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX#X0.8.b h h h y y 
8.2.@XeXdXfXfXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX>X~ h , 2 3 2 2 1 > 1 > ; ; = $ + 
> H z.sXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXeX~ d a F B B K K L | ~ ! I H H M f r 5 
; = % o g x.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXeX^ h W Q |  .5.t.l.R.*X;X>X>X-X%[email protected].~ 
F i 5 ; $ O ; z.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXsX^ g 
5.5.7.i.j.P.&X5XrXrXyXrXyXrXrXyXrXrXrXeX:X(.u.T f 5 ; $ X ; 
W.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXu.g 
[email protected] i > * + . h 
sXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXsXH ^ 
f.f.N.Y.P.].5XyXyXeXeX5X5X5X5X5X5X:X5X:X8X:XeXrXrXtXeX#Xu.T h 1 = O o O 
#XdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdX:Xg 
z.l.K.Y.T.T.'.-X5X8X:X>X;X;X;X&X%X%X%X;X;X;X;X>X;X>X:X5XeX:XR.9.T h 5 ; O O . 
0.dXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdX:Xb 
L.L.Y.Y.T.T.Y./.].$X$X].[.(.(.(.(.(.(.(.(.(.(.(.(.(.(.(.#X#X%XW.f.~ G 8 > & + o 
. j dXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdX:XH 
W.W.Y.T.T.Y.K.K.L.P.T.P.P.P.P.P.P.P.P.x.P.x.R.P.R.P.P.L.P.R.P.R.x.k.2.T h 4 ; $ 
o . . J dXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdX:XJ 
(.].T.E.T.Y.N.f.h.j.j.l.f.f.f.j.j.j.l.l.l.l.j.l.l.j.l.l.f.f.f.f.u.u.9.~ T f e > 
= + o . . j dXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdX4Xb 
(.*X^.E.T.Y.J.i.w.w.w.i.w.7.w.9.d.9.d.d.9.k.k.d.y.d.d.d.d.9.9.8.8.8.4.~ W H f r 
5 : $ # X . . 0.dXdXdXdXdXdXdX",
+"dXdXdXdXdXdXsXJ W.$X].^.E.Y.J.i.6.o.5.o.O.O.O.~ O.O.8.O.O.~ O.~ 
3.4.3.3.4.4.2.~ O.~ W W T T J f r 5 : $ + X . . O x.dXdXdXdXdXdX",
+"dXdXdXdXdXdXI z.&X].$X^.Y.J.g.5. .! Q Q ! ~ ~ W ! W W ~ T T ~ ^ ! ! ! ! ! ! W 
W W W T T F j f i e > ; $ % o . . . O eXdXdXdXdXdX",
+"dXdXdXdXfX#X^ -X].].].T.J.g.r.` T E T E T Y F F G T T T T T T T T T T T T T T 
T T T M T f f i r 5 > : $ + o .     . e dXdXdXdXdX",
+"dXdXdXdXfXb &X$X].$X^.J.N.i.| P Y C s f f f M M M M F F T m T T T G G G G G M 
B M M j f f a r 4 5 ; : $ @ O .       . z.dXdXdXdX",
+"dXdXdXdXy.l.&X].&X].Y.J.r.r.P P n t t y z b n b f Y f Y j Y T m G m G m M m M 
m m m f s i w 8 4 > ; : % # # . . .     + pXdXdXdX",
+"dXdXdXyXL 4X$X$X].^.J.g.r.P Z t 7 e t t z z z z s s f f f f m m m m m m m m m 
v s a a i w 8 4 5 , ; = $ # # . .       . 3.dXdXdX",
+"dXdXdXf.Y.-X].&X].Y.g.r.r.Z 7 3 7 7 7 t t z z z s s s s s s s c x m s m v s s 
s a w i w e e 4 1 < : = $ $ # X .   . . . @ pXdXdX",
+"dXdXsXI 5X&X-X].^.J.w.r.P 2 2 7 3 7 7 7 t e z z w s w s s s s c x x x x x x l 
a i w w 8 0 4 q 1 ; : : $ $ # X X . .     . z.dXdX",
+"fXfX*XY.:X&X&X^.Y.g.r.P z 3 3 3 6 6 6 9 7 k k z w w p s s x p s l x x l l l l 
a w w 8 8 4 q q , < : & & & # # # o X . . . ; dXdX",
+"dXfX7.-X-X&X&X^.Y.g.P n k 3 3 3 3 6 6 6 7 k k k s w w p w k p a l l l l l l w 
w w 8 8 8 0 q q , < : : : & $ $ # O O O . . . >XdX",
+"dXeXg.7X&X-X].^.J.I b z t 3 3 3 3 3 6 0 6 9 7 k k w w w w k p w l l l l w l w 
w 9 8 8 0 0 q q < < : : & & $ $ $ % + O O . . ^ dX",
+"dX;X^.7X&X-X^.Y.r.Z n z z 3 3 3 6 6 6 6 9 t k k k k w w k k w w l l l l l w w 
w w 9 9 0 0 q q q < < : & & & $ $ $ % @ O O O > dX",
+"dXL.&X-X&X&X^.N.P P P P n z z z k z n n N N V V V C V V Y V V Y Y Y C C C C C 
C Y s Y s c w w s p r 8 4 4 5 2 1 ; ; ; = * @ O sX",
+"dXf.4X=X1X-X].N.g.w.5.5. .Q Q | P r.r.P 
o.o.6.6.q.q.q.6.6.:.6.6.:.O.:.:.:.9.:.O.:.O.~ O.O.:.X.! R R T H K F M M v f i e 
> - @ R.",
+"rX^.7X7X0X7X<X,X&X$X].$X$X$X&X;X<X7X7XwXtXtXtXtXtXyXyXyXuXtX0X8X8X8X8X8X4X9XeXeXtX8X>X<X=X;X%X#X(.(././.R.P.L.x.z.f.y.~
 J u ; 2.",
+"rX^.7X&X<X^.J.g.w.r. . . .` Q ` P P  .P 
....o.o.X.X.:.:.o.o.X.X.X.X.X.X.>.x.U.C.C.C.h.| | ' ' R R R T K Z B M M m f i r 
5 > * j ",
+"%X].4X&X&XN.g.r.P P P P P V N n Z Z Z Z V S S S Y Y Y Y Y Y Y Y Y Y Y Y 
:.*.*.s.q.q.q._ V N N c c x x a p p p t 7 4 2 2 > - $ u ",
+">X&X<X&X^.J.J.g.g.g... ...P ` P P P P ........ .X.X.X.X.:.:.X.X.[ 
X.X.:.f.s.s.s.s.s.h.9.' ' ' R E E E A A B A A Z n a r 4 1 - - ",
+";X-X7X4X<X&X&X&XoX].^.^.&X&X^.$X-X&X&X,X<X<X<X<X-X1X-X4X1X1X1X>X;X1X;X1X1X:X:X:X<X>X-X%X.X[.[.[.[./././.P.P.Y.L.K.l.g.8.W
 b e * ",
+"P.-X4X&X&X&X^.^.Y.Y.Y.J.V.J.K.K.Y.Y.Y.Y.T.T.^.!.)./.).).)./.).).!.!.!.!.'. 
X).).'.'.'.).U.L.I.C.l.j.h.d.d.i.i.i.w.6.4.| R d 5 * ",
+"P.&X,XY.T.I.N.g.r.o...` ' ' E E Y ) _ _ _ [ [ [ [ } } } } } X.X.X.[ | } [ 
X.X.X.X.X.[ [ _ E _ Y E Y Y m Y x Y Y s s c c m m > % ",
+"-X&X&XY.!.J.M.p.*.%..._ _ ) ) Y Y Y ) _ _ _ _ [ [ [ } } } } } X.X.[ [ [ [ [ [ 
[ [ _ _ _ _ _ ) Y Y Y Y Y m Y m Y Y c c N C Y m @ ",
+"-X-X&XE.^.^.T.Y.V.N.M.g.a.g.a.s.h.s.h.h.h.S.S.S.l.S.S.S.S.A.S.C.S.C.C.C.C.C.C.C.C.C.S.C.M.s.M.s.s.s.:.:.:.:.:.:.[
 O.' *.e.O. .; ",
+"].>X-X-X7XqX7X7X7X6X6X5X9X0XqXtXtXuXuXiXiXiXiXpXpXpXsXiXsXiXiXiXtXyXiXyXyXiXiXtXtXtXtXtXtXtXtXtX0XeX8X5X:X1X>X<X%X.X,X.X'.j.y.g
 ",
+"eX-X&XY. 
X^.!.I.V.M.b.b.a.a.a.v.s.s.s.s.s.h.S.M.S.M.M.S.C.C.S.C.S.S.C.C.M.M.M.M.M.S.M.s.M.s.s.s.>.>.*.*.:.O.&.>.v.n.B.B.M.w.w.J
 ",
+"rX^.&XJ.Y.Y.V.b.e.*.X.%.} ] ] @.} _ [ +.} } } } } 
%.%.%.:.:.%.%.:.%.:.:.X.X.X.X.} %.} [ [ [ _ _ _ E Y Y Y Y ( >.<.<.m.n.v.w.4.8.",
+"dXJ.-XY.Q.!.J.B.b.p.e.-.*.%.%.%.&.&.&.&.*.*.*.;.*.>.;.>.>.>.>.>.>.>.>.>.>.*.*.*.*.s.>.:.:.:.X.X.X.[
 [ _ ) ) X.>.m.m.n.F.V.f.I W.",
+"dXE.<X$X^.&X&X&X].XX^.^.{.{.{.}.|..X.X.X=X=X<X>X1X1X1X4X4X4X8X4X4X5X4X4X:X<X;X<X;X.X.X.X.X
 X X XR.).U.U.C.C.U.}._._.XXXX!.K.g sX",
+"dX&X;X&X!. X|.{.{.).).).G.).`.U.).).).'.'.'. X X.X X.X.X1X8X9X4X1X.X.X.X.X X 
X X X X X).).!.U.U.I.C.C.N.M.B.~.`._._.XXoX^.T.b dX",
+"dXsX^.&XJ.I.Y.V.n.p.;.&.-.&.-.$.&.&.>.>.>.>.>.>.>.c.>.s.).1X1X1X 
Xb.s.b.M.s.>.s.s.s.>.>.*.&.:.X.X.} [ [ _ +.<.D.D.F.~.XXY.t.3.dX",
+"dXdXT.&XY.v.A.B.c.;.$.#.#.#.+.@.] @.} 
+.%.&.*.X.%.&.;.>.>.;XtX6Xs.>.>.>.>.*.*.>.;.*.*.*.[ _ _ _ / / U S S U 
<.1.D.H.+XXXY.J :XdX",
+"dXdX;X&XT.M.M.B.c.>.$.#.#.+.@.#.@.@.+.#.=.&.;.>.;.;.>.>.>.>.>.s.b.b.>.s.s.>.>.>.>.>.;.*.}
 _ _ / / / U S S U 1.D.H._.&X&XY.h dXdX",
+"dXdXfXK.$XM.a.V.n.>.&.$.#.#.#.$.#.+.=.&.&.>.>.>.c.c.c.>.c.b.b.b.b.b.>.b.b.b.b.>.c.>.>.>.%.}
 [ _ ) / Y S U @.D.F.~.XX3X|.3.L.dXdX",
+"dXdXdX^.&XI.v.v.n.1.-.$.#.#.#.$.-.-.&.;.>.>.>.b.b.b.Z.Z.Z.b.Z.Z.S.S.S.S.S.S.G.S.S.M.c.c.>.X.}
 [ _ ) / / ( <.D.~.+X,X6X^.y sXdXdX",
+"dXdXdXsXY.^.v.p.1.1.<.$.$.#.$.$.-.;.>.>.>.1.b.n.Z.Z.Z.S.S.A.S.S.S.S.S.S.G..X}.).).).Q.Z.s.&.X.}
 ] ) / ( @.m.H.+XoX2X<X4.0.dXdXdX",
+"dXdXdXdX&X^.J.c.>.1.<.$.$.$.$.-.-.1.1.m.b.b.n.Z.S.F.G.G.Q.Q.Q.Q.U.G.Q.Q..X1X3X,X,X,X.X).S.&.&.X.}
 _ ) ] $.H.+XoX3X0X^.g sXdXdXdX",
+"dXdXdXdXfXN.^.v.;.,.,.-.$.$.=.<.>.1.m.n.n.Z.Z.A.H.G.Q.Q.).).`.)._.).)._.0XqX0XwX0X9X9X}.S.>.*.*.}
 [ ] } c.`.XX3X6X2XW @XdXdXdXdX",
+"dXdXdXdXdX0Xg.M.;.-.-.<.=.$.=.-.1.b.n.Z.F.F.A.G.G.Q.)._.)._._.}.{.}.}.}.9XaXaXaXpXpXiX.XA.s.>.*.%.[
 } $.H.XXOX6XwXI.H dXdXdXdXdX",
+"dXdXdXdXdXdX&Xw._ 
@.+.=.=.=.=.;.>.1.b.n.Z.G.Q.).Q._._._.}.}.XX}.oXOXOXOXOXpXfXfXfXaX6X.XS.s.p.;.%.%.%.c.+XOX2X0X&XJ
 aXdXdXdXdXdX",
+"dXdXdXdXdXdXfX^.w.S U U { 
+.+.-.>.1.b.Z.A.G._._.}.}.}..XOXOXOX3X3X3X3X2X3X3X6XwX0X2X2XOXS.M.s.>.*.&.&.H.oX3X9X6X!
 >XdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXiX^.e.U U { { 
+.-.>.1.B.Z.A.)._.}.XXoX.XOXOX3X3X2X2X2X6X2X2X9X6X2X9X6X6X}.A.C.s.>.>.;.v.XX3X6X9Xd.L.dXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXaX^.w.U ( { [ 
%.>.p.n.A.G.)._.}.oXOX,X,X3X2X2X2X6X9X9XwXwXwXwXwXwXwX2X).G.S.b.a.>.p._.3X6X9XK.0.dXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXaX[.M.U _ 
+.+.&.>.b.S.G.).{.}..X,X3X2X2X6X9XwXwXwXwXuXuXuXuXuXuXqX 
X).U.A.B.v.p.G.OX2X9XY.9.dXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXaX&XY._ _ 
+.&.>.b.S.G.).}.oXOX3X2X9X9XwXwXqXuXuXiXiXiXpXiXiXuX,X}.'.U.A.B.v.B.oX3X2XJ.d.dXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXaX<X[.%._ [ 
;.v.B.U.).}.=X<X1X1X9XwXuXuXuXaXaXaXaXaXaXaXwX3X,X|.{.).A.b.n.XX3X,Xd.@XdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdX7X-XM.] 
%.;.b.A.Q.{..X3X9X9X9X9XwXqXiXiXaXaXaXiXqX9X6X4X<X=X).U.Z.Z.XX,X 
Xy.8XdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXiX7X[.*.X.;.v.A.).}.<X9XqX0XwXqXqXqXwXwXwXqXqXqX0X0X9X1X}.!.Z.A.XX}.J.K.fXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXuX5X).q.;.a.S.).}.=X9XtXqXqXtXqXwXwXuXwXrXqXqXqX1XoX!.V.G._.Q.l.5XdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXfXuX9X 
Xa.s.M.U.).|.1X9X0XtXtXuXuXtXtXqX0X6X.X{.U.A.Q.U.f.%XdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXfXuX8X1X).S.S.G.).{.|.=X1X1X1X2X=X.X 
X).).A.U.M.].5XdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXpX9X8X$X=X 
X).).U.).).).).)./.).C.C.].;XfXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
+"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXqX9X8X4X=X=X=X[. 
X-X[.8XsXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX"
+};
diff --git a/test/test_file.cpp b/test/test_file.cpp
new file mode 100644
index 0000000..dbc2dcb
--- /dev/null
+++ b/test/test_file.cpp
@@ -0,0 +1,193 @@
+#include <gtest/gtest.h>
+
+/**INDENT-OFF**/
+extern "C" {
+#include "file.h"
+}
+/**INDENT-ON**/
+
+#if 0
+#define D(...) printf(__VA_ARGS__)
+#else
+#define D(...)
+#endif
+
+#define EXPECT_OK(x)  EXPECT_FALSE(x)
+#define EXPECT_ERR(x) EXPECT_TRUE(x)
+
+#if 0
+char               *__imlib_FileKey(const char *file);
+char               *__imlib_FileRealFile(const char *file);
+char               *__imlib_FileExtension(const char *file);
+
+//int                 __imlib_FileExists(const char *s);
+//int                 __imlib_FileIsFile(const char *s);
+//int                 __imlib_FileIsDir(const char *s);
+char              **__imlib_FileDir(const char *dir, int *num);
+void                __imlib_FileFreeDirList(char **l, int num);
+void                __imlib_FileDel(const char *s);
+time_t              __imlib_FileModDate(const char *s);
+char               *__imlib_FileHomeDir(int uid);
+int                 __imlib_FilePermissions(const char *s);
+
+//int                 __imlib_FileCanRead(const char *s);
+int                 __imlib_IsRealFile(const char *s);
+#endif
+
+#define USE_REAL_FILE 0
+
+TEST(FILE, file_extension)
+{
+   const char         *s;
+
+   s = __imlib_FileExtension("abc.def");
+   EXPECT_STREQ(s, "def");
+
+   s = __imlib_FileExtension(".def");
+   EXPECT_STREQ(s, "def");
+
+   s = __imlib_FileExtension("def");
+   EXPECT_STREQ(s, "def");
+
+   s = __imlib_FileExtension(".");
+   EXPECT_STREQ(s, NULL);
+
+   s = __imlib_FileExtension("def.");
+   EXPECT_STREQ(s, NULL);
+
+   s = __imlib_FileExtension("/def.x");
+   EXPECT_STREQ(s, "x");
+
+   s = __imlib_FileExtension("/def");
+   EXPECT_STREQ(s, "def");
+}
+
+TEST(FILE, file_exists)
+{
+   int                 rc;
+
+   rc = __imlib_FileExists("./Makefile");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileExists(".");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileExists("./foob");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileExists("./Makefile:foo");
+   EXPECT_EQ(rc, USE_REAL_FILE);
+
+   rc = __imlib_FileExists(".:foo");
+   EXPECT_EQ(rc, USE_REAL_FILE);
+
+   rc = __imlib_FileExists("./foob:foo");
+   EXPECT_EQ(rc, 0);
+}
+
+TEST(FILE, file_is_file)
+{
+   int                 rc;
+
+   rc = __imlib_FileIsFile("./Makefile");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileIsFile(".");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsFile("./foob");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsFile("./Makefile:foo");
+   EXPECT_EQ(rc, USE_REAL_FILE);
+
+   rc = __imlib_FileIsFile(".:foo");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsFile("./foob:foo");
+   EXPECT_EQ(rc, 0);
+}
+
+TEST(FILE, file_is_dir)
+{
+   int                 rc;
+
+   rc = __imlib_FileIsDir("./Makefile");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsDir(".");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileIsDir("./foob");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsDir("./Makefile:foo");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_FileIsDir(".:foo");
+   EXPECT_EQ(rc, USE_REAL_FILE);
+
+   rc = __imlib_FileIsDir("./foob:foo");
+   EXPECT_EQ(rc, 0);
+}
+
+TEST(FILE, file_can_read)
+{
+   int                 rc;
+
+   rc = __imlib_FileCanRead("./Makefile");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileCanRead(".");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_FileCanRead("./foob");
+   EXPECT_EQ(rc, 0);
+
+   rc = system("touch gylle");
+   EXPECT_EQ(rc, 0);
+   rc = __imlib_FileCanRead("gylle");
+   EXPECT_EQ(rc, 1);
+
+   rc = system("chmod 000 gylle");
+   EXPECT_EQ(rc, 0);
+   rc = __imlib_FileCanRead("gylle");
+   EXPECT_EQ(rc, 0);
+
+   rc = unlink("gylle");
+   EXPECT_EQ(rc, 0);
+}
+
+TEST(FILE, file_is_real_file)
+{
+   int                 rc;
+
+   rc = __imlib_IsRealFile("./Makefile");
+   EXPECT_EQ(rc, 1);
+
+   rc = __imlib_IsRealFile(".");
+   EXPECT_EQ(rc, 0);
+
+   rc = __imlib_IsRealFile("./foob");
+   EXPECT_EQ(rc, 0);
+
+   rc = system("touch gylle");
+   EXPECT_EQ(rc, 0);
+   rc = __imlib_IsRealFile("gylle");
+   EXPECT_EQ(rc, 1);
+
+   rc = system("chmod 000 gylle");
+   EXPECT_EQ(rc, 0);
+   rc = __imlib_IsRealFile("gylle");
+   EXPECT_EQ(rc, 1);
+
+   rc = unlink("gylle");
+   EXPECT_EQ(rc, 0);
+}
+
+int
+main(int argc, char **argv)
+{
+   ::testing::InitGoogleTest(&argc, argv);
+   return RUN_ALL_TESTS();
+}
diff --git a/test/test_load.cpp b/test/test_load.cpp
new file mode 100644
index 0000000..5e47c55
--- /dev/null
+++ b/test/test_load.cpp
@@ -0,0 +1,174 @@
+#include <gtest/gtest.h>
+
+#include <Imlib2.h>
+#include <fcntl.h>
+
+int                 debug = 0;
+
+#define D(...) if (debug) printf(__VA_ARGS__)
+
+#define EXPECT_OK(x)  EXPECT_FALSE(x)
+#define EXPECT_ERR(x) EXPECT_TRUE(x)
+
+#define TOPDIR         SRC_DIR
+#define IMGDIR         TOPDIR "/test/images"
+#define FILE_REF       "icon-64.png"
+
+static const char  *const pfxs[] = {
+   "argb",
+   "bmp",
+   "ff.bz2",                    // bz2
+   "ff",
+   "gif",
+   "ico",
+   "jpg.mp3",                   // id3
+   "jpeg",
+   "ilbm",                      // lbm
+   "png",
+   "ppm",                       // pnm
+   "tga",
+   "tiff",
+   "webp",
+   "xbm",
+   "xpm",
+   "ff.gz",                     // zlib
+};
+#define N_PFX (sizeof(pfxs) / sizeof(char*))
+
+static int
+progress(Imlib_Image im, char percent, int update_x, int update_y,
+         int update_w, int update_h)
+{
+   D("%s: %3d%% %4d,%4d %4dx%4d\n",
+     __func__, percent, update_x, update_y, update_w, update_h);
+
+   return 1;                    /* Continue */
+}
+
+static void
+image_free(Imlib_Image im)
+{
+   imlib_context_set_image(im);
+   imlib_free_image_and_decache();
+}
+
+static void
+test_load(void)
+{
+   char                filei[256];
+   char                fileo[256];
+   unsigned int        i, j;
+   Imlib_Image         im;
+   Imlib_Load_Error    lerr;
+   FILE               *fp;
+   int                 fd;
+   int                 err;
+
+   snprintf(filei, sizeof(filei), "%s/%s", IMGDIR, FILE_REF);
+   D("Load '%s'\n", filei);
+   im = imlib_load_image(filei);
+
+   ASSERT_TRUE(im);
+
+   image_free(im);
+
+   for (i = 0; i < N_PFX; i++)
+     {
+        // Load files of all types
+        snprintf(fileo, sizeof(fileo), "%s/%s.%s", IMGDIR, "icon-64", pfxs[i]);
+        D("Load '%s'\n", fileo);
+        im = imlib_load_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, 0);
+        if (lerr)
+           D("Error %d loading '%s'\n", lerr, fileo);
+        if (im)
+           image_free(im);
+
+        if (strchr(pfxs[i], '.') == 0)
+          {
+             snprintf(filei, sizeof(filei), "%s.%s", "icon-64", pfxs[i]);
+             for (j = 0; j < N_PFX; j++)
+               {
+                  // Load certain types pretending they are something else
+                  snprintf(fileo, sizeof(fileo), "%s/%s.%s.%s", IMGDIR,
+                           "icon-64", pfxs[i], pfxs[j]);
+                  unlink(fileo);
+                  symlink(filei, fileo);
+                  D("Load incorrect suffix '%s'\n", fileo);
+                  im = imlib_load_image_with_error_return(fileo, &lerr);
+                  EXPECT_EQ(lerr, 0);
+                  if (lerr)
+                     D("Error %d loading '%s'\n", lerr, fileo);
+                  if (im)
+                     image_free(im);
+               }
+          }
+
+        // Empty files of all types
+        snprintf(fileo, sizeof(fileo), "%s/%s.%s", IMGDIR, "empty", pfxs[i]);
+        unlink(fileo);
+        fp = fopen(fileo, "wb");
+        fclose(fp);
+        D("Load empty '%s'\n", fileo);
+        im = imlib_load_image_with_error_return(fileo, &lerr);
+        D("  err = %d\n", lerr);
+        EXPECT_TRUE(lerr == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT ||
+                    lerr == IMLIB_LOAD_ERROR_UNKNOWN ||
+                    lerr == IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST);
+
+        // Non-existing files of all types
+        snprintf(fileo, sizeof(fileo), "%s/%s.%s", IMGDIR, "nonex", pfxs[i]);
+        unlink(fileo);
+        symlink("non-existing", fileo);
+        D("Load non-existing '%s'\n", fileo);
+        im = imlib_load_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST);
+
+        // Load via fd
+        snprintf(fileo, sizeof(fileo), "%s/%s.%s", IMGDIR, "icon-64", pfxs[i]);
+        fd = open(fileo, O_RDONLY);
+        D("Load fd %d '%s'\n", fd, fileo);
+        snprintf(fileo, sizeof(fileo), ".%s", pfxs[i]);
+        im = imlib_load_image_fd(fd, pfxs[i]);
+        EXPECT_TRUE(im);
+        if (im)
+           image_free(im);
+        err = close(fd);
+        EXPECT_TRUE(err != 0);
+     }
+}
+
+TEST(LOAD, load_1)
+{
+   test_load();
+}
+
+TEST(LOAD, load_2)
+{
+   imlib_context_set_progress_function(progress);
+   imlib_context_set_progress_granularity(10);
+   test_load();
+}
+
+int
+main(int argc, char **argv)
+{
+   const char         *s;
+
+   ::testing::InitGoogleTest(&argc, argv);
+
+   for (argc--, argv++; argc > 0; argc--, argv++)
+     {
+        s = argv[0];
+        if (*s++ != '-')
+           break;
+        switch (*s)
+          {
+          case 'd':
+             debug++;
+             break;
+          }
+     }
+
+   return RUN_ALL_TESTS();
+}
diff --git a/test/test_save.cpp b/test/test_save.cpp
new file mode 100644
index 0000000..a813482
--- /dev/null
+++ b/test/test_save.cpp
@@ -0,0 +1,154 @@
+#include <gtest/gtest.h>
+
+#include <Imlib2.h>
+
+#if 0
+#define D(...) printf(__VA_ARGS__)
+#else
+#define D(...) do { } while (0)
+#endif
+
+#define EXPECT_OK(x)  EXPECT_FALSE(x)
+#define EXPECT_ERR(x) EXPECT_TRUE(x)
+
+#define TOPDIR         SRC_DIR
+#define FILE_REF       "test/images/icon-64.bmp"
+
+static const char  *const pfxs[] = {
+   "argb",
+   "bmp",
+   "ff",
+// "gif",
+// "ico",
+   "jpeg",
+// "lbm",
+   "png",
+   "pnm",
+   "tga",
+   "tiff",
+   "webp",
+   "xbm",
+// "xpm",
+};
+#define N_PFX (sizeof(pfxs) / sizeof(char*))
+
+static int
+progress(Imlib_Image im, char percent, int update_x, int update_y,
+         int update_w, int update_h)
+{
+   D("%s: %3d%% %4d,%4d %4dx%4d\n",
+     __func__, percent, update_x, update_y, update_w, update_h);
+
+   return 1;                    /* Continue */
+}
+
+static void
+test_save(void)
+{
+   char                filei[256];
+   char                fileo[256];
+   unsigned int        i;
+   int                 w, h;
+   Imlib_Image         im, im1, im2, im3;
+   Imlib_Load_Error    lerr;
+
+   snprintf(filei, sizeof(filei), "%s/%s", TOPDIR, FILE_REF);
+   D("Load '%s'\n", filei);
+   im = imlib_load_image(filei);
+   if (!im)
+     {
+        printf("Error loading '%s'\n", filei);
+        exit(0);
+     }
+
+   imlib_context_set_image(im);
+   w = imlib_image_get_width();
+   h = imlib_image_get_height();
+   im1 = imlib_create_cropped_scaled_image(0, 0, w, h, w + 1, h + 1);
+   im2 = imlib_create_cropped_scaled_image(0, 0, w, h, w + 2, h + 2);
+   im3 = imlib_create_cropped_scaled_image(0, 0, w, h, w + 3, h + 3);
+
+   ASSERT_TRUE(im);
+   ASSERT_TRUE(im1);
+   ASSERT_TRUE(im2);
+   ASSERT_TRUE(im3);
+
+   for (i = 0; i < N_PFX; i++)
+     {
+        imlib_context_set_image(im);
+        imlib_image_set_format(pfxs[i]);
+        w = imlib_image_get_width();
+        h = imlib_image_get_height();
+        snprintf(fileo, sizeof(fileo), "%s/%s-%dx%d.%s",
+                 ".", "img_save", w, h, pfxs[i]);
+        D("Save '%s'\n", fileo);
+        imlib_save_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, 0);
+        if (lerr)
+           D("Error %d saving '%s'\n", lerr, fileo);
+
+        imlib_context_set_image(im1);
+        imlib_image_set_format(pfxs[i]);
+        w = imlib_image_get_width();
+        h = imlib_image_get_height();
+        snprintf(fileo, sizeof(fileo), "%s/%s-%dx%d.%s",
+                 ".", "img_save", w, h, pfxs[i]);
+        D("Save '%s'\n", fileo);
+        imlib_save_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, 0);
+        if (lerr)
+           D("Error %d saving '%s'\n", lerr, fileo);
+
+        imlib_context_set_image(im2);
+        imlib_image_set_format(pfxs[i]);
+        w = imlib_image_get_width();
+        h = imlib_image_get_height();
+        snprintf(fileo, sizeof(fileo), "%s/%s-%dx%d.%s",
+                 ".", "img_save", w, h, pfxs[i]);
+        D("Save '%s'\n", fileo);
+        imlib_save_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, 0);
+        if (lerr)
+           D("Error %d saving '%s'\n", lerr, fileo);
+
+        imlib_context_set_image(im3);
+        imlib_image_set_format(pfxs[i]);
+        w = imlib_image_get_width();
+        h = imlib_image_get_height();
+        snprintf(fileo, sizeof(fileo), "%s/%s-%dx%d.%s",
+                 ".", "img_save", w, h, pfxs[i]);
+        D("Save '%s'\n", fileo);
+        imlib_save_image_with_error_return(fileo, &lerr);
+        EXPECT_EQ(lerr, 0);
+        if (lerr)
+           D("Error %d saving '%s'\n", lerr, fileo);
+     }
+
+   imlib_context_set_image(im);
+   imlib_free_image_and_decache();
+   imlib_context_set_image(im1);
+   imlib_free_image_and_decache();
+   imlib_context_set_image(im2);
+   imlib_free_image_and_decache();
+   imlib_context_set_image(im3);
+   imlib_free_image_and_decache();
+}
+
+TEST(SAVE, save_1)
+{
+   test_save();
+}
+
+TEST(SAVE, save_2)
+{
+   imlib_context_set_progress_function(progress);
+   imlib_context_set_progress_granularity(10);
+   test_save();
+}
+
+int
+main(int argc, char **argv)
+{
+   ::testing::InitGoogleTest(&argc, argv);
+   return RUN_ALL_TESTS();
+}

-- 


Reply via email to