Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
08 Dec '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 01cb569b20ec2962ccb1f4b845d2f396ad8b08df (commit)
via a8f40a07ec88adfc05232ea8b0a1174eeb03384d (commit)
via 9132111c70875afe910de2c5fa90327c0947d0f4 (commit)
via e7663526f7a8ee2ba10dbe1e85758c4ea4b3b12e (commit)
via 266c9d02b03917a0bfd6bf7c5a2c94cdbaf43ea3 (commit)
via ac4d7195b3f0ab79365c831f8c0bf26657d737f4 (commit)
via c7f781854b28871c22794e5f43a7625583869edc (commit)
via e450ba0813517e753c32371a58aac2c9c3134130 (commit)
via e7186b166a3c5847490637818694e61a515341e4 (commit)
via b392ec017ad30463f1761a2a66c565417acc153d (commit)
via 71461948b59b8c7e839bd3b3541678449b8c4451 (commit)
via f83e3fc6980bd4cdc1b0151bea961ccfe35aa006 (commit)
via 39c170a76a85408c85175b434dd0250e7b01d314 (commit)
via a5731b6a1f6532ad0b6348f3b198e930ee50f3ea (commit)
from f7ec65e213cd4f5b98add6853202db0d6da72578 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/gfxprim.git/commit/01cb569b20ec2962ccb1f4b845d2f396ad8b08…
commit 01cb569b20ec2962ccb1f4b845d2f396ad8b08df
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Dec 8 15:25:08 2015 +0100
tests: Add 'make afl'
Now all that we need to run the fuzzer is to type 'make afl'.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/Makefile b/Makefile
index 2747b51..4d8de96 100644
--- a/Makefile
+++ b/Makefile
@@ -40,4 +40,14 @@ tar:
$(MAKE) clean
cd .. && tar cf gfxprim-`date +%Y-%b-%d-%HH%MM`.tar gfxprim
+afl:
+ @if [ -z `which afl-gcc 2>/dev/null` ]; then \
+ echo "ERROR: afl-gcc not installed!"; \
+ exit 127; \
+ fi
+ CC=afl-gcc ./configure
+ $(MAKE) -C include
+ $(MAKE) -C libs
+ $(MAKE) afl -C tests/afl
+
include $(TOPDIR)/post.mk
diff --git a/tests/afl/.gitignore b/tests/afl/.gitignore
new file mode 100644
index 0000000..2f32a21
--- /dev/null
+++ b/tests/afl/.gitignore
@@ -0,0 +1 @@
+loaders
diff --git a/tests/afl/Makefile b/tests/afl/Makefile
new file mode 100644
index 0000000..4b12b13
--- /dev/null
+++ b/tests/afl/Makefile
@@ -0,0 +1,17 @@
+TOPDIR=../..
+include $(TOPDIR)/pre.mk
+
+APPS=loaders
+
+CSOURCES=$(shell echo *.c)
+
+# Link the binary statically
+LIBS=$(shell $(TOPDIR)/gfxprim-config --libs-loaders --libs)
+RLIBS=$(subst -lgfxprim-loaders,$(TOPDIR)/build/libgfxprim-loaders.a,$(LIBS))
+LDLIBS=$(subst -lgfxprim,$(TOPDIR)/build/libgfxprim.a,$(RLIBS))
+
+afl: loaders
+ ./run_afl.sh
+
+include $(TOPDIR)/app.mk
+include $(TOPDIR)/post.mk
diff --git a/tests/afl/data/1bpp-1x1.bmp b/tests/afl/data/1bpp-1x1.bmp
new file mode 100644
index 0000000..508b73c
Binary files /dev/null and b/tests/afl/data/1bpp-1x1.bmp differ
diff --git a/tests/afl/data/1bpp-320x1-overlappingcolor.bmp b/tests/afl/data/1bpp-320x1-overlappingcolor.bmp
new file mode 100644
index 0000000..324b66e
Binary files /dev/null and b/tests/afl/data/1bpp-320x1-overlappingcolor.bmp differ
diff --git a/tests/afl/data/1bpp-335x.bmp b/tests/afl/data/1bpp-335x.bmp
new file mode 100644
index 0000000..bbf67b7
Binary files /dev/null and b/tests/afl/data/1bpp-335x.bmp differ
diff --git a/tests/afl/data/1bpp-topdown-320x2.bmp b/tests/afl/data/1bpp-topdown-320x2.bmp
new file mode 100644
index 0000000..cc1020d
Binary files /dev/null and b/tests/afl/data/1bpp-topdown-320x2.bmp differ
diff --git a/tests/afl/data/24bpp-1x1.bmp b/tests/afl/data/24bpp-1x1.bmp
new file mode 100644
index 0000000..fa6c104
Binary files /dev/null and b/tests/afl/data/24bpp-1x1.bmp differ
diff --git a/tests/afl/data/24bpp-323x2.bmp b/tests/afl/data/24bpp-323x2.bmp
new file mode 100644
index 0000000..9db72c9
Binary files /dev/null and b/tests/afl/data/24bpp-323x2.bmp differ
diff --git a/tests/afl/data/24bpp-topdown-32x24.bmp b/tests/afl/data/24bpp-topdown-32x24.bmp
new file mode 100644
index 0000000..c1f072a
Binary files /dev/null and b/tests/afl/data/24bpp-topdown-32x24.bmp differ
diff --git a/tests/afl/data/32bpp-0x240.bmp b/tests/afl/data/32bpp-0x240.bmp
new file mode 100644
index 0000000..ee541ee
Binary files /dev/null and b/tests/afl/data/32bpp-0x240.bmp differ
diff --git a/tests/afl/data/32bpp-101110-32x24.bmp b/tests/afl/data/32bpp-101110-32x24.bmp
new file mode 100644
index 0000000..196b747
Binary files /dev/null and b/tests/afl/data/32bpp-101110-32x24.bmp differ
diff --git a/tests/afl/data/32bpp-1x1.bmp b/tests/afl/data/32bpp-1x1.bmp
new file mode 100644
index 0000000..d1b33e4
Binary files /dev/null and b/tests/afl/data/32bpp-1x1.bmp differ
diff --git a/tests/afl/data/32bpp-320x0.bmp b/tests/afl/data/32bpp-320x0.bmp
new file mode 100644
index 0000000..522dfc3
Binary files /dev/null and b/tests/afl/data/32bpp-320x0.bmp differ
diff --git a/tests/afl/data/32bpp-888-optimalpalette-32x24.bmp b/tests/afl/data/32bpp-888-optimalpalette-32x24.bmp
new file mode 100644
index 0000000..d11032d
Binary files /dev/null and b/tests/afl/data/32bpp-888-optimalpalette-32x24.bmp differ
diff --git a/tests/afl/data/4bpp-1x1.bmp b/tests/afl/data/4bpp-1x1.bmp
new file mode 100644
index 0000000..edc72d8
Binary files /dev/null and b/tests/afl/data/4bpp-1x1.bmp differ
diff --git a/tests/afl/data/4bpp-326x2.bmp b/tests/afl/data/4bpp-326x2.bmp
new file mode 100644
index 0000000..913d4e8
Binary files /dev/null and b/tests/afl/data/4bpp-326x2.bmp differ
diff --git a/tests/afl/data/4bpp-pixeldata-cropped.bmp b/tests/afl/data/4bpp-pixeldata-cropped.bmp
new file mode 100644
index 0000000..76a7c41
Binary files /dev/null and b/tests/afl/data/4bpp-pixeldata-cropped.bmp differ
diff --git a/tests/afl/data/555-1x1.bmp b/tests/afl/data/555-1x1.bmp
new file mode 100644
index 0000000..b85d03c
Binary files /dev/null and b/tests/afl/data/555-1x1.bmp differ
diff --git a/tests/afl/data/555-pixeldata-cropped.bmp b/tests/afl/data/555-pixeldata-cropped.bmp
new file mode 100644
index 0000000..161b2e8
Binary files /dev/null and b/tests/afl/data/555-pixeldata-cropped.bmp differ
diff --git a/tests/afl/data/565-320x2-topdown.bmp b/tests/afl/data/565-320x2-topdown.bmp
new file mode 100644
index 0000000..5d86c78
Binary files /dev/null and b/tests/afl/data/565-320x2-topdown.bmp differ
diff --git a/tests/afl/data/8bpp-1x1.bmp b/tests/afl/data/8bpp-1x1.bmp
new file mode 100644
index 0000000..27ec19a
Binary files /dev/null and b/tests/afl/data/8bpp-1x1.bmp differ
diff --git a/tests/afl/data/8bpp-320x2.bmp b/tests/afl/data/8bpp-320x2.bmp
new file mode 100644
index 0000000..54c8221
Binary files /dev/null and b/tests/afl/data/8bpp-320x2.bmp differ
diff --git a/tests/afl/data/8bpp-colorsused-negative.bmp b/tests/afl/data/8bpp-colorsused-negative.bmp
new file mode 100644
index 0000000..d635597
Binary files /dev/null and b/tests/afl/data/8bpp-colorsused-negative.bmp differ
diff --git a/tests/afl/data/8bpp-pixels-not-in-palette.bmp b/tests/afl/data/8bpp-pixels-not-in-palette.bmp
new file mode 100644
index 0000000..faf1ac0
Binary files /dev/null and b/tests/afl/data/8bpp-pixels-not-in-palette.bmp differ
diff --git a/tests/afl/data/bitdepth-odd.bmp b/tests/afl/data/bitdepth-odd.bmp
new file mode 100644
index 0000000..2a0a207
Binary files /dev/null and b/tests/afl/data/bitdepth-odd.bmp differ
diff --git a/tests/afl/data/bitdepth-zero.bmp b/tests/afl/data/bitdepth-zero.bmp
new file mode 100644
index 0000000..935e49a
Binary files /dev/null and b/tests/afl/data/bitdepth-zero.bmp differ
diff --git a/tests/afl/data/colormasks-missing.bmp b/tests/afl/data/colormasks-missing.bmp
new file mode 100644
index 0000000..5fb8fab
Binary files /dev/null and b/tests/afl/data/colormasks-missing.bmp differ
diff --git a/tests/afl/data/compression-unknown.bmp b/tests/afl/data/compression-unknown.bmp
new file mode 100644
index 0000000..4841f05
Binary files /dev/null and b/tests/afl/data/compression-unknown.bmp differ
diff --git a/tests/afl/data/emptyfile.bmp b/tests/afl/data/emptyfile.bmp
new file mode 100644
index 0000000..e69de29
diff --git a/tests/afl/data/infoheader-cropped.bmp b/tests/afl/data/infoheader-cropped.bmp
new file mode 100644
index 0000000..81ab1c3
Binary files /dev/null and b/tests/afl/data/infoheader-cropped.bmp differ
diff --git a/tests/afl/data/infoheadersize-large.bmp b/tests/afl/data/infoheadersize-large.bmp
new file mode 100644
index 0000000..2d797c0
Binary files /dev/null and b/tests/afl/data/infoheadersize-large.bmp differ
diff --git a/tests/afl/data/infoheadersize-small.bmp b/tests/afl/data/infoheadersize-small.bmp
new file mode 100644
index 0000000..73fcf97
Binary files /dev/null and b/tests/afl/data/infoheadersize-small.bmp differ
diff --git a/tests/afl/data/magicnumber-bad.bmp b/tests/afl/data/magicnumber-bad.bmp
new file mode 100644
index 0000000..be94c5a
Binary files /dev/null and b/tests/afl/data/magicnumber-bad.bmp differ
diff --git a/tests/afl/data/offbits-negative.bmp b/tests/afl/data/offbits-negative.bmp
new file mode 100644
index 0000000..baba6d3
Binary files /dev/null and b/tests/afl/data/offbits-negative.bmp differ
diff --git a/tests/afl/data/planes-zero.bmp b/tests/afl/data/planes-zero.bmp
new file mode 100644
index 0000000..b07e590
Binary files /dev/null and b/tests/afl/data/planes-zero.bmp differ
diff --git a/tests/afl/data/rle4-encoded-320x2.bmp b/tests/afl/data/rle4-encoded-320x2.bmp
new file mode 100644
index 0000000..08ee760
Binary files /dev/null and b/tests/afl/data/rle4-encoded-320x2.bmp differ
diff --git a/tests/afl/data/rle8-64000x1.bmp b/tests/afl/data/rle8-64000x1.bmp
new file mode 100644
index 0000000..6ded0a3
Binary files /dev/null and b/tests/afl/data/rle8-64000x1.bmp differ
diff --git a/tests/afl/data/rle8-absolute-320x2.bmp b/tests/afl/data/rle8-absolute-320x2.bmp
new file mode 100644
index 0000000..d294f41
Binary files /dev/null and b/tests/afl/data/rle8-absolute-320x2.bmp differ
diff --git a/tests/afl/data/rle8-absolute-cropped.bmp b/tests/afl/data/rle8-absolute-cropped.bmp
new file mode 100644
index 0000000..c8d8619
Binary files /dev/null and b/tests/afl/data/rle8-absolute-cropped.bmp differ
diff --git a/tests/afl/data/rle8-blank-160x1.bmp b/tests/afl/data/rle8-blank-160x1.bmp
new file mode 100644
index 0000000..25976fe
Binary files /dev/null and b/tests/afl/data/rle8-blank-160x1.bmp differ
diff --git a/tests/afl/data/rle8-delta-320x2.bmp b/tests/afl/data/rle8-delta-320x2.bmp
new file mode 100644
index 0000000..8a56903
Binary files /dev/null and b/tests/afl/data/rle8-delta-320x2.bmp differ
diff --git a/tests/afl/data/rle8-delta-cropped.bmp b/tests/afl/data/rle8-delta-cropped.bmp
new file mode 100644
index 0000000..44ebc8e
Binary files /dev/null and b/tests/afl/data/rle8-delta-cropped.bmp differ
diff --git a/tests/afl/data/rle8-deltaleavesimage.bmp b/tests/afl/data/rle8-deltaleavesimage.bmp
new file mode 100644
index 0000000..bb31c8a
Binary files /dev/null and b/tests/afl/data/rle8-deltaleavesimage.bmp differ
diff --git a/tests/afl/data/rle8-encoded-320x2.bmp b/tests/afl/data/rle8-encoded-320x2.bmp
new file mode 100644
index 0000000..885ac9a
Binary files /dev/null and b/tests/afl/data/rle8-encoded-320x2.bmp differ
diff --git a/tests/afl/data/rle8-no-end-of-bitmap-marker.bmp b/tests/afl/data/rle8-no-end-of-bitmap-marker.bmp
new file mode 100644
index 0000000..72134b7
Binary files /dev/null and b/tests/afl/data/rle8-no-end-of-bitmap-marker.bmp differ
diff --git a/tests/afl/data/rle8-no-end-of-line-marker.bmp b/tests/afl/data/rle8-no-end-of-line-marker.bmp
new file mode 100644
index 0000000..64d5cdc
Binary files /dev/null and b/tests/afl/data/rle8-no-end-of-line-marker.bmp differ
diff --git a/tests/afl/data/rle8-runlength-cropped.bmp b/tests/afl/data/rle8-runlength-cropped.bmp
new file mode 100644
index 0000000..c2733f7
Binary files /dev/null and b/tests/afl/data/rle8-runlength-cropped.bmp differ
diff --git a/tests/afl/data/ver3_0_palette_1bpp_10x10_white.pcx b/tests/afl/data/ver3_0_palette_1bpp_10x10_white.pcx
new file mode 100644
index 0000000..9fe5a00
Binary files /dev/null and b/tests/afl/data/ver3_0_palette_1bpp_10x10_white.pcx differ
diff --git a/tests/afl/data/ver3_0_palette_24bpp_10x10_white.pcx b/tests/afl/data/ver3_0_palette_24bpp_10x10_white.pcx
new file mode 100644
index 0000000..9bc48fb
Binary files /dev/null and b/tests/afl/data/ver3_0_palette_24bpp_10x10_white.pcx differ
diff --git a/tests/afl/data/ver3_0_palette_2bpp_10x10_white.pcx b/tests/afl/data/ver3_0_palette_2bpp_10x10_white.pcx
new file mode 100644
index 0000000..080a9af
Binary files /dev/null and b/tests/afl/data/ver3_0_palette_2bpp_10x10_white.pcx differ
diff --git a/tests/afl/data/ver3_0_palette_4bpp_10x10_white.pcx b/tests/afl/data/ver3_0_palette_4bpp_10x10_white.pcx
new file mode 100644
index 0000000..da88d77
Binary files /dev/null and b/tests/afl/data/ver3_0_palette_4bpp_10x10_white.pcx differ
diff --git a/tests/afl/data/ver3_0_palette_8bpp_10x10_white.pcx b/tests/afl/data/ver3_0_palette_8bpp_10x10_white.pcx
new file mode 100644
index 0000000..2f7e71e
Binary files /dev/null and b/tests/afl/data/ver3_0_palette_8bpp_10x10_white.pcx differ
diff --git a/tests/afl/data/width-times-height-overflow.bmp b/tests/afl/data/width-times-height-overflow.bmp
new file mode 100644
index 0000000..1dd3a5b
Binary files /dev/null and b/tests/afl/data/width-times-height-overflow.bmp differ
diff --git a/tests/afl/loaders.c b/tests/afl/loaders.c
new file mode 100644
index 0000000..7f3b482
--- /dev/null
+++ b/tests/afl/loaders.c
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Minimal loaders call to be used by american fuzzy lop (afl).
+
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <GP.h>
+
+int main(int argc, char *argv[])
+{
+ GP_Context *img;
+
+ if (argc != 2) {
+ fprintf(stderr, "Takes an image as an parameter\n");
+ return 1;
+ }
+
+ img = GP_LoadImage(argv[1], NULL);
+
+ GP_ContextFree(img);
+
+ return 0;
+}
diff --git a/tests/afl/run_afl.sh b/tests/afl/run_afl.sh
new file mode 100755
index 0000000..4785387
--- /dev/null
+++ b/tests/afl/run_afl.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Start afl in NCPU + 1 threads to saturate CPU
+#
+
+NCPU=$(getconf _NPROCESSORS_ONLN)
+
+DATADIR=data/
+OUTDIR=result/
+EXEC="./loaders @@"
+
+for i in $(seq -w 1 $NCPU); do
+ afl-fuzz -i "$DATADIR" -o "$OUTDIR" -S fuzzer$i $EXEC > /dev/null&
+done
+
+afl-fuzz -i "$DATADIR" -o "$OUTDIR" -M fuzzer00 $EXEC
http://repo.or.cz/gfxprim.git/commit/a8f40a07ec88adfc05232ea8b0a1174eeb0338…
commit a8f40a07ec88adfc05232ea8b0a1174eeb03384d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Dec 8 12:19:48 2015 +0100
build: app.mk: Do not append -lgfxprim
Since we may want to build binaries statically linked with gfxprim.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/app.mk b/app.mk
index 2e10fff..20015ab 100644
--- a/app.mk
+++ b/app.mk
@@ -3,8 +3,8 @@ CLEAN+=$(APPS)
%: %.o
ifdef VERBOSE
- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--start-group $^ $(LDLIBS) -lgfxprim -Wl,--end-group -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--start-group $^ $(LDLIBS) -Wl,--end-group -o $@
else
@echo "LD $@"
- @$(CC) $(CFLAGS) $(LDFLAGS) -Wl,--start-group $^ $(LDLIBS) -lgfxprim -Wl,--end-group -o $@
+ @$(CC) $(CFLAGS) $(LDFLAGS) -Wl,--start-group $^ $(LDLIBS) -Wl,--end-group -o $@
endif
diff --git a/demos/bogoman/Makefile b/demos/bogoman/Makefile
index c998522..005d784 100644
--- a/demos/bogoman/Makefile
+++ b/demos/bogoman/Makefile
@@ -4,7 +4,7 @@ include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
INCLUDE=
-LDLIBS+=-lgfxprim-backends -lgfxprim-loaders
+LDLIBS+=-lgfxprim-backends -lgfxprim-loaders -lgfxprim
APPS=bogoman
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index 1346423..0525e72 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -10,7 +10,7 @@ CSOURCES=$(SOURCES)
endif
INCLUDE=
-LDLIBS+=-lrt
+LDLIBS+=-lrt -lgfxprim
APPS=backend_example loaders_example loaders filters_symmetry gfx_koch\
virtual_backend_example meta_data showimage\
diff --git a/demos/grinder/Makefile b/demos/grinder/Makefile
index 6e53dc3..5abbc1e 100644
--- a/demos/grinder/Makefile
+++ b/demos/grinder/Makefile
@@ -5,7 +5,7 @@ CSOURCES=$(shell echo *.c)
INCLUDE=core gfx
LDLIBS+=-lrt -lm
-LDLIBS+=-lgfxprim-loaders
+LDLIBS+=-lgfxprim-loaders -lgfxprim
APPS=grinder
diff --git a/demos/particle/Makefile b/demos/particle/Makefile
index 7b553e5..f4670ec 100644
--- a/demos/particle/Makefile
+++ b/demos/particle/Makefile
@@ -4,7 +4,7 @@ CSOURCES=$(shell echo *.c)
INCLUDE=
LDFLAGS+=-L$(TOPDIR)/build/
-LDLIBS+=-lrt -lm -lgfxprim-backends
+LDLIBS+=-lrt -lm -lgfxprim-backends -lgfxprim
APPS=particle_demo
diff --git a/demos/spiv/Makefile b/demos/spiv/Makefile
index 9376ee4..e3bc8fe 100644
--- a/demos/spiv/Makefile
+++ b/demos/spiv/Makefile
@@ -7,7 +7,7 @@ INCLUDE=
LDFLAGS+=-L$(TOPDIR)/build/
LDLIBS+=-lrt
-LDLIBS+=-lgfxprim-loaders -lgfxprim-backends
+LDLIBS+=-lgfxprim-loaders -lgfxprim-backends -lgfxprim
APPS=spiv
diff --git a/demos/ttf2img/Makefile b/demos/ttf2img/Makefile
index 636b04b..bdd0992 100644
--- a/demos/ttf2img/Makefile
+++ b/demos/ttf2img/Makefile
@@ -4,7 +4,7 @@ include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
INCLUDE=
-LDLIBS+=-lgfxprim-loaders
+LDLIBS+=-lgfxprim-loaders -lgfxprim
APPS=ttf2img
http://repo.or.cz/gfxprim.git/commit/9132111c70875afe910de2c5fa90327c0947d0…
commit 9132111c70875afe910de2c5fa90327c0947d0f4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Dec 8 11:33:23 2015 +0100
loaders: BMP: RLE8: Fix stop at end.
The RLE8_move() must be called after we decode repeat or undecoded byte
since otherwise we may reset the decoder state to RLE_START after
RLE8_move() set it to RLE_STOP because all image data has been read.
This fixes crash with corrupted RLE8 BMP images.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP_RLE.h b/libs/loaders/GP_BMP_RLE.h
index 2b1a3ba..6d5625b 100644
--- a/libs/loaders/GP_BMP_RLE.h
+++ b/libs/loaders/GP_BMP_RLE.h
@@ -174,8 +174,6 @@ static int RLE8_next_undecoded(struct RLE *rle)
{
GETC(rle);
- RLE8_move(rle);
-
//GP_DEBUG(4, "RLE unencoded %u %u -> %02x", rle->x, rle->y, rle->c);
if (--rle->rep == 0) {
@@ -185,6 +183,8 @@ static int RLE8_next_undecoded(struct RLE *rle)
GETC(rle);
}
+ RLE8_move(rle);
+
rle->move = 1;
return 0;
@@ -192,13 +192,13 @@ static int RLE8_next_undecoded(struct RLE *rle)
static int RLE8_next_repeat(struct RLE *rle)
{
- RLE8_move(rle);
-
//GP_DEBUG(4, "RLE repeat %u %u -> %02x", rle->x, rle->y, rle->c);
if (--rle->rep == 0)
rle->state = RLE_START;
+ RLE8_move(rle);
+
rle->move = 1;
return 0;
http://repo.or.cz/gfxprim.git/commit/e7663526f7a8ee2ba10dbe1e85758c4ea4b3b1…
commit e7663526f7a8ee2ba10dbe1e85758c4ea4b3b12e
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Dec 8 10:37:48 2015 +0100
loaders: BMP: Add sanity check for palette size
The palette size is 32bit integer in BMP header which when set to
absurdly large number makes the process go out of memory when palette
is initialized.
Now we check that palette size is <= 1<<bpp and truncate it otherwise.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP.c b/libs/loaders/GP_BMP.c
index 385fa3d..2112f04 100644
--- a/libs/loaders/GP_BMP.c
+++ b/libs/loaders/GP_BMP.c
@@ -339,9 +339,8 @@ static int read_bitmap_header(GP_IO *io, struct bitmap_info_header *header)
* Reads palette, the format is R G B X, each one byte.
*/
static int read_bitmap_palette(GP_IO *io, struct bitmap_info_header *header,
- GP_Pixel *palette)
+ GP_Pixel *palette, uint32_t palette_colors)
{
- uint32_t palette_colors = get_palette_size(header);
uint32_t palette_offset = header->header_size + 14;
uint8_t pixel_size;
uint32_t i;
@@ -367,7 +366,7 @@ static int read_bitmap_palette(GP_IO *io, struct bitmap_info_header *header,
return err;
}
- uint32_t palette_size = pixel_size * palette_colors;
+ size_t palette_size = pixel_size * palette_colors;
uint8_t *buf = GP_TempAlloc(palette_size);
if (GP_IOFill(io, buf, palette_size)) {
@@ -517,7 +516,7 @@ static int read_palette(GP_IO *io, struct bitmap_info_header *header,
GP_Pixel *palette = GP_TempAllocArr(tmp, GP_Pixel, palette_size);
- if ((err = read_bitmap_palette(io, header, palette)))
+ if ((err = read_bitmap_palette(io, header, palette, palette_size)))
goto err;
if ((err = seek_pixels_offset(io, header)))
@@ -631,11 +630,23 @@ static int read_bitfields_or_rgb(GP_IO *io, struct bitmap_info_header *header,
return 0;
}
+static void check_palette_size(struct bitmap_info_header *header)
+{
+ if (header->palette_colors > 1u << header->bpp) {
+ GP_WARN("Corrupted header bpp=%"PRIu16" palette_size=%"PRIu32
+ ", truncating palette_size to %u",
+ header->bpp, header->palette_colors, 1u << header->bpp);
+ header->palette_colors = 0;
+ }
+}
+
static int read_bitmap_pixels(GP_IO *io, struct bitmap_info_header *header,
GP_Context *context, GP_ProgressCallback *callback)
{
- if (header->compress_type == COMPRESS_RLE8)
+ if (header->compress_type == COMPRESS_RLE8) {
+ check_palette_size(header);
return read_RLE8(io, header, context, callback);
+ }
switch (header->bpp) {
case 1:
@@ -643,6 +654,7 @@ static int read_bitmap_pixels(GP_IO *io, struct bitmap_info_header *header,
case 2:
case 4:
case 8:
+ check_palette_size(header);
return read_palette(io, header, context, callback);
case 16:
case 24:
diff --git a/libs/loaders/GP_BMP_RLE.h b/libs/loaders/GP_BMP_RLE.h
index a3592ed..2b1a3ba 100644
--- a/libs/loaders/GP_BMP_RLE.h
+++ b/libs/loaders/GP_BMP_RLE.h
@@ -279,7 +279,7 @@ static int read_RLE8(GP_IO *io, struct bitmap_info_header *header,
GP_Pixel *palette = GP_TempAlloc(palette_size * sizeof(GP_Pixel));
- if ((err = read_bitmap_palette(io, header, palette)))
+ if ((err = read_bitmap_palette(io, header, palette, palette_size)))
goto err;
if ((err = seek_pixels_offset(io, header)))
http://repo.or.cz/gfxprim.git/commit/266c9d02b03917a0bfd6bf7c5a2c94cdbaf43e…
commit 266c9d02b03917a0bfd6bf7c5a2c94cdbaf43ea3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 18:49:44 2015 +0100
loaders: BMP: RLE8: Add header consistency check.
Make sure that the allocated context is RGB888 since corrupted header
may say something different and the end result is that the RLE8 decoder
writes after the allocated pixmap buffer.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP_RLE.h b/libs/loaders/GP_BMP_RLE.h
index e282f0d..a3592ed 100644
--- a/libs/loaders/GP_BMP_RLE.h
+++ b/libs/loaders/GP_BMP_RLE.h
@@ -270,6 +270,13 @@ static int read_RLE8(GP_IO *io, struct bitmap_info_header *header,
DECLARE_RLE(rle, header->w, GP_ABS(header->h), io);
int err;
+ if (context->pixel_type != GP_PIXEL_RGB888) {
+ GP_WARN("Corrupted BMP header! "
+ "RLE8 is 24bit (RGB888) palette but header says %s",
+ GP_PixelTypeName(context->pixel_type));
+ return EINVAL;
+ }
+
GP_Pixel *palette = GP_TempAlloc(palette_size * sizeof(GP_Pixel));
if ((err = read_bitmap_palette(io, header, palette)))
http://repo.or.cz/gfxprim.git/commit/ac4d7195b3f0ab79365c831f8c0bf26657d737…
commit ac4d7195b3f0ab79365c831f8c0bf26657d737f4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 16:31:01 2015 +0100
core: GP_ContextAlloc() Fix overflow in get_bpr()
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/core/GP_Context.c b/libs/core/GP_Context.c
index 8a6ab30..050c4dd 100644
--- a/libs/core/GP_Context.c
+++ b/libs/core/GP_Context.c
@@ -36,7 +36,15 @@
static uint32_t get_bpr(uint32_t bpp, uint32_t w)
{
- return (bpp * w) / 8 + !!((bpp * w) % 8);
+ uint64_t bits_per_row = (uint64_t)bpp * w;
+ uint8_t padd = !!(bits_per_row % 8);
+
+ if (bits_per_row / 8 + padd > UINT32_MAX) {
+ GP_WARN("Context too wide %u (overflow detected)", w);
+ return 0;
+ }
+
+ return bits_per_row / 8 + padd;
}
GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
@@ -62,7 +70,9 @@ GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
w, h, GP_PixelTypeName(type));
bpp = GP_PixelSize(type);
- bpr = get_bpr(bpp, w);
+
+ if (!(bpr = get_bpr(bpp, w)))
+ return NULL;
size_t size = bpr * h;
http://repo.or.cz/gfxprim.git/commit/c7f781854b28871c22794e5f43a7625583869e…
commit c7f781854b28871c22794e5f43a7625583869edc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 15:32:04 2015 +0100
Loaders: BMP_RLE: Fix unbounded stack allocation.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP_RLE.h b/libs/loaders/GP_BMP_RLE.h
index 4c228fb..e282f0d 100644
--- a/libs/loaders/GP_BMP_RLE.h
+++ b/libs/loaders/GP_BMP_RLE.h
@@ -267,15 +267,16 @@ static int read_RLE8(GP_IO *io, struct bitmap_info_header *header,
GP_Context *context, GP_ProgressCallback *callback)
{
uint32_t palette_size = get_palette_size(header);
- GP_Pixel palette[get_palette_size(header)];
DECLARE_RLE(rle, header->w, GP_ABS(header->h), io);
int err;
+ GP_Pixel *palette = GP_TempAlloc(palette_size * sizeof(GP_Pixel));
+
if ((err = read_bitmap_palette(io, header, palette)))
- return err;
+ goto err;
if ((err = seek_pixels_offset(io, header)))
- return err;
+ goto err;
int cnt = 0;
@@ -289,7 +290,7 @@ static int read_RLE8(GP_IO *io, struct bitmap_info_header *header,
for (;;) {
if ((err = RLE8_next(&rle)))
- return err;
+ goto err;
if (rle.state == RLE_STOP)
break;
@@ -319,11 +320,14 @@ static int read_RLE8(GP_IO *io, struct bitmap_info_header *header,
if (GP_ProgressCallbackReport(callback, rle.y,
context->h, context->w)) {
GP_DEBUG(1, "Operation aborted");
- return ECANCELED;
+ err = ECANCELED;
+ goto err;
}
}
}
GP_ProgressCallbackDone(callback);
- return 0;
+err:
+ GP_TempFree(palette_size * sizeof(GP_Pixel), palette);
+ return err;
}
http://repo.or.cz/gfxprim.git/commit/e450ba0813517e753c32371a58aac2c9c31341…
commit e450ba0813517e753c32371a58aac2c9c3134130
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 15:22:21 2015 +0100
core: GP_ContextAlloc() add overflow detection.
Check that bpp * w * h does not overflow before we pass it to the
malloc() to allcate context bitmap buffer. Otherwise we end up with
context with w and h pointing outside the allocate pixel buffer.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/core/GP_Context.c b/libs/core/GP_Context.c
index 8e61ce0..8a6ab30 100644
--- a/libs/core/GP_Context.c
+++ b/libs/core/GP_Context.c
@@ -43,7 +43,7 @@ GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
{
GP_Context *context;
uint32_t bpp;
- uint32_t bpr;
+ size_t bpr;
void *pixels;
if (!GP_VALID_PIXELTYPE(type)) {
@@ -64,7 +64,14 @@ GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
bpp = GP_PixelSize(type);
bpr = get_bpr(bpp, w);
- pixels = malloc(bpr * h);
+ size_t size = bpr * h;
+
+ if (size / h != bpr) {
+ GP_WARN("Context too big %u x %u (owerflow detected)", w, h);
+ return NULL;
+ }
+
+ pixels = malloc(size);
context = malloc(sizeof(GP_Context));
if (pixels == NULL || context == NULL) {
http://repo.or.cz/gfxprim.git/commit/e7186b166a3c5847490637818694e61a515341…
commit e7186b166a3c5847490637818694e61a515341e4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 14:49:51 2015 +0100
Loaders: BMP: Fix two unbounded stack allocations.
Special thanks to the american fuzzy lop (afl).
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_BMP.c b/libs/loaders/GP_BMP.c
index 8b890f9..385fa3d 100644
--- a/libs/loaders/GP_BMP.c
+++ b/libs/loaders/GP_BMP.c
@@ -39,6 +39,7 @@
#include "core/GP_Debug.h"
#include "core/GP_Pixel.h"
#include "core/GP_GetPutPixel.h"
+#include "core/GP_TempAlloc.h"
#include "loaders/GP_LineConvert.h"
#include "loaders/GP_BMP.h"
@@ -366,10 +367,12 @@ static int read_bitmap_palette(GP_IO *io, struct bitmap_info_header *header,
return err;
}
- uint8_t buf[pixel_size * palette_colors];
+ uint32_t palette_size = pixel_size * palette_colors;
+ uint8_t *buf = GP_TempAlloc(palette_size);
- if (GP_IOFill(io, buf, sizeof(buf))) {
+ if (GP_IOFill(io, buf, palette_size)) {
GP_DEBUG(1, "Failed to read palette: %s", strerror(errno));
+ GP_TempFree(palette_size, buf);
return EIO;
}
@@ -384,6 +387,7 @@ static int read_bitmap_palette(GP_IO *io, struct bitmap_info_header *header,
GP_Pixel_GET_B_RGB888(palette[i]));
}
+ GP_TempFree(palette_size, buf);
return 0;
}
@@ -505,27 +509,30 @@ static int read_palette(GP_IO *io, struct bitmap_info_header *header,
GP_Context *context, GP_ProgressCallback *callback)
{
uint32_t palette_size = get_palette_size(header);
- GP_Pixel palette[get_palette_size(header)];
+ uint32_t row_size = bitmap_row_size(header);
+ int32_t y;
int err;
+ GP_TempAllocCreate(tmp, sizeof(GP_Pixel) * palette_size + row_size);
+
+ GP_Pixel *palette = GP_TempAllocArr(tmp, GP_Pixel, palette_size);
+
if ((err = read_bitmap_palette(io, header, palette)))
- return err;
+ goto err;
if ((err = seek_pixels_offset(io, header)))
- return err;
+ goto err;
- uint32_t row_size = bitmap_row_size(header);
- int32_t y;
+ uint8_t *row = GP_TempAllocArr(tmp, uint8_t, row_size);
for (y = 0; y < GP_ABS(header->h); y++) {
int32_t x;
- uint8_t row[row_size];
if (GP_IOFill(io, row, row_size)) {
err = errno;
GP_DEBUG(1, "Failed to read row %"PRId32": %s",
y, strerror(errno));
- return err;
+ goto err;
}
for (x = 0; x < header->w; x++) {
@@ -552,12 +559,15 @@ static int read_palette(GP_IO *io, struct bitmap_info_header *header,
if (GP_ProgressCallbackReport(callback, y,
context->h, context->w)) {
GP_DEBUG(1, "Operation aborted");
- return ECANCELED;
+ err = ECANCELED;
+ goto err;
}
}
GP_ProgressCallbackDone(callback);
- return 0;
+err:
+ GP_TempAllocFree(tmp);
+ return err;
}
static int read_bitfields_or_rgb(GP_IO *io, struct bitmap_info_header *header,
http://repo.or.cz/gfxprim.git/commit/b392ec017ad30463f1761a2a66c565417acc15…
commit b392ec017ad30463f1761a2a66c565417acc153d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 14:30:46 2015 +0100
core: GP_TempAlloc.c: Add simpler interface.
Add GP_TempAlloc() and GP_TempFree() to be used for single temporary
allocations.
Also adds GP_TempAllocArr(self, type, len) to allocate len size array of
type members.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/core/GP_TempAlloc.h b/include/core/GP_TempAlloc.h
index e17adff..78cfeb0 100644
--- a/include/core/GP_TempAlloc.h
+++ b/include/core/GP_TempAlloc.h
@@ -79,9 +79,20 @@ struct GP_TempAlloc {
(void*)(((char*)(self.buffer)) + _pos); \
})
+#define GP_TempAllocArr(self, type, len) \
+ GP_TempAllocGet(self, sizeof(type) * len)
+
#define GP_TempAllocFree(self) do { \
if (self.size > GP_ALLOCA_THRESHOLD) \
free(self.buffer); \
} while (0)
+#define GP_TempAlloc(size) GP_TEMP_ALLOC(size)
+
+static inline void GP_TempFree(size_t size, void *ptr)
+{
+ if (size > GP_ALLOCA_THRESHOLD)
+ free(ptr);
+}
+
#endif /* CORE_GP_TEMP_ALLOC_H */
http://repo.or.cz/gfxprim.git/commit/71461948b59b8c7e839bd3b3541678449b8c44…
commit 71461948b59b8c7e839bd3b3541678449b8c4451
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Dec 7 12:07:49 2015 +0100
lib,build: Correct static library filename.
The static library filename should apparently be without the version
string.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/Makefile b/build/Makefile
index 5f88872..13b901a 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -8,7 +8,7 @@ include $(TOPDIR)/libver.mk
LIB_NAME=libgfxprim
-STATIC_LIB=$(LIB_NAME).$(LIB_VERSION).a
+STATIC_LIB=$(LIB_NAME).a
DYNAMIC_LIB=$(LIB_NAME).so.$(LIB_VERSION).$(LIB_RELEASE)
SONAME=$(LIB_NAME).so.$(LIB_MAJOR)
SYMLINKS=$(LIB_NAME).so.$(LIB_MAJOR) $(LIB_NAME).so
diff --git a/lib.mk b/lib.mk
index 6afa462..23b7fcb 100644
--- a/lib.mk
+++ b/lib.mk
@@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk
LIB_NAME=libgfxprim-$(LIBNAME)
BUILD_DIR=$(TOPDIR)/build/
-STATIC_LIB=$(LIB_NAME).$(LIB_VERSION).a
+STATIC_LIB=$(LIB_NAME).a
DYNAMIC_LIB=$(LIB_NAME).so.$(LIB_VERSION).$(LIB_RELEASE)
SONAME=$(LIB_NAME).so.$(LIB_MAJOR)
SYMLINKS=$(LIB_NAME).so.$(LIB_MAJOR) $(LIB_NAME).so
http://repo.or.cz/gfxprim.git/commit/f83e3fc6980bd4cdc1b0151bea961ccfe35aa0…
commit f83e3fc6980bd4cdc1b0151bea961ccfe35aa006
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Sep 15 19:43:55 2015 +0200
shapetest: Fix segfault on rotation (R key)
Make use of the GP_ContextW() and GP_ContextH() accessors as changing
the backend->context->w and backend->context->h leads to undefined
behavior and crashes.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/shapetest.c b/demos/c_simple/shapetest.c
index b114fd8..14e832c 100644
--- a/demos/c_simple/shapetest.c
+++ b/demos/c_simple/shapetest.c
@@ -251,12 +251,17 @@ void redraw_screen(void)
/* axes */
if (show_axes) {
- GP_HLine(win, 0, win->w, center_y, gray);
- GP_HLine(win, 0, win->w, center_y-yradius, darkgray);
- GP_HLine(win, 0, win->w, center_y+yradius, darkgray);
- GP_VLine(win, center_x, 0, win->h, gray);
- GP_VLine(win, center_x-xradius, 0, win->h, darkgray);
- GP_VLine(win, center_x+xradius, 0, win->h, darkgray);
+ int w, h;
+
+ w = GP_ContextW(win);
+ h = GP_ContextH(win);
+
+ GP_HLine(win, 0, w, center_y, gray);
+ GP_HLine(win, 0, w, center_y-yradius, darkgray);
+ GP_HLine(win, 0, w, center_y+yradius, darkgray);
+ GP_VLine(win, center_x, 0, h, gray);
+ GP_VLine(win, center_x-xradius, 0, h, darkgray);
+ GP_VLine(win, center_x+xradius, 0, h, darkgray);
}
/* the shape */
@@ -305,7 +310,7 @@ void redraw_screen(void)
static void xradius_add(int xradius_add)
{
if (xradius + xradius_add > 1 &&
- xradius + xradius_add < (int)win->w)
+ xradius + xradius_add < (int)GP_ContextW(win))
xradius += xradius_add;
}
@@ -313,21 +318,21 @@ static void xradius_add(int xradius_add)
static void yradius_add(int yradius_add)
{
if (yradius + yradius_add > 1 &&
- yradius + yradius_add < (int)win->h)
+ yradius + yradius_add < (int)GP_ContextH(win))
yradius += yradius_add;
}
static void xcenter_add(int xcenter_add)
{
if (center_x + xcenter_add > 1 &&
- center_x + xcenter_add < (int)win->w/2)
+ center_x + xcenter_add < (int)GP_ContextW(win)/2)
center_x += xcenter_add;
}
static void ycenter_add(int ycenter_add)
{
if (center_y + ycenter_add > 1 &&
- center_y + ycenter_add < (int)win->h/2)
+ center_y + ycenter_add < (int)GP_ContextH(win)/2)
center_y += ycenter_add;
}
@@ -359,7 +364,8 @@ void event_loop(void)
break;
case GP_KEY_R:
win->axes_swap = !win->axes_swap;
- GP_SWAP(win->w, win->h);
+ center_x = GP_ContextW(win) / 2;
+ center_y = GP_ContextH(win) / 2;
break;
case GP_KEY_F:
fill = !fill;
@@ -445,8 +451,9 @@ void event_loop(void)
break;
case GP_EV_SYS_RESIZE:
GP_BackendResizeAck(backend);
- center_x = backend->context->w / 2;
- center_y = backend->context->h / 2;
+ win = backend->context;
+ center_x = GP_ContextW(win) / 2;
+ center_y = GP_ContextH(win) / 2;
break;
}
break;
http://repo.or.cz/gfxprim.git/commit/39c170a76a85408c85175b434dd0250e7b01d3…
commit 39c170a76a85408c85175b434dd0250e7b01d314
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Apr 16 12:09:25 2015 +0200
tests: framework: Call mktime() on init as well.
mktime() allocates memory that is not freed, calling it at start
avoids most of the false possitives. Unfortunatelly it reallocates
one buffer on each iteration which turns out in the final result :(
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/tests/framework/tst_preload.c b/tests/framework/tst_preload.c
index fa0a5cf..871abdf 100644
--- a/tests/framework/tst_preload.c
+++ b/tests/framework/tst_preload.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -27,6 +27,7 @@
#include <string.h>
#include <dlfcn.h>
#include <execinfo.h>
+#include <time.h>
#include "tst_test.h"
#include "tst_preload.h"
@@ -48,12 +49,23 @@ void tst_malloc_check_start(void)
{
void *buf[1];
char *str_verbose;
+
/*
* Call backtrace() before we start tracking memory, because it calls
* dlopen() on first invocation, which allocates memory that is never
* freed...
*/
backtrace(buf, 1);
+
+ /*
+ * And so does mktime(), it allocates memory which is not freed in tzset()
+ *
+ * Unfortunatelly this still leaves one chunk of size 15 that is reallocated
+ * on each call to mktime() :(
+ */
+ struct tm tm;
+ mktime(&tm);
+
check_malloc = 1;
str_verbose = getenv("TST_MALLOC_VERBOSE");
http://repo.or.cz/gfxprim.git/commit/a5731b6a1f6532ad0b6348f3b198e930ee50f3…
commit a5731b6a1f6532ad0b6348f3b198e930ee50f3ea
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Apr 16 11:04:50 2015 +0200
tests: framework: Add calloc() tracking && verbose mode
* Add calloc tracking
* Simplify realloc()
(fixes bugs with chunks added twice because realloc()
may call malloc() internally)
* Add verbose mode
The verbose mode is controlled by TST_MALLOC_VEBOSE variable.
If TST_MALLOC_VERBOSE=1 is exported all allocations with addresses are
printed.
If TST_MALLOC_VERBOSE=2 is exported the log includes also stack trace
for each allocation.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/tests/framework/tst_preload.c b/tests/framework/tst_preload.c
index 42457aa..fa0a5cf 100644
--- a/tests/framework/tst_preload.c
+++ b/tests/framework/tst_preload.c
@@ -23,14 +23,17 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
+#include <execinfo.h>
#include "tst_test.h"
#include "tst_preload.h"
#include "tst_malloc_canaries.h"
static int check_malloc = 0;
+static int verbose = 0;
static int malloc_canary = MALLOC_CANARY_OFF;
static size_t cur_size = 0;
@@ -43,23 +46,30 @@ static unsigned int max_chunks = 0;
void tst_malloc_check_start(void)
{
+ void *buf[1];
+ char *str_verbose;
+ /*
+ * Call backtrace() before we start tracking memory, because it calls
+ * dlopen() on first invocation, which allocates memory that is never
+ * freed...
+ */
+ backtrace(buf, 1);
check_malloc = 1;
+
+ str_verbose = getenv("TST_MALLOC_VERBOSE");
+ if (str_verbose)
+ verbose = atoi(str_verbose);
}
-void tst_malloc_check_stop(void)
+static void print_c_trace(void)
{
- /*
- * We cannot stop the tracing when canaries are on
- * because we need the chunk table to keep track
- * which allocations are with canary and their
- * sizes for free and realloc.
- */
- if (malloc_canary != MALLOC_CANARY_OFF) {
- tst_warn("Cannot turn malloc checks off when canaries are on");
- return;
- }
+ void *buffer[128];
+ int size = backtrace(buffer, 128);
- check_malloc = 0;
+ fprintf(stderr, "C stack trace (most recent call first):\n");
+ fflush(stderr);
+ backtrace_symbols_fd(buffer, size, fileno(stderr));
+ fprintf(stderr, "\n");
}
void tst_malloc_canaries_set(enum tst_malloc_canary canary)
@@ -102,6 +112,18 @@ struct chunk {
static struct chunk chunks[MAX_CHUNKS];
static unsigned int chunks_top = 0;
+static struct chunk *get_chunk(void *ptr)
+{
+ unsigned int i;
+
+ for (i = 0; i < chunks_top; i++) {
+ if (chunks[i].ptr == ptr)
+ return &chunks[i];
+ }
+
+ return NULL;
+}
+
static void add_chunk(size_t size, void *ptr)
{
if (chunks_top >= MAX_CHUNKS) {
@@ -110,6 +132,12 @@ static void add_chunk(size_t size, void *ptr)
return;
}
+ if (get_chunk(ptr))
+ tst_warn("Duplicate chunk addres added %p\n", ptr);
+
+ if (verbose > 1)
+ fprintf(stderr, " (adding chunk %p %6zu %i)\n", ptr, size, chunks_top);
+
/* Store chunk */
chunks[chunks_top].size = size;
chunks[chunks_top].ptr = ptr;
@@ -133,6 +161,9 @@ static void rem_chunk(void *ptr)
{
unsigned int i;
+ if (verbose > 1)
+ fprintf(stderr, " (removing chunk %p)\n", ptr);
+
for (i = 0; i < chunks_top; i++) {
if (chunks[i].ptr == ptr) {
/* Update global stats */
@@ -149,21 +180,35 @@ static void rem_chunk(void *ptr)
tst_warn("Chunk passed to free not found (%p)", ptr);
}
-static struct chunk *get_chunk(void *ptr)
+void tst_malloc_check_stop(void)
{
+ /*
+ * We cannot stop the tracing when canaries are on
+ * because we need the chunk table to keep track
+ * which allocations are with canary and their
+ * sizes for free and realloc.
+ */
+ if (malloc_canary != MALLOC_CANARY_OFF) {
+ tst_warn("Cannot turn malloc checks off when canaries are on");
+ return;
+ }
+
+ check_malloc = 0;
+
unsigned int i;
- for (i = 0; i < chunks_top; i++) {
- if (chunks[i].ptr == ptr)
- return &chunks[i];
+ if (verbose) {
+ for (i = 0; i < chunks_top; i++) {
+ fprintf(stderr, "LOST CHUNK: %p %6zu\n",
+ chunks[i].ptr, chunks[i].size);
+ }
}
-
- return NULL;
}
+static void *(*real_malloc)(size_t) = NULL;
+
void *malloc(size_t size)
{
- static void *(*real_malloc)(size_t) = NULL;
void *ptr;
if (!real_malloc)
@@ -179,13 +224,40 @@ void *malloc(size_t size)
case MALLOC_CANARY_END:
ptr = tst_malloc_canary_right(size);
break;
- /* Shut up gcc */
default:
return NULL;
}
- if (check_malloc && ptr)
+ if (check_malloc && ptr) {
+ if (verbose)
+ fprintf(stderr, "MALLOC %p\n", ptr);
+ if (verbose > 1)
+ print_c_trace();
add_chunk(size, ptr);
+ }
+
+ return ptr;
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+ static int been_here = 0;
+ void *ptr;
+
+ /*
+ * Fail calloc() before dlsym(RTLD_NEXT, "calloc") returns.
+ *
+ * The glibc seems to work with this failure just fine.
+ */
+ if (!real_malloc && been_here)
+ return NULL;
+
+ been_here = 1;
+
+ ptr = malloc(nmemb * size);
+
+ if (ptr)
+ memset(ptr, 0, nmemb * size);
return ptr;
}
@@ -221,6 +293,9 @@ void free(void *ptr)
break;
}
+ if (verbose)
+ fprintf(stderr, "FREE %p\n", ptr);
+
rem_chunk(ptr);
}
@@ -229,8 +304,8 @@ void free(void *ptr)
void *realloc(void *optr, size_t size)
{
static void *(*real_realloc)(void*, size_t) = NULL;
- struct chunk *chunk;
void *ptr;
+ struct chunk *chunk;
if (!real_realloc)
real_realloc = dlsym(RTLD_NEXT, "realloc");
@@ -238,44 +313,31 @@ void *realloc(void *optr, size_t size)
if (!optr)
return malloc(size);
- switch (malloc_canary) {
- case MALLOC_CANARY_OFF:
- ptr = real_realloc(optr, size);
- break;
- case MALLOC_CANARY_BEGIN:
- case MALLOC_CANARY_END:
- chunk = get_chunk(optr);
-
- if (!chunk) {
- tst_warn("%p allocated before checking was turned on, "
- "using using real_realloc()", optr);
-
- ptr = real_realloc(optr, size);
+ chunk = get_chunk(optr);
- goto out;
- }
+ if (!chunk) {
+ /*
+ * We don't know old size -> have to use real_realloc()
+ */
+ ptr = real_realloc(optr, size);
- ptr = malloc(size);
+ /*
+ * realloc() may call malloc(), add the chunk only if it
+ * haven't been added previously.
+ */
+ if (ptr && !get_chunk(ptr))
+ add_chunk(size, ptr);
- if (ptr) {
- memcpy(ptr, optr, min(chunk->size, size));
- free(optr);
- }
- break;
- /* Shut up gcc */
- default:
- return NULL;
+ return ptr;
}
-out:
+ ptr = malloc(size);
+
if (!ptr)
return NULL;
- if (check_malloc) {
- if (optr)
- rem_chunk(optr);
- add_chunk(size, ptr);
- }
+ memcpy(ptr, optr, min(chunk->size, size));
+ free(optr);
return ptr;
}
-----------------------------------------------------------------------
Summary of changes:
Makefile | 10 ++
app.mk | 4 +-
build/Makefile | 2 +-
demos/bogoman/Makefile | 2 +-
demos/c_simple/Makefile | 2 +-
demos/c_simple/shapetest.c | 33 ++--
demos/grinder/Makefile | 2 +-
demos/particle/Makefile | 2 +-
demos/spiv/Makefile | 2 +-
demos/ttf2img/Makefile | 2 +-
include/core/GP_TempAlloc.h | 11 ++
lib.mk | 2 +-
libs/core/GP_Context.c | 25 ++-
libs/loaders/GP_BMP.c | 52 ++++--
libs/loaders/GP_BMP_RLE.h | 33 ++--
tests/afl/.gitignore | 1 +
tests/afl/Makefile | 17 ++
.../bmp/bitmaps/valid => afl/data}/1bpp-1x1.bmp | Bin
tests/afl/data/1bpp-320x1-overlappingcolor.bmp | Bin 0 -> 102 bytes
tests/afl/data/1bpp-335x.bmp | Bin 0 -> 150 bytes
tests/afl/data/1bpp-topdown-320x2.bmp | Bin 0 -> 142 bytes
.../bmp/bitmaps/valid => afl/data}/24bpp-1x1.bmp | Bin
tests/afl/data/24bpp-323x2.bmp | Bin 0 -> 1998 bytes
tests/afl/data/24bpp-topdown-32x24.bmp | Bin 0 -> 2358 bytes
.../questionable => afl/data}/32bpp-0x240.bmp | Bin
tests/afl/data/32bpp-101110-32x24.bmp | Bin 0 -> 3138 bytes
.../bmp/bitmaps/valid => afl/data}/32bpp-1x1.bmp | Bin
.../questionable => afl/data}/32bpp-320x0.bmp | Bin
tests/afl/data/32bpp-888-optimalpalette-32x24.bmp | Bin 0 -> 3162 bytes
.../bmp/bitmaps/valid => afl/data}/4bpp-1x1.bmp | Bin
tests/afl/data/4bpp-326x2.bmp | Bin 0 -> 406 bytes
tests/afl/data/4bpp-pixeldata-cropped.bmp | Bin 0 -> 261 bytes
.../bmp/bitmaps/valid => afl/data}/555-1x1.bmp | Bin
tests/afl/data/555-pixeldata-cropped.bmp | Bin 0 -> 789 bytes
tests/afl/data/565-320x2-topdown.bmp | Bin 0 -> 1346 bytes
.../bmp/bitmaps/valid => afl/data}/8bpp-1x1.bmp | Bin
tests/afl/data/8bpp-320x2.bmp | Bin 0 -> 718 bytes
tests/afl/data/8bpp-colorsused-negative.bmp | Bin 0 -> 846 bytes
tests/afl/data/8bpp-pixels-not-in-palette.bmp | Bin 0 -> 398 bytes
tests/afl/data/bitdepth-odd.bmp | Bin 0 -> 846 bytes
tests/afl/data/bitdepth-zero.bmp | Bin 0 -> 158 bytes
tests/afl/data/colormasks-missing.bmp | Bin 0 -> 54 bytes
tests/afl/data/compression-unknown.bmp | Bin 0 -> 158 bytes
.../bmp/bitmaps/corrupt => afl/data}/emptyfile.bmp | 0
tests/afl/data/infoheader-cropped.bmp | Bin 0 -> 53 bytes
tests/afl/data/infoheadersize-large.bmp | Bin 0 -> 158 bytes
tests/afl/data/infoheadersize-small.bmp | Bin 0 -> 142 bytes
tests/afl/data/magicnumber-bad.bmp | Bin 0 -> 158 bytes
tests/afl/data/offbits-negative.bmp | Bin 0 -> 158 bytes
tests/afl/data/planes-zero.bmp | Bin 0 -> 158 bytes
tests/afl/data/rle4-encoded-320x2.bmp | Bin 0 -> 96 bytes
.../bitmaps/valid => afl/data}/rle8-64000x1.bmp | Bin
tests/afl/data/rle8-absolute-320x2.bmp | Bin 0 -> 736 bytes
tests/afl/data/rle8-absolute-cropped.bmp | Bin 0 -> 543 bytes
.../data/rle8-blank-160x1.bmp} | Bin 1080 -> 1080 bytes
.../data/rle8-delta-320x2.bmp} | Bin 1080 -> 1100 bytes
.../data/rle8-delta-cropped.bmp} | Bin 1080 -> 1229 bytes
tests/afl/data/rle8-deltaleavesimage.bmp | Bin 0 -> 428 bytes
tests/afl/data/rle8-encoded-320x2.bmp | Bin 0 -> 96 bytes
tests/afl/data/rle8-no-end-of-bitmap-marker.bmp | Bin 0 -> 422 bytes
tests/afl/data/rle8-no-end-of-line-marker.bmp | Bin 0 -> 376 bytes
tests/afl/data/rle8-runlength-cropped.bmp | Bin 0 -> 251 bytes
.../data}/ver3_0_palette_1bpp_10x10_white.pcx | Bin
.../data}/ver3_0_palette_24bpp_10x10_white.pcx | Bin
.../data}/ver3_0_palette_2bpp_10x10_white.pcx | Bin
.../data}/ver3_0_palette_4bpp_10x10_white.pcx | Bin
.../data}/ver3_0_palette_8bpp_10x10_white.pcx | Bin
tests/afl/data/width-times-height-overflow.bmp | Bin 0 -> 1602 bytes
.../loaders_example.c => tests/afl/loaders.c | 18 +--
tests/afl/run_afl.sh | 16 ++
tests/framework/tst_preload.c | 180 +++++++++++++++------
71 files changed, 295 insertions(+), 121 deletions(-)
create mode 100644 tests/afl/.gitignore
create mode 100644 tests/afl/Makefile
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/1bpp-1x1.bmp (100%)
create mode 100644 tests/afl/data/1bpp-320x1-overlappingcolor.bmp
create mode 100644 tests/afl/data/1bpp-335x.bmp
create mode 100644 tests/afl/data/1bpp-topdown-320x2.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/24bpp-1x1.bmp (100%)
create mode 100644 tests/afl/data/24bpp-323x2.bmp
create mode 100644 tests/afl/data/24bpp-topdown-32x24.bmp
copy tests/{loaders/data/bmp/bitmaps/questionable => afl/data}/32bpp-0x240.bmp (100%)
create mode 100644 tests/afl/data/32bpp-101110-32x24.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/32bpp-1x1.bmp (100%)
copy tests/{loaders/data/bmp/bitmaps/questionable => afl/data}/32bpp-320x0.bmp (100%)
create mode 100644 tests/afl/data/32bpp-888-optimalpalette-32x24.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/4bpp-1x1.bmp (100%)
create mode 100644 tests/afl/data/4bpp-326x2.bmp
create mode 100644 tests/afl/data/4bpp-pixeldata-cropped.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/555-1x1.bmp (100%)
create mode 100644 tests/afl/data/555-pixeldata-cropped.bmp
create mode 100644 tests/afl/data/565-320x2-topdown.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/8bpp-1x1.bmp (100%)
create mode 100644 tests/afl/data/8bpp-320x2.bmp
create mode 100644 tests/afl/data/8bpp-colorsused-negative.bmp
create mode 100644 tests/afl/data/8bpp-pixels-not-in-palette.bmp
create mode 100644 tests/afl/data/bitdepth-odd.bmp
create mode 100644 tests/afl/data/bitdepth-zero.bmp
create mode 100644 tests/afl/data/colormasks-missing.bmp
create mode 100644 tests/afl/data/compression-unknown.bmp
copy tests/{loaders/data/bmp/bitmaps/corrupt => afl/data}/emptyfile.bmp (100%)
create mode 100644 tests/afl/data/infoheader-cropped.bmp
create mode 100644 tests/afl/data/infoheadersize-large.bmp
create mode 100644 tests/afl/data/infoheadersize-small.bmp
create mode 100644 tests/afl/data/magicnumber-bad.bmp
create mode 100644 tests/afl/data/offbits-negative.bmp
create mode 100644 tests/afl/data/planes-zero.bmp
create mode 100644 tests/afl/data/rle4-encoded-320x2.bmp
copy tests/{loaders/data/bmp/bitmaps/valid => afl/data}/rle8-64000x1.bmp (100%)
create mode 100644 tests/afl/data/rle8-absolute-320x2.bmp
create mode 100644 tests/afl/data/rle8-absolute-cropped.bmp
copy tests/{loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp => afl/data/rle8-blank-160x1.bmp} (88%)
copy tests/{loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp => afl/data/rle8-delta-320x2.bmp} (87%)
copy tests/{loaders/data/bmp/bitmaps/valid/rle8-blank-160x120.bmp => afl/data/rle8-delta-cropped.bmp} (78%)
create mode 100644 tests/afl/data/rle8-deltaleavesimage.bmp
create mode 100644 tests/afl/data/rle8-encoded-320x2.bmp
create mode 100644 tests/afl/data/rle8-no-end-of-bitmap-marker.bmp
create mode 100644 tests/afl/data/rle8-no-end-of-line-marker.bmp
create mode 100644 tests/afl/data/rle8-runlength-cropped.bmp
copy tests/{loaders/data/pcx/valid => afl/data}/ver3_0_palette_1bpp_10x10_white.pcx (100%)
copy tests/{loaders/data/pcx/valid => afl/data}/ver3_0_palette_24bpp_10x10_white.pcx (100%)
copy tests/{loaders/data/pcx/valid => afl/data}/ver3_0_palette_2bpp_10x10_white.pcx (100%)
copy tests/{loaders/data/pcx/valid => afl/data}/ver3_0_palette_4bpp_10x10_white.pcx (100%)
copy tests/{loaders/data/pcx/valid => afl/data}/ver3_0_palette_8bpp_10x10_white.pcx (100%)
create mode 100644 tests/afl/data/width-times-height-overflow.bmp
copy demos/c_simple/loaders_example.c => tests/afl/loaders.c (82%)
create mode 100755 tests/afl/run_afl.sh
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
05 Mar '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via f7ec65e213cd4f5b98add6853202db0d6da72578 (commit)
via b660efde6e125ce8a21af032111e5d7a6edf333a (commit)
via 4c094f1071eb954f50bbd0cb12679f19aa96c933 (commit)
via aef9a4ebb755774df1edc57ab416b4943fd8dd17 (commit)
via b22cf524cd809ff41d1efb85e0012b10305ee3a8 (commit)
via 6347df8f95d78f9d3b290dca3c7ddff5b9dcb62a (commit)
via 0f4d9f51c8594de68df626ff14ce4bad2e429f86 (commit)
via bab98282d38d2f0b1526f0259d42ad7b8362e596 (commit)
from 85375ef6c62a32f40443803cfba409e0b4e56ae5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/f7ec65e213cd4f5b98add6853202db0d6da7…
commit f7ec65e213cd4f5b98add6853202db0d6da72578
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Mar 5 17:42:13 2015 +0100
install: Install headers into $INCLUDEDIR/gfxprim/
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/configure b/configure
index 57f7174..7d7a3c0 100755
--- a/configure
+++ b/configure
@@ -300,7 +300,7 @@ def write_gfxprim_config(cfg, libs):
# General switches cflags and ldflags
f.write('\t--help) echo "$USAGE"; exit 0;;\n')
f.write('\t--list-modules) echo "%s"; exit 0;;\n' % ' '.join(modules))
- f.write('\t--cflags) echo -n "-I/usr/include/GP/%s";;\n' %
+ f.write('\t--cflags) echo -n "-I/usr/include/gfxprim/%s";;\n' %
libs.get_cflags('core'))
f.write('\t--libs) echo -n "-lgfxprim -lrt -lm %s ";;\n' % libs.get_linker_flags('core'))
diff --git a/install.sh b/install.sh
index dbb2ca8..80a8ef3 100755
--- a/install.sh
+++ b/install.sh
@@ -11,15 +11,15 @@ BIN_LOC="${DESTDIR}/$BINDIR"
# Headers
echo "INSTALL headers ($HEADER_LOC)"
-install -m 775 -d "${HEADER_LOC}/GP"
+install -m 775 -d "${HEADER_LOC}/gfxprim"
for i in `ls include/`; do
if [ -d "include/$i" ]; then
echo " $i"
- install -m 775 -d "${HEADER_LOC}/GP/$i"
- install -m 664 "include/$i/"*.h "${HEADER_LOC}/GP/$i"
+ install -m 775 -d "${HEADER_LOC}/gfxprim/$i"
+ install -m 664 "include/$i/"*.h "${HEADER_LOC}/gfxprim/$i"
else
if [ "$i" != "Makefile" ]; then
- install -m 664 "include/$i" "${HEADER_LOC}/GP/$i"
+ install -m 664 "include/$i" "${HEADER_LOC}/gfxprim/$i"
fi
fi
done
http://repo.or.cz/w/gfxprim.git/commit/b660efde6e125ce8a21af032111e5d7a6edf…
commit b660efde6e125ce8a21af032111e5d7a6edf333a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 21:18:17 2015 +0100
tests: loaders: DataStorage: Add tests for GetByPath
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/tests/loaders/DataStorage.c b/tests/loaders/DataStorage.c
index 16ffcae..ba5e6bf 100644
--- a/tests/loaders/DataStorage.c
+++ b/tests/loaders/DataStorage.c
@@ -200,6 +200,87 @@ static int wrong_type_add(void)
return TST_SUCCESS;
}
+static int get_by_path(void)
+{
+ GP_DataStorage *storage;
+ GP_DataNode *ret, *res;
+ int fail = 0;
+
+ storage = GP_DataStorageCreate();
+
+ if (!storage)
+ return TST_FAILED;
+
+ GP_DataNode data = {
+ .type = GP_DATA_STRING,
+ .id = "string",
+ .value.str = "test string",
+ };
+
+ ret = GP_DataStorageAdd(storage, NULL, &data);
+
+ if (!ret) {
+ tst_msg("DataStorageAdd() failed");
+ GP_DataStorageDestroy(storage);
+ return TST_FAILED;
+ }
+
+ /* Global path */
+ res = GP_DataStorageGetByPath(storage, NULL, "/string");
+
+ if (res != ret) {
+ tst_msg("DataStorageGetByPath(storage, NULL, '/string')");
+ fail++;
+ }
+
+ /* Local path */
+ res = GP_DataStorageGetByPath(NULL, GP_DataStorageRoot(storage), "string");
+
+ if (res != ret) {
+ tst_msg("DataStorageGetByPath(NULL, root, 'string')");
+ fail++;
+ }
+
+ /* Non existing in global path */
+ res = GP_DataStorageGetByPath(storage, NULL, "/does-not-exist");
+
+ if (res) {
+ tst_msg("DataStorageGetByPath(storage, NULL, '/does-not-exist')");
+ fail++;
+ }
+
+ /* Non existing in local path */
+ res = GP_DataStorageGetByPath(NULL, GP_DataStorageRoot(storage), "does-not-exist");
+
+ if (res) {
+ tst_msg("DataStorageGetByPath(NULL, root, 'does-not-exist')");
+ fail++;
+ }
+
+ /* Empty dict for local path */
+ res = GP_DataStorageGetByPath(NULL, NULL, "does-not-exist");
+
+ if (res) {
+ tst_msg("DataStorageGetByPath(NULL, NULL, 'does-not-exist')");
+ fail++;
+ }
+
+ /* Empty storage for global path */
+ res = GP_DataStorageGetByPath(NULL, NULL, "/does-not-exist");
+
+ if (res) {
+ tst_msg("DataStorageGetByPath(NULL, NULL, '/does-not-exist')");
+ fail++;
+ }
+
+ GP_DataStorageDestroy(storage);
+
+ if (fail)
+ return TST_FAILED;
+
+ return TST_SUCCESS;
+}
+
const struct tst_suite tst_suite = {
.suite_name = "Data Storage",
.tests = {
@@ -223,6 +304,10 @@ const struct tst_suite tst_suite = {
.tst_fn = wrong_type_add,
.flags = TST_CHECK_MALLOC},
+ {.name = "GP_DataStorageGetByPath()",
+ .tst_fn = get_by_path,
+ .flags = TST_CHECK_MALLOC},
+
{.name = NULL},
}
};
http://repo.or.cz/w/gfxprim.git/commit/4c094f1071eb954f50bbd0cb12679f19aa96…
commit 4c094f1071eb954f50bbd0cb12679f19aa96c933
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 20:34:57 2015 +0100
libs: loaders: DataStorage: Fix duplicate node add
Print warning and return when trying to add a node with duplicate id.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_DataStorage.c b/libs/loaders/GP_DataStorage.c
index b453bea..9210d72 100644
--- a/libs/loaders/GP_DataStorage.c
+++ b/libs/loaders/GP_DataStorage.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2014 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -254,6 +254,7 @@ GP_DataNode *GP_DataStorageAdd(GP_DataStorage *self,
GP_DataNode *node, GP_DataNode *data)
{
struct record *rec;
+ struct GP_DataNode *dup;
GP_DEBUG(2, "Adding '%s' to storage (%p)", data->id, self);
@@ -263,6 +264,14 @@ GP_DataNode *GP_DataStorageAdd(GP_DataStorage *self,
return NULL;
}
+ dup = GP_DataStorageGet(self, node, data->id);
+
+ if (dup) {
+ GP_WARN("Trying to insert allready existing node '%s'",
+ data->id);
+ return NULL;
+ }
+
rec = new_record(self, data);
if (!rec)
http://repo.or.cz/w/gfxprim.git/commit/aef9a4ebb755774df1edc57ab416b4943fd8…
commit aef9a4ebb755774df1edc57ab416b4943fd8dd17
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 20:28:56 2015 +0100
core: Debug: Do not print trace on WARNING for now
The thing is that backtrace() calls __libc_dlopen() that allocates
memory, which is then freed at the end of the program.
That causes false possitives memleaks for tests that trigger WARNING.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/core/GP_Debug.c b/libs/core/GP_Debug.c
index 011b604..4fbecdc 100644
--- a/libs/core/GP_Debug.c
+++ b/libs/core/GP_Debug.c
@@ -112,7 +112,6 @@ void GP_DebugPrint(int level, const char *file, const char *function, int line,
fprintf(stderr, "*** BUG: %s:%s():%u: ", file, function, line);
break;
case GP_DEBUG_WARN:
- GP_DebugPrintCStack();
fprintf(stderr, "*** WARNING: %s:%s():%u: ", file, function, line);
break;
case GP_DEBUG_TODO:
http://repo.or.cz/w/gfxprim.git/commit/b22cf524cd809ff41d1efb85e0012b10305e…
commit b22cf524cd809ff41d1efb85e0012b10305ee3a8
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 19:32:35 2015 +0100
tests: framework: log2html.py: Fix malloc stats
The number of chunks is just number not Bytes.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/tests/framework/log2html.py b/tests/framework/log2html.py
index c1dac38..fd3bd8f 100755
--- a/tests/framework/log2html.py
+++ b/tests/framework/log2html.py
@@ -94,7 +94,7 @@ class MallocStats:
print(' <td bgcolor="#ffffaa">')
print(' <center><small>%s</small></center>' %
- bytes_conv(self.total_chunks))
+ self.total_chunks)
print(' </td>')
print(' <td bgcolor="#ffffaa">')
@@ -104,7 +104,7 @@ class MallocStats:
print(' <td bgcolor="#ffffaa">')
print(' <center><small>%s</small></center>' %
- bytes_conv(self.max_chunks))
+ self.max_chunks)
print(' </td>')
print(' <td bgcolor="#ffffaa">')
@@ -114,7 +114,7 @@ class MallocStats:
print(' <td bgcolor="#ffffaa">')
print(' <center><small>%s</small></center>' %
- bytes_conv(self.lost_chunks))
+ self.lost_chunks)
print(' </td>')
print(' </tr>')
http://repo.or.cz/w/gfxprim.git/commit/6347df8f95d78f9d3b290dca3c7ddff5b9dc…
commit 6347df8f95d78f9d3b290dca3c7ddff5b9dcb62a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 18:35:24 2015 +0100
demos: py_simple: gfx.py: Handle SYS_RESIZE event
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/py_simple/gfx.py b/demos/py_simple/gfx.py
index 81d78b3..c79d879 100755
--- a/demos/py_simple/gfx.py
+++ b/demos/py_simple/gfx.py
@@ -93,10 +93,10 @@ def polygon(bk):
polygon = [(10, 10), (10, (h-10)//3), ((w-10)//3, (h-10)//2),
(10, 2*(h-10)//3), (10, h-10), ((w-10)//3, h-10),
- ((w-10)//2, 2*(h-10)//3), (2*(w-10)//3, h-10),
+ ((w-10)//2, 2*(h-10)//3), (2*(w-10)//3, h-10),
(w-10, h-10), (w-10, 2*(h-10)//3), (2*(w-10)//3, (h-10)//2),
- (w-10, (h-10)//3), (w-10, 10), (2*(w-10)//3, 10),
- ((w-10)//2, (h-10)//3), ((w-10)//3, 10)]
+ (w-10, (h-10)//3), (w-10, 10), (2*(w-10)//3, 10),
+ ((w-10)//2, (h-10)//3), ((w-10)//3, 10)]
bk.context.gfx.Polygon(polygon, fg)
@@ -162,6 +162,10 @@ def main():
if (ev.type == input.EV_SYS):
if (ev.code == input.EV_SYS_QUIT):
sys.exit(0)
+ elif (ev.code == input.EV_SYS_RESIZE):
+ bk.ResizeAck()
+ fill(bk)
+ bk.Flip()
if __name__ == '__main__':
main()
http://repo.or.cz/w/gfxprim.git/commit/0f4d9f51c8594de68df626ff14ce4bad2e42…
commit 0f4d9f51c8594de68df626ff14ce4bad2e429f86
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 18:28:10 2015 +0100
gfx: Remove FillRect_AA
It never worked anyway.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/GFX_symbols.txt b/build/syms/GFX_symbols.txt
index c3566ae..3ffccdc 100644
--- a/build/syms/GFX_symbols.txt
+++ b/build/syms/GFX_symbols.txt
@@ -109,11 +109,6 @@ GP_PutPixelAA_Raw_Clipped
GP_ArcSegment
GP_ArcSegment_Raw
-GP_FillRectXYXY_AA
-GP_FillRectXYXY_AA_Raw
-GP_FillRectXYWH_AA
-GP_FillRectXYWH_AA_Raw
-
GP_AngleInRange
GP_NormalizeAngle
diff --git a/include/gfx/GP_Gfx.h b/include/gfx/GP_Gfx.h
index f0ed470..5b7e286 100644
--- a/include/gfx/GP_Gfx.h
+++ b/include/gfx/GP_Gfx.h
@@ -55,6 +55,5 @@
#include "GP_VLineAA.h"
#include "GP_HLineAA.h"
#include "GP_LineAA.h"
-#include "GP_RectAA.h"
#endif /* GP_GFX_H */
diff --git a/include/gfx/GP_RectAA.h b/include/gfx/GP_RectAA.h
deleted file mode 100644
index fc6d9e9..0000000
--- a/include/gfx/GP_RectAA.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#ifndef GFX_GP_RECT_AA_H
-#define GFX_GP_RECT_AA_H
-
-#include "core/GP_Context.h"
-
-/* Filled Rectangle */
-
-void GP_FillRectXYXY_AA(GP_Context *context, GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
-
-void GP_FillRectXYXY_AA_Raw(GP_Context *context, GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
-
-void GP_FillRectXYWH_AA(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size w, GP_Size h, GP_Pixel pixel);
-
-void GP_FillRectXYWH_AA_Raw(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size w, GP_Size h, GP_Pixel pixel);
-
-/* The XYXY argument set is the default */
-static inline void GP_FillRect_AA(GP_Context *context, GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
-{
- GP_FillRectXYXY_AA(context, x0, y0, x1, y1, pixel);
-}
-
-static inline void GP_FillRect_AA_Raw(GP_Context *context,
- GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
-{
- GP_FillRectXYXY_AA_Raw(context, x0, y0, x1, y1, pixel);
-}
-
-#endif /* GFX_GP_RECT_AA_H */
diff --git a/libs/gfx/GP_RectAA.c b/libs/gfx/GP_RectAA.c
deleted file mode 100644
index 6026cad..0000000
--- a/libs/gfx/GP_RectAA.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include "core/GP_Transform.h"
-#include "core/GP_GetPutPixel.h"
-#include "core/GP_MixPixels.h"
-#include "core/GP_FixedPoint.h"
-#include "core/GP_GammaCorrection.h"
-#include "GP_Rect.h"
-#include "GP_RectAA.h"
-
-void GP_FillRectXYXY_AA_Raw(GP_Context *context, GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
-{
- GP_CHECK_CONTEXT(context);
-
- if (x0 > x1)
- GP_SWAP(x0, x1);
-
- if (y0 > y1)
- GP_SWAP(y0, y1);
-
- /* Outer coordinates */
- GP_Coord out_x0 = GP_FP_FLOOR_TO_INT(x0 + GP_FP_1_2);
- GP_Coord out_y0 = GP_FP_FLOOR_TO_INT(y0 + GP_FP_1_2);
- GP_Coord out_x1 = GP_FP_CEIL_TO_INT(x1 - GP_FP_1_2);
- GP_Coord out_y1 = GP_FP_CEIL_TO_INT(y1 - GP_FP_1_2);
-
- /* Size */
- GP_Size w = x1 - x0;
- GP_Size h = y1 - y0;
-
- /* Special case, vertical 1px line */
- if (out_x0 == out_x1) {
- uint8_t mix = w;
- GP_Coord i;
-
- /* Special case 1px 100% width line */
- if (w == GP_FP_1)
- mix = 255;
-
- for (i = out_y0; i <= out_y1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x0, i);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, out_x0, i, p);
- }
-
- return;
- }
-
- /* Special case, horizontal 1px line */
- if (out_y0 == out_y1) {
- uint8_t mix = w;
- GP_Coord i;
-
- /* Special case 1px 100% height line */
- if (h == GP_FP_1)
- mix = 255;
-
- for (i = out_x0; i <= out_x1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y0);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, i, out_y0, p);
- }
-
- return;
- }
-
- /* This are integer coordinates of the "inner" rectangle */
- GP_Coord in_x0 = GP_FP_CEIL_TO_INT(x0 + GP_FP_1_2);
- GP_Coord in_y0 = GP_FP_CEIL_TO_INT(y0 + GP_FP_1_2);
- GP_Coord in_x1 = GP_FP_FLOOR_TO_INT(x1 - GP_FP_1_2);
- GP_Coord in_y1 = GP_FP_FLOOR_TO_INT(y1 - GP_FP_1_2);
-
- /*
- * Draw the inner rectanle in 100% intensity.
- *
- * Note that if out_x0 == in_x1 is 2px wide and both lines has less than
- * 100% intensity. The same goes for out_y0 == in_y1.
- */
- if (in_x1 >= in_x0 && (out_x0 != in_x1 || out_x1 != in_x0)
- && in_y1 >= in_y0 && (out_y0 != in_y1 || out_y1 != in_y0))
- GP_FillRectXYXY_Raw(context, in_x0, in_y0, in_x1, in_y1, pixel);
-
- /* if the outer and innter coordinates doesn't match, draw blurred edge */
- if (in_y0 != out_y0) {
- uint8_t mix = GP_FP_FROM_INT(in_y0) + GP_FP_1_2 - y0;
- GP_Coord i;
-
- for (i = out_x0; i <= out_x1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y0);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, i, out_y0, p);
- }
- }
-
- if (in_y1 != out_y1) {
- uint8_t mix = y1 - GP_FP_FROM_INT(in_y0) - GP_FP_1_2;
- GP_Coord i;
-
- for (i = out_x0; i <= out_x1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y1);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, i, out_y1, p);
- }
- }
-
- if (in_x0 != out_x0) {
- uint8_t mix = GP_FP_FROM_INT(in_x0) + GP_FP_1_2 - x0;
- GP_Coord i;
-
- for (i = out_y0; i <= out_y1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x0, i);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, out_x0, i, p);
- }
- }
-
- if (in_x1 != out_x1) {
- uint8_t mix = x1 - GP_FP_FROM_INT(in_x1) - GP_FP_1_2;
- GP_Coord i;
-
- for (i = out_y0; i <= out_y1; i++) {
- GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x1, i);
- p = GP_MixPixels(pixel, p, mix, context->pixel_type);
- GP_PutPixel_Raw_Clipped(context, out_x1, i, p);
- }
- }
-
- //TODO four corner pixels!!!
-}
-
-void GP_FillRectXYWH_AA_Raw(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size w, GP_Size h, GP_Pixel pixel)
-{
- if (w == 0 || h == 0)
- return;
-
- GP_FillRectXYXY_AA_Raw(context, x, y,
- x + w - GP_FP_1, y + h - GP_FP_1, pixel);
-}
-
-void GP_FillRectXYXY_AA(GP_Context *context, GP_Coord x0, GP_Coord y0,
- GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
-{
- GP_CHECK_CONTEXT(context);
-
- GP_TRANSFORM_POINT_FP(context, x0, y0);
- GP_TRANSFORM_POINT_FP(context, x1, y1);
-
- GP_FillRectXYXY_AA_Raw(context, x0, y0, x1, y1, pixel);
-}
-
-void GP_FillRectXYWH_AA(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size w, GP_Size h, GP_Pixel pixel)
-{
- if (w == 0 || h == 0)
- return;
-
- GP_FillRectXYXY_AA(context, x, y,
- x + w - GP_FP_1, y + h - GP_FP_1, pixel);
-}
diff --git a/pylib/gfxprim/gfx/__init__.py b/pylib/gfxprim/gfx/__init__.py
index daf99e1..5c92d66 100644
--- a/pylib/gfxprim/gfx/__init__.py
+++ b/pylib/gfxprim/gfx/__init__.py
@@ -37,7 +37,7 @@ def _init(module):
for name in [
'ArcSegment', 'Circle', 'Ellipse', 'FillCircle', 'FillEllipse',
- 'FillRect', 'FillRect_AA', 'FillRing',
+ 'FillRect', 'FillRing',
'FillTetragon', 'FillTriangle', 'HLine', 'HLineAA', 'Line', 'LineAA',
'PutPixelAA', 'Rect', 'Ring', 'Tetragon',
'Triangle', 'VLine', 'VLineAA']:
diff --git a/pylib/gfxprim/gfx/gfx.i b/pylib/gfxprim/gfx/gfx.i
index e09e633..5e4f447 100644
--- a/pylib/gfxprim/gfx/gfx.i
+++ b/pylib/gfxprim/gfx/gfx.i
@@ -27,7 +27,6 @@
%include "GP_VLineAA.h"
%include "GP_HLineAA.h"
%include "GP_LineAA.h"
-%include "GP_RectAA.h"
%inline %{
static GP_Coord *GP_Polygon_unpack_coordinates(PyObject *coords)
diff --git a/tests/pylib/test_gfx.py b/tests/pylib/test_gfx.py
index 292202a..b9314b2 100644
--- a/tests/pylib/test_gfx.py
+++ b/tests/pylib/test_gfx.py
@@ -30,7 +30,6 @@ gfx_params = {
'FillEllipse': 'IIIIP',
'FillPolygon': ([(0,0),(1,1),(1,0)], 0, {}),
'FillRect': 'IIIIP',
- 'FillRect_AA': 'IIIIP', # Fixpoint, originally 'FFFFP'
'FillRing': 'IIIIP',
'FillTetragon': 'IIIIIIIIP',
'FillTriangle': 'IIIIIIP',
http://repo.or.cz/w/gfxprim.git/commit/bab98282d38d2f0b1526f0259d42ad7b8362…
commit bab98282d38d2f0b1526f0259d42ad7b8362e596
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 18:11:46 2015 +0100
demos; c_simple: randomshapetest: Fixes
* Remove AA rectangle
* Handle SYS_RESIZE event
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/randomshapetest.c b/demos/c_simple/randomshapetest.c
index e5f4e5d..6b970f0 100644
--- a/demos/c_simple/randomshapetest.c
+++ b/demos/c_simple/randomshapetest.c
@@ -44,8 +44,7 @@ static int pause_flag = 0;
#define SHAPE_RECTANGLE 4
#define SHAPE_TETRAGON 5
#define SHAPE_POLYGON 6
-#define SHAPE_RECTANGLE_AA 7
-#define SHAPE_LAST 7
+#define SHAPE_LAST 6
static int shape = SHAPE_FIRST;
/* Draw outlines? */
@@ -155,20 +154,6 @@ void draw_random_polygon(GP_Pixel pixel)
GP_FillPolygon_Raw(win->context, 5, xy, pixel);
}
-void draw_random_rectangle_AA(GP_Pixel pixel)
-{
- int x0, y0, x1, y1;
- random_point_AA(win->context, &x0, &y0);
- random_point_AA(win->context, &x1, &y1);
-
-// if (fill_flag)
- GP_FillRect_AA(win->context, x0, y0, x1, y1, pixel);
-
-// if (outline_flag)
-// GP_Rect(win->context, x0, y0, x1, y1, white);
-}
-
-
void clear_screen(void)
{
GP_Fill(win->context, black);
@@ -204,9 +189,6 @@ void redraw_screen(void)
case SHAPE_POLYGON:
draw_random_polygon(pixel);
break;
- case SHAPE_RECTANGLE_AA:
- draw_random_rectangle_AA(pixel);
- break;
}
}
@@ -252,6 +234,14 @@ void event_loop(void)
exit(0);
break;
}
+ break;
+ case GP_EV_SYS:
+ if (ev.code == GP_EV_SYS_RESIZE) {
+ GP_BackendResizeAck(win);
+ clear_screen();
+ GP_BackendFlip(win);
+ }
+ break;
}
}
}
-----------------------------------------------------------------------
Summary of changes:
build/syms/GFX_symbols.txt | 5 -
configure | 2 +-
demos/c_simple/randomshapetest.c | 28 ++----
demos/py_simple/gfx.py | 10 ++-
include/gfx/GP_Gfx.h | 1 -
include/gfx/GP_RectAA.h | 56 ------------
install.sh | 8 +-
libs/core/GP_Debug.c | 1 -
libs/gfx/GP_RectAA.c | 181 --------------------------------------
libs/loaders/GP_DataStorage.c | 11 ++-
pylib/gfxprim/gfx/__init__.py | 2 +-
pylib/gfxprim/gfx/gfx.i | 1 -
tests/framework/log2html.py | 6 +-
tests/loaders/DataStorage.c | 85 ++++++++++++++++++
tests/pylib/test_gfx.py | 1 -
15 files changed, 120 insertions(+), 278 deletions(-)
delete mode 100644 include/gfx/GP_RectAA.h
delete mode 100644 libs/gfx/GP_RectAA.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
08 Feb '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 85375ef6c62a32f40443803cfba409e0b4e56ae5 (commit)
via 37c29279ba0395d957597f60325545fba9d4fcf2 (commit)
from 254ab1bb2cf59cfef000a55e64837a89e35e4008 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/85375ef6c62a32f40443803cfba409e0b4e5…
commit 85375ef6c62a32f40443803cfba409e0b4e56ae5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 17:50:58 2015 +0100
loaders: Exif: Fix rational loading
Arrays are TODO!
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.c
index e11f72e..04b3d85 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.c
@@ -186,29 +186,15 @@ add:
static int load_rat(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
const char *id, uint32_t num_comp, uint32_t val)
{
- (void)io;(void)storage;(void)node;(void)id;(void)num_comp;(void)val;
- return GP_DataStorageAddRational(storage, node, id, 0, 0) != NULL;
-}
-
-/*
-static int rat_num(void *buf, uint32_t offset, size_t buf_len, int swap)
-{
- int ret;
+ size_t max_comps = GP_MIN(num_comp, 32u);
+ uint32_t buf[2 * max_comps];
- GET_32(ret, buf, offset, buf_len, swap);
-
- return ret;
-}
-
-static int rat_den(void *buf, uint32_t offset, size_t buf_len, int swap)
-{
- int ret;
-
- GET_32(ret, buf, offset + 4, buf_len, swap);
+ if (get_buf(io, val + 6, (void*)buf, num_comp * 8))
+ return 1;
- return ret;
+ //TODO: Data Storage needs array
+ return GP_DataStorageAddRational(storage, node, id, buf[0], buf[1]) != NULL;
}
-*/
static int load_tag(GP_IO *io, GP_DataStorage *storage,
GP_DataNode* node, const struct IFD_tags *taglist,
@@ -228,6 +214,7 @@ static int load_tag(GP_IO *io, GP_DataStorage *storage,
"expected '%s' in %s block", res->name,
IFD_format_name(format), format,
IFD_format_name(res->format), taglist->id);
+ //TODO: Load and convert!
}
if ((res->num_components != 0) &&
http://repo.or.cz/w/gfxprim.git/commit/37c29279ba0395d957597f60325545fba9d4…
commit 37c29279ba0395d957597f60325545fba9d4fcf2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 17:42:44 2015 +0100
loaders: Exif: Limit number of subrecords
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.c
index 0cfd591..e11f72e 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.c
@@ -324,7 +324,7 @@ static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
GP_DEBUG(2, "-- IFD Offset 0x%08x Entries %04u --",
IFD_offset, IFD_entries_count);
- struct IFD_subrecord subrecs[IFD_entries_count];
+ struct IFD_subrecord subrecs[4];
unsigned int subrec_cnt = 0;
for (i = 0; i < IFD_entries_count; i++) {
@@ -346,6 +346,10 @@ static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
case IFD_EXIF_OFFSET:
case IFD_GPS_OFFSET:
case IFD_INTEROPERABILITY_OFFSET:
+ if (subrec_cnt >= GP_ARRAY_SIZE(subrecs)) {
+ GP_WARN("Too much subrecords, skipping one");
+ continue;
+ }
subrecs[subrec_cnt].tag = tag;
subrecs[subrec_cnt].offset = val;
subrec_cnt++;
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_Exif.c | 33 ++++++++++++---------------------
1 files changed, 12 insertions(+), 21 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
08 Feb '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 254ab1bb2cf59cfef000a55e64837a89e35e4008 (commit)
via 76e4c74a3e527af4fe39c98123d4475a1ddc2a05 (commit)
from 143e4e08779b9dcd3aeed69e2de28c64d9c3d4d0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/254ab1bb2cf59cfef000a55e64837a89e35e…
commit 254ab1bb2cf59cfef000a55e64837a89e35e4008
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 17:00:23 2015 +0100
loaders: DataStorage: Print strings enclosed in ''
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_DataStorage.c b/libs/loaders/GP_DataStorage.c
index cb02425..b453bea 100644
--- a/libs/loaders/GP_DataStorage.c
+++ b/libs/loaders/GP_DataStorage.c
@@ -411,7 +411,7 @@ static void data_print(const GP_DataNode *node,
node->value.rat.num, node->value.rat.den);
break;
case GP_DATA_STRING:
- padd_printf(padd, node->id, id_padd, " : %sn", node->value.str);
+ padd_printf(padd, node->id, id_padd, " : '%s'n", node->value.str);
break;
case GP_DATA_DICT:
padd_printf(padd, node->id ? node->id : "Data Root", 0, " = {n");
http://repo.or.cz/w/gfxprim.git/commit/76e4c74a3e527af4fe39c98123d4475a1ddc…
commit 76e4c74a3e527af4fe39c98123d4475a1ddc2a05
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 15:49:27 2015 +0100
loaders: Exif: Fix subIFD handling, add subIFDs
* Add interoperability and GPS sub IFD handling
* Add a few more tags
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.c
index 99f49f7..0cfd591 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.c
@@ -24,9 +24,9 @@
#include <string.h>
#include <errno.h>
-#include "core/GP_Debug.h"
-
-#include "loaders/GP_Exif.h"
+#include <core/GP_Common.h>
+#include <core/GP_Debug.h>
+#include <loaders/GP_Exif.h>
enum IFD_formats {
/* 1 bytes/components */
@@ -71,133 +71,13 @@ static const char *IFD_format_names[] = {
"Double Float",
};
-enum IFD_tags {
- /* Image width and height */
- IFD_IMAGE_WIDTH = 0x0100,
- IFD_IMAGE_HEIGHT = 0x0101,
-
- IFD_BITS_PER_SAMPLE = 0x0102,
-
- /* TODO: enum of compressions */
- IFD_COMPRESSION = 0x0103,
- /* TODO: enum of interpretations */
- IFD_PHOTOMETRIC_INTERPRETATION = 0x0106,
-
- /* ASCII text no multibyte encoding */
- IFD_IMAGE_DESCRIPTION = 0x010e,
- /* Device (camer, scanner, ...) manufacturer */
- IFD_MAKE = 0x010f,
- /* Device model */
- IFD_MODEL = 0x0110,
- /* Image orientation *
- * 1 upper left, 3 lower right, 6 upper right, *
- * 8 lower left, other reserved */
- IFD_ORIENTATION = 0x0112,
- /* X resolution 72 DPI is default */
- IFD_X_RESOLUTION = 0x011a,
- /* Y resolution 72 DPI is default */
- IFD_Y_RESOLUTION = 0x011b,
- /* 1 = Chunky, 2 = Planar */
- IFD_PLANAR_CONFIGURATION = 0x011c,
- /* 1 = No unit, 2 = Inch (default), 3 = Centimeter */
- IFD_RESOLUTION_UNIT = 0x0128,
- /* Software string. */
- IFD_SOFTWARE = 0x0131,
- /* YYYY:MM:DD HH:MM:SS in 24 hours format */
- IFD_DATE_TIME = 0x0132,
- /* White Point */
- IFD_WHITE_POINT = 0x013e,
- /* Primary Chromaticies */
- IFD_PRIMARY_CHROMATICIES = 0x013f,
- /* YCbCr Coefficients */
- IFD_Y_CB_CR_COEFFICIENTS = 0x0211,
- /* YCbCr Positioning */
- IFD_Y_CB_CR_POSITIONING = 0x0213,
- /* Reference Black White */
- IFD_REFERENCE_BLACK_WHITE = 0x0214,
- /* Copyright */
- IFD_COPYRIGHT = 0x8298,
- /* Exif SubIFD Offset */
- IFD_EXIF_OFFSET = 0x8769,
-
- /* TAGs from Exif SubIFD */
- IFD_EXPOSURE_TIME = 0x829a,
- /* Actual F-Number of lens when image was taken */
- IFD_F_NUMBER = 0x829d,
- /* 1 manual, 2 normal, 3 aperture priority, 4 shutter priority, *
- * 5 creative (slow), 6 action (high-speed), 7 portrait mode, *
- * 8 landscape mode */
- IFD_EXPOSURE_PROGRAM = 0x8822,
- /* CCD sensitivity */
- IFD_ISO_SPEED_RATINGS = 0x8827,
- /* ASCII 4 byte Exif version */
- IFD_EXIF_VERSION = 0x9000,
- /* Original time should not be modified by user program */
- IFD_DATE_TIME_ORIGINAL = 0x9003,
- IFD_DATE_TIME_DIGITIZED = 0x9004,
- /* Undefined commonly 0x00, 0x01, 0x02, 0x03 */
- IFD_COMPONENT_CONFIGURATION = 0x9101,
- /* Average compression ration */
- IFD_COMPRESSED_BITS_PER_PIXEL = 0x9102,
- /* Shutter speed as 1 / (2 ^ val) */
- IFD_SHUTTER_SPEED_VALUE = 0x9201,
- /* Aperture to convert to F-Number do 1.4142 ^ val */
- IFD_APERTURE_VALUE = 0x9202,
- /* Brightness in EV */
- IFD_BRIGHTNESS_VALUE = 0x9203,
- /* Exposure bias in EV */
- IFD_EXPOSURE_BIAS_VALUE = 0x9204,
- /* Max Aperture in the same format as IFD_APERTURE_VALUE */
- IFD_MAX_APERTURE_VALUE = 0x9205,
- /* Distance to focus point in meters */
- IFD_SUBJECT_DISTANCE = 0x9206,
- /* Exposure metering method, 1 average, 2 center weighted average, *
- * 3 spot, 4 multi-spot, 5 multi-segment */
- IFD_METERING_MODE = 0x9207,
- /* White balance 0 auto, 1 daylight, 2 flourescent, 3 tungsten, 10 flash */
- IFD_LIGHT_SOURCE = 0x9208,
- /* 0 off, 1 on */
- IFD_FLASH = 0x9209,
- /* Focal length in milimeters */
- IFD_FOCAL_LENGTH = 0x920a,
- /* Maker note, undefined may be IFD block */
- IFD_MAKER_NOTE = 0x927c,
- /* Comment */
- IFD_USER_COMMENT = 0x9286,
-
- /* Stores FlashPix version, undefined, may be four ASCII numbers */
- IFD_FLASH_PIX_VERSION = 0xa000,
- /* Unknown may be 1 */
- IFD_COLOR_SPACE = 0xa001,
- /* Exif Image Width and Height */
- IFD_EXIF_IMAGE_WIDTH = 0xa002,
- IFD_EXIF_IMAGE_HEIGHT = 0xa003,
- /* May store related audio filename */
- IFD_RELATED_SOUND_FILE = 0xa004,
- /* */
- IFD_FOCAL_PLANE_X_RESOLUTION = 0xa20e,
- IFD_FOCAL_PLANE_Y_RESOLUTION = 0xa20f,
- /* 1 = No unit, 2 = Inch (default), 3 = Centimeter */
- IFD_FOCAL_PLANE_RESOLUTION_UNIT = 0xa210,
- /* TODO: enum of sensing methods */
- IFD_SENSING_METHOD = 0xa217,
- IFD_FILE_SOURCE = 0xa300,
- IFD_SCENE_TYPE = 0xa301,
- /* 0 = Normal, 1 = Custom */
- IFD_CUSTOM_RENDERER = 0xa401,
- /* 0 = Auto, 1 = Manual, 2 = Auto bracket */
- IFD_EXPOSURE_MODE = 0xa402,
- /* 0 = Auto, 1 = Manual */
- IFD_WHITE_BALANCE = 0xa403,
- /* 0 = Standard, 1 = Landscape, 2 = Portrait, 3 = Night Scene */
- IFD_SCENE_CAPTURE_TYPE = 0xa406,
- /* 0 = Normal, 1 = Soft, 2 = Hard */
- IFD_CONTRAST = 0xa408,
- /* 0 = Normal, 1 = Low Saturation, 2 = Hight Saturation */
- IFD_SATURATION = 0xa409,
- /* 0 = Normal, 1 = Sort, 2 = Hard */
- IFD_SHARPNESS = 0xa40a,
-};
+static const char *IFD_format_name(uint16_t format)
+{
+ if (format == 0 || format > IFD_FORMAT_LAST)
+ return "Unknown";
+
+ return IFD_format_names[format - 1];
+}
struct IFD_tag {
uint16_t tag;
@@ -207,120 +87,43 @@ struct IFD_tag {
uint32_t num_components;
};
-/* These are sorted by tag */
-static const struct IFD_tag IFD_tags[] = {
- /* TAGs from IFD0 */
- /* TODO May be LONG */
- {IFD_IMAGE_WIDTH, "Image Width", IFD_UNSIGNED_SHORT, 1},
- {IFD_IMAGE_HEIGHT, "Image Height", IFD_UNSIGNED_SHORT, 1},
-
- {IFD_BITS_PER_SAMPLE, "Bits Per Sample", IFD_UNSIGNED_SHORT, 3},
- {IFD_COMPRESSION, "Compression", IFD_UNSIGNED_SHORT, 1},
- {IFD_PHOTOMETRIC_INTERPRETATION, "Photometric Interpretation", IFD_UNSIGNED_SHORT, 1},
-
- {IFD_IMAGE_DESCRIPTION, "Image Description", IFD_ASCII_STRING, 0},
- {IFD_MAKE, "Make", IFD_ASCII_STRING, 0},
- {IFD_MODEL, "Model", IFD_ASCII_STRING, 0},
- {IFD_ORIENTATION, "Orientation", IFD_UNSIGNED_SHORT, 1},
- {IFD_X_RESOLUTION, "X Resolution", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_Y_RESOLUTION, "Y Resolution", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_PLANAR_CONFIGURATION, "Planar Configuration", IFD_UNSIGNED_SHORT, 1},
- {IFD_RESOLUTION_UNIT, "Resolution Unit", IFD_UNSIGNED_SHORT, 1},
- {IFD_SOFTWARE, "Software", IFD_ASCII_STRING, 0},
- {IFD_DATE_TIME, "Date Time", IFD_ASCII_STRING, 20},
- {IFD_WHITE_POINT, "White Point", IFD_UNSIGNED_RATIONAL, 2},
- {IFD_PRIMARY_CHROMATICIES, "Primary Chromaticies", IFD_UNSIGNED_RATIONAL, 6},
- {IFD_Y_CB_CR_COEFFICIENTS, "YCbCr Conefficients", IFD_UNSIGNED_RATIONAL, 3},
- {IFD_Y_CB_CR_POSITIONING, "YCbCr Positioning", IFD_UNSIGNED_SHORT, 1},
- {IFD_REFERENCE_BLACK_WHITE, "Reference Black White", IFD_UNSIGNED_RATIONAL, 6},
- {IFD_COPYRIGHT, "Copyright", IFD_ASCII_STRING, 0},
-
- /* TAGs from Exif SubIFD */
- {IFD_EXPOSURE_TIME, "Exposure Time", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_F_NUMBER, "F-Number", IFD_UNSIGNED_RATIONAL, 1},
-
- /* TAG from IFD0 */
- {IFD_EXIF_OFFSET, "Exif Offset", IFD_UNSIGNED_LONG, 1},
-
- /* TAGs from Exif SubIFD */
- {IFD_EXPOSURE_PROGRAM, "Exposure Program", IFD_UNSIGNED_SHORT, 1},
- {IFD_ISO_SPEED_RATINGS, "ISO Speed Ratings", IFD_UNSIGNED_SHORT, 1},
- {IFD_EXIF_VERSION, "Exif Version", IFD_UNDEFINED, 4},
- {IFD_DATE_TIME_ORIGINAL, "Date Time Original", IFD_ASCII_STRING, 20},
- {IFD_DATE_TIME_DIGITIZED, "Date Time Digitized", IFD_ASCII_STRING, 20},
- {IFD_COMPONENT_CONFIGURATION, "Component Configuration", IFD_UNDEFINED, 0},
- {IFD_COMPRESSED_BITS_PER_PIXEL, "Compressed Bits Per Pixel", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_SHUTTER_SPEED_VALUE, "Shutter Speed", IFD_SIGNED_RATIONAL, 1},
- {IFD_APERTURE_VALUE, "Aperture", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_BRIGHTNESS_VALUE, "Brightness", IFD_SIGNED_RATIONAL, 1},
- {IFD_EXPOSURE_BIAS_VALUE, "Exposure Bias", IFD_SIGNED_RATIONAL, 1},
- {IFD_MAX_APERTURE_VALUE, "Max Aperture", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_SUBJECT_DISTANCE, "Subject Distance", IFD_SIGNED_RATIONAL, 1},
- {IFD_METERING_MODE, "Metering Mode", IFD_UNSIGNED_SHORT, 1},
- {IFD_LIGHT_SOURCE, "Light Source", IFD_UNSIGNED_SHORT, 1},
- {IFD_FLASH, "Flash", IFD_UNSIGNED_SHORT, 1},
- {IFD_FOCAL_LENGTH, "Focal Length", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_MAKER_NOTE, "Maker Note", IFD_UNDEFINED, 0},
- {IFD_USER_COMMENT, "User Comment", IFD_UNDEFINED, 0},
- {IFD_FLASH_PIX_VERSION, "Flash Pix Version", IFD_UNDEFINED, 4},
- {IFD_COLOR_SPACE, "Color Space", IFD_UNSIGNED_SHORT, 1},
- /* these two may be short in some cases */
- {IFD_EXIF_IMAGE_WIDTH, "Exif Image Width", IFD_UNSIGNED_LONG, 1},
- {IFD_EXIF_IMAGE_HEIGHT, "Exif Image Height", IFD_UNSIGNED_LONG, 1},
- {IFD_RELATED_SOUND_FILE, "Related Soundfile", IFD_ASCII_STRING, 0},
- {IFD_FOCAL_PLANE_X_RESOLUTION, "Focal Plane X Resolution", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_FOCAL_PLANE_Y_RESOLUTION, "Focal Plane Y Resolution", IFD_UNSIGNED_RATIONAL, 1},
- {IFD_FOCAL_PLANE_RESOLUTION_UNIT, "Focal Plane Resolution Unit", IFD_UNSIGNED_SHORT, 1},
- {IFD_SENSING_METHOD, "Sensing Method", IFD_UNSIGNED_SHORT, 1},
- {IFD_FILE_SOURCE, "File Source", IFD_UNDEFINED, 1},
- {IFD_SCENE_TYPE, "Scene Type", IFD_UNDEFINED, 1},
- {IFD_CUSTOM_RENDERER, "Custom Renderer", IFD_UNSIGNED_SHORT, 1},
- {IFD_EXPOSURE_MODE, "Exposure Mode", IFD_UNSIGNED_SHORT, 1},
- {IFD_WHITE_BALANCE, "White Balance", IFD_UNSIGNED_SHORT, 1},
- {IFD_SCENE_CAPTURE_TYPE, "Scene Capture Type", IFD_UNSIGNED_SHORT, 1},
- {IFD_CONTRAST, "Contrast", IFD_UNSIGNED_SHORT, 1},
- {IFD_SATURATION, "Saturation", IFD_UNSIGNED_SHORT, 1},
- {IFD_SHARPNESS, "Sharpness", IFD_UNSIGNED_SHORT, 1},
+struct IFD_tags {
+ const struct IFD_tag *tags;
+ unsigned int tag_cnt;
+ const char *id;
};
-static const char *IFD_format_name(uint16_t format)
-{
- if (format == 0 || format > IFD_FORMAT_LAST)
- return "Unknown";
-
- return IFD_format_names[format - 1];
-}
-
-static const struct IFD_tag *IFD_tag_get(uint16_t tag)
+static const struct IFD_tag *IFD_tag_get(const struct IFD_tags *tags,
+ uint16_t tag)
{
int left = 0;
- int right = sizeof(IFD_tags)/sizeof(struct IFD_tag) - 1;
+ int right = tags->tag_cnt - 1;
while (right - left > 1) {
int middle = (right + left)/2;
- if (IFD_tags[middle].tag == tag)
- return &IFD_tags[middle];
+ if (tags->tags[middle].tag == tag)
+ return &tags->tags[middle];
- if (IFD_tags[middle].tag > tag)
+ if (tags->tags[middle].tag > tag)
right = middle;
else
left = middle;
}
- if (IFD_tags[left].tag == tag)
- return &IFD_tags[left];
+ if (tags->tags[left].tag == tag)
+ return &tags->tags[left];
- if (IFD_tags[right].tag == tag)
- return &IFD_tags[right];
+ if (tags->tags[right].tag == tag)
+ return &tags->tags[right];
return NULL;
}
-static const char *IFD_tag_name(uint16_t tag)
+static const char *IFD_tag_name(const struct IFD_tags *taglist, uint16_t tag)
{
- const struct IFD_tag *res = IFD_tag_get(tag);
+ const struct IFD_tag *res = IFD_tag_get(taglist, tag);
if (res == NULL)
return "Unknown";
@@ -328,6 +131,9 @@ static const char *IFD_tag_name(uint16_t tag)
return res->name;
}
+#include "GP_ExifGPS.h"
+#include "GP_Exif.h"
+
static int get_buf(GP_IO *io, off_t offset, char *buf, size_t len)
{
off_t off;
@@ -380,8 +186,7 @@ add:
static int load_rat(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
const char *id, uint32_t num_comp, uint32_t val)
{
- uint32_t buf[2];
-
+ (void)io;(void)storage;(void)node;(void)id;(void)num_comp;(void)val;
return GP_DataStorageAddRational(storage, node, id, 0, 0) != NULL;
}
@@ -406,29 +211,29 @@ static int rat_den(void *buf, uint32_t offset, size_t buf_len, int swap)
*/
static int load_tag(GP_IO *io, GP_DataStorage *storage,
- GP_DataNode* node, int endian,
- uint16_t tag, uint16_t format,
+ GP_DataNode* node, const struct IFD_tags *taglist,
+ int endian, uint16_t tag, uint16_t format,
uint32_t num_comp, uint32_t val)
{
- const struct IFD_tag *res = IFD_tag_get(tag);
+ const struct IFD_tag *res = IFD_tag_get(taglist, tag);
if (res == NULL) {
- GP_TODO("Skipping unknown IFD tag 0x%02x format %s",
- tag, IFD_format_name(format));
+ GP_TODO("Skipping unknown IFD tag 0x%02x %s cnt %u in %s block",
+ tag, IFD_format_name(format), num_comp, taglist->id);
return 0;
}
if (res->format != format) {
GP_WARN("Unexpected tag '%s' format '%s' (0x%02x) "
- "expected '%s'", res->name,
+ "expected '%s' in %s block", res->name,
IFD_format_name(format), format,
- IFD_format_name(res->format));
+ IFD_format_name(res->format), taglist->id);
}
if ((res->num_components != 0) &&
(res->num_components != num_comp)) {
- GP_WARN("Unexpected tag '%s' num_components %u expected %u",
- res->name, num_comp, res->num_components);
+ GP_WARN("Unexpected '%s' num_components %u expected %u in %s block",
+ res->name, num_comp, res->num_components, taglist->id);
}
switch (format) {
@@ -436,7 +241,9 @@ static int load_tag(GP_IO *io, GP_DataStorage *storage,
if (load_string(io, storage, node, res->name, num_comp, &val))
return 1;
break;
- //case IFD_UNSIGNED_LONG:
+ case IFD_SIGNED_LONG:
+ case IFD_UNSIGNED_LONG:
+ case IFD_SIGNED_SHORT:
case IFD_UNSIGNED_SHORT:
if (num_comp == 1)
GP_DataStorageAddInt(storage, node, res->name, val);
@@ -448,23 +255,13 @@ static int load_tag(GP_IO *io, GP_DataStorage *storage,
case IFD_SIGNED_RATIONAL:
if (load_rat(io, storage, node, res->name, num_comp, val))
return 1;
-
-/* if (num_comp == 1) {
- rec.type = GP_DATA_RATIONAL;
- rec.value.rat.
- GP_MetaDataCreateRat(self, res->name,
- rat_num(buf, val, buf_len, swap),
- rat_den(buf, val, buf_len, swap));
- } else {
- goto unused;
- }
-*/
break;
case IFD_UNDEFINED:
switch (res->tag) {
case IFD_EXIF_VERSION:
case IFD_FLASH_PIX_VERSION:
case IFD_MAKER_NOTE:
+ case IFD_INTEROP_VERSION:
if (load_string(io, storage, node, res->name, num_comp, &val))
return 1;
break;
@@ -482,11 +279,18 @@ static int load_tag(GP_IO *io, GP_DataStorage *storage,
return 0;
}
+struct IFD_subrecord {
+ uint16_t tag;
+ uint32_t offset;
+};
+
static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
- uint32_t IFD_offset, int endian)
+ const struct IFD_tags *taglist, uint32_t IFD_offset,
+ int endian)
{
uint16_t IFD_entries_count;
uint16_t i2 = endian == 'I' ? GP_IO_L2 : GP_IO_B2;
+ unsigned int i;
uint16_t IFD_header[] = {
GP_IO_IGN | IFD_offset,
@@ -494,14 +298,6 @@ static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
GP_IO_END,
};
- if (GP_IOReadF(io, IFD_header, &IFD_entries_count) != 2) {
- GP_DEBUG(1, "Failed to read IFD entries count");
- return 1;
- }
-
- GP_DEBUG(2, "-- IFD Offset 0x%08x Entries 0x%04x --",
- IFD_offset, IFD_entries_count);
-
uint16_t IFD_record_LE[] = {
GP_IO_L2, /* Tag */
GP_IO_L2, /* Format */
@@ -518,16 +314,24 @@ static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
GP_IO_END,
};
- uint16_t *IFD_record = endian == 'I' ? IFD_record_LE : IFD_record_BE;
+ uint16_t *IFD_rec_head = endian == 'I' ? IFD_record_LE : IFD_record_BE;
+
+ if (GP_IOReadF(io, IFD_header, &IFD_entries_count) != 2) {
+ GP_DEBUG(1, "Failed to read IFD entries count");
+ return 1;
+ }
+
+ GP_DEBUG(2, "-- IFD Offset 0x%08x Entries %04u --",
+ IFD_offset, IFD_entries_count);
- int i;
+ struct IFD_subrecord subrecs[IFD_entries_count];
+ unsigned int subrec_cnt = 0;
for (i = 0; i < IFD_entries_count; i++) {
uint16_t tag, format;
uint32_t num_comp, val;
- off_t cur_off;
- if (GP_IOReadF(io, IFD_record, &tag, &format, &num_comp, &val) != 4) {
+ if (GP_IOReadF(io, IFD_rec_head, &tag, &format, &num_comp, &val) != 4) {
GP_DEBUG(1, "Failed to read IFD record");
return 1;
}
@@ -536,28 +340,55 @@ static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
tag, format, num_comp, val);
GP_DEBUG(3, "IFD Entry tag '%s' format '%s'",
- IFD_tag_name(tag), IFD_format_name(format));
+ IFD_tag_name(taglist, tag), IFD_format_name(format));
+
+ switch (tag) {
+ case IFD_EXIF_OFFSET:
+ case IFD_GPS_OFFSET:
+ case IFD_INTEROPERABILITY_OFFSET:
+ subrecs[subrec_cnt].tag = tag;
+ subrecs[subrec_cnt].offset = val;
+ subrec_cnt++;
+ break;
+ default:
+ load_tag(io, storage, node, taglist, endian, tag, format, num_comp, val);
+ break;
+ }
+ }
+ for (i = 0; i < subrec_cnt; i++) {
+ off_t cur_off = GP_IOTell(io);
+ const struct IFD_tags *tags;
+ GP_DataNode *new_node;
- if (tag == IFD_EXIF_OFFSET) {
- cur_off = GP_IOTell(io);
+ GP_DEBUG(3, "-- Loading sub IFD %s --",
+ IFD_tag_name(taglist, subrecs[i].tag));
- /* Offset is counted from the II or MM in the Exif header */
- if (val + 6 < cur_off)
- GP_DEBUG(1, "Negative offset!");
- else
- load_IFD(io, storage, node, val + 6 - cur_off, endian);
- } else {
- load_tag(io, storage, node, endian, tag, format, num_comp, val);
+ switch (subrecs[i].tag) {
+ case IFD_EXIF_OFFSET:
+ tags = taglist;
+ new_node = node;
+ break;
+ case IFD_GPS_OFFSET:
+ tags = &IFD_GPS_tags;
+ new_node = GP_DataStorageAddDict(storage, node, "GPS");
+ break;
+ case IFD_INTEROPERABILITY_OFFSET:
+ tags = taglist;
+ new_node = GP_DataStorageAddDict(storage, node, "Interoperability");
+ break;
+ default:
+ GP_BUG("Invalid tag");
+ return 1;
}
- }
-/*
- GET_32(IFD_offset, buf, IFD_offset, buf_len, swap);
+ /* Offset is counted from the II or MM in the Exif header */
+ if (subrecs[i].offset + 6 < cur_off)
+ GP_DEBUG(1, "Negative offset!");
+
+ load_IFD(io, storage, new_node, tags, subrecs[i].offset + 6 - cur_off, endian);
+ }
- if (IFD_offset != 0x00000000)
- load_IFD(self, buf, buf_len, IFD_offset, swap);
-*/
return 0;
}
@@ -605,5 +436,5 @@ int GP_ReadExif(GP_IO *io, GP_DataStorage *storage)
GP_DataNode *exif_root = GP_DataStorageAddDict(storage, NULL, "Exif");
/* The offset starts from the II or MM */
- return load_IFD(io, storage, exif_root, IFD_offset - 8, b1);
+ return load_IFD(io, storage, exif_root, &IFD_EXIF_tags, IFD_offset - 8, b1);
}
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.h
similarity index 53%
copy from libs/loaders/GP_Exif.c
copy to libs/loaders/GP_Exif.h
index 99f49f7..2e09413 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.h
@@ -20,64 +20,15 @@
* *
*****************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
+enum IFD_EXIF_tags {
+ /* Stored in interop IFD */
+ IFD_INTEROP_VERSION = 0x2,
-#include "core/GP_Debug.h"
-
-#include "loaders/GP_Exif.h"
-
-enum IFD_formats {
- /* 1 bytes/components */
- IFD_UNSIGNED_BYTE = 0x01,
- /* 1 bytes/components */
- IFD_ASCII_STRING = 0x02,
- /* 2 bytes/components */
- IFD_UNSIGNED_SHORT = 0x03,
- /* 4 bytes/components */
- IFD_UNSIGNED_LONG = 0x04,
- /* 8 bytes/components */
- IFD_UNSIGNED_RATIONAL = 0x05,
- /* 1 bytes/components */
- IFD_SIGNED_BYTE = 0x06,
- /* 1 bytes/components */
- IFD_UNDEFINED = 0x07,
- /* 2 bytes/components */
- IFD_SIGNED_SHORT = 0x08,
- /* 4 bytes/components */
- IFD_SIGNED_LONG = 0x09,
- /* 8 bytes/components */
- IFD_SIGNED_RATIONAL = 0x0a,
- /* 4 bytes/components */
- IFD_SINGLE_FLOAT = 0x0b,
- /* 8 bytes/components */
- IFD_SINGLE_DOUBLE = 0x0c,
- IFD_FORMAT_LAST = IFD_SINGLE_DOUBLE,
-};
-
-static const char *IFD_format_names[] = {
- "Unsigned Byte",
- "ASCII String",
- "Unsigned Short",
- "Unsigned Long",
- "Unsigned Rational",
- "Signed Byte",
- "Undefined",
- "Signed Short",
- "Signed Long",
- "Signed Rational",
- "Single Float",
- "Double Float",
-};
-
-enum IFD_tags {
/* Image width and height */
IFD_IMAGE_WIDTH = 0x0100,
IFD_IMAGE_HEIGHT = 0x0101,
IFD_BITS_PER_SAMPLE = 0x0102,
-
/* TODO: enum of compressions */
IFD_COMPRESSION = 0x0103,
/* TODO: enum of interpretations */
@@ -105,6 +56,8 @@ enum IFD_tags {
IFD_SOFTWARE = 0x0131,
/* YYYY:MM:DD HH:MM:SS in 24 hours format */
IFD_DATE_TIME = 0x0132,
+ /* Artist */
+ IFD_ARTIST = 0x013b,
/* White Point */
IFD_WHITE_POINT = 0x013e,
/* Primary Chromaticies */
@@ -115,19 +68,22 @@ enum IFD_tags {
IFD_Y_CB_CR_POSITIONING = 0x0213,
/* Reference Black White */
IFD_REFERENCE_BLACK_WHITE = 0x0214,
+ /* Stored in interop IFD */
+ IFD_RELATED_IMAGE_WIDTH = 0x1001,
+ IFD_RELATED_IMAGE_HEIGHT = 0x1002,
/* Copyright */
IFD_COPYRIGHT = 0x8298,
- /* Exif SubIFD Offset */
- IFD_EXIF_OFFSET = 0x8769,
-
- /* TAGs from Exif SubIFD */
IFD_EXPOSURE_TIME = 0x829a,
/* Actual F-Number of lens when image was taken */
IFD_F_NUMBER = 0x829d,
+ /* Exif SubIFD Offset */
+ IFD_EXIF_OFFSET = 0x8769,
/* 1 manual, 2 normal, 3 aperture priority, 4 shutter priority, *
* 5 creative (slow), 6 action (high-speed), 7 portrait mode, *
* 8 landscape mode */
IFD_EXPOSURE_PROGRAM = 0x8822,
+ /* Offset to GPS data */
+ IFD_GPS_OFFSET = 0x8825,
/* CCD sensitivity */
IFD_ISO_SPEED_RATINGS = 0x8827,
/* ASCII 4 byte Exif version */
@@ -165,6 +121,11 @@ enum IFD_tags {
/* Comment */
IFD_USER_COMMENT = 0x9286,
+ /* Subsec time in addition to IFD_DATE_TIME* */
+ IFD_SUBSEC_TIME = 0x9290,
+ IFD_SUBSEC_TIME_ORIGINAL = 0x9291,
+ IFD_SUBSEC_TIME_DIGITIZED = 0x9292,
+
/* Stores FlashPix version, undefined, may be four ASCII numbers */
IFD_FLASH_PIX_VERSION = 0xa000,
/* Unknown may be 1 */
@@ -174,6 +135,8 @@ enum IFD_tags {
IFD_EXIF_IMAGE_HEIGHT = 0xa003,
/* May store related audio filename */
IFD_RELATED_SOUND_FILE = 0xa004,
+ /* Offset to Interoperability SubIFD */
+ IFD_INTEROPERABILITY_OFFSET = 0xa005,
/* */
IFD_FOCAL_PLANE_X_RESOLUTION = 0xa20e,
IFD_FOCAL_PLANE_Y_RESOLUTION = 0xa20f,
@@ -183,33 +146,47 @@ enum IFD_tags {
IFD_SENSING_METHOD = 0xa217,
IFD_FILE_SOURCE = 0xa300,
IFD_SCENE_TYPE = 0xa301,
+ /* Color Filter Array pattern */
+ IFD_CFA_PATTERN = 0xa302,
/* 0 = Normal, 1 = Custom */
IFD_CUSTOM_RENDERER = 0xa401,
/* 0 = Auto, 1 = Manual, 2 = Auto bracket */
IFD_EXPOSURE_MODE = 0xa402,
/* 0 = Auto, 1 = Manual */
IFD_WHITE_BALANCE = 0xa403,
+ /* 0 == Not Used */
+ IFD_DIGITAL_ZOOM_RATIO = 0xa404,
+ /* Equivalent lenght assuming 35mm camera */
+ IFD_FOCAL_LENGTH_IN_35_MM_FILM = 0xa405,
/* 0 = Standard, 1 = Landscape, 2 = Portrait, 3 = Night Scene */
IFD_SCENE_CAPTURE_TYPE = 0xa406,
+ /* 0 = None, 1 = Low Gain Up, 2 = High Gain Up, 3 = Low Gain Down, 4 = High Gain Down */
+ IFD_GAIN_CONTROL = 0xa407,
/* 0 = Normal, 1 = Soft, 2 = Hard */
IFD_CONTRAST = 0xa408,
/* 0 = Normal, 1 = Low Saturation, 2 = Hight Saturation */
IFD_SATURATION = 0xa409,
/* 0 = Normal, 1 = Sort, 2 = Hard */
IFD_SHARPNESS = 0xa40a,
+ /* 0 = Unknown, 1 = Macro, 2 = Close View, 3 = Distant View */
+ IFD_SUBJECT_DISTANCE_RANGE = 0xa40c,
+ /* Unique in hex string */
+ IFD_IMAGE_UNIQUE_ID = 0xa420,
+
+ /* ??? */
+ IFD_PRINT_IM = 0xc4a5,
+
+ /* Padding */
+ IFD_PADDING = 0xea1c,
+ /* Microsoft's ill-conceived maker note offset difference */
+ IFD_OFFSET_SCHEMA = 0xea1d,
};
-struct IFD_tag {
- uint16_t tag;
- const char *name;
- uint16_t format;
- /* 0 == not defined */
- uint32_t num_components;
-};
+/* MUST SORTED BY TAG */
+static const struct IFD_tag IFD_EXIF_taglist[] = {
+ /* Stored in interop IFD */
+ {IFD_INTEROP_VERSION, "Interop Version", IFD_UNDEFINED, 4},
-/* These are sorted by tag */
-static const struct IFD_tag IFD_tags[] = {
- /* TAGs from IFD0 */
/* TODO May be LONG */
{IFD_IMAGE_WIDTH, "Image Width", IFD_UNSIGNED_SHORT, 1},
{IFD_IMAGE_HEIGHT, "Image Height", IFD_UNSIGNED_SHORT, 1},
@@ -228,22 +205,25 @@ static const struct IFD_tag IFD_tags[] = {
{IFD_RESOLUTION_UNIT, "Resolution Unit", IFD_UNSIGNED_SHORT, 1},
{IFD_SOFTWARE, "Software", IFD_ASCII_STRING, 0},
{IFD_DATE_TIME, "Date Time", IFD_ASCII_STRING, 20},
+ {IFD_ARTIST, "Artist", IFD_ASCII_STRING, 0},
{IFD_WHITE_POINT, "White Point", IFD_UNSIGNED_RATIONAL, 2},
{IFD_PRIMARY_CHROMATICIES, "Primary Chromaticies", IFD_UNSIGNED_RATIONAL, 6},
{IFD_Y_CB_CR_COEFFICIENTS, "YCbCr Conefficients", IFD_UNSIGNED_RATIONAL, 3},
{IFD_Y_CB_CR_POSITIONING, "YCbCr Positioning", IFD_UNSIGNED_SHORT, 1},
{IFD_REFERENCE_BLACK_WHITE, "Reference Black White", IFD_UNSIGNED_RATIONAL, 6},
+
+ /* Stored in interop IFD */
+ {IFD_RELATED_IMAGE_WIDTH, "Related Image Width", IFD_UNSIGNED_LONG, 1},
+ {IFD_RELATED_IMAGE_HEIGHT, "Related Image Height", IFD_UNSIGNED_LONG, 1},
+
{IFD_COPYRIGHT, "Copyright", IFD_ASCII_STRING, 0},
/* TAGs from Exif SubIFD */
{IFD_EXPOSURE_TIME, "Exposure Time", IFD_UNSIGNED_RATIONAL, 1},
{IFD_F_NUMBER, "F-Number", IFD_UNSIGNED_RATIONAL, 1},
-
- /* TAG from IFD0 */
{IFD_EXIF_OFFSET, "Exif Offset", IFD_UNSIGNED_LONG, 1},
-
- /* TAGs from Exif SubIFD */
{IFD_EXPOSURE_PROGRAM, "Exposure Program", IFD_UNSIGNED_SHORT, 1},
+ {IFD_GPS_OFFSET, "GPS Offset", IFD_UNSIGNED_LONG, 1},
{IFD_ISO_SPEED_RATINGS, "ISO Speed Ratings", IFD_UNSIGNED_SHORT, 1},
{IFD_EXIF_VERSION, "Exif Version", IFD_UNDEFINED, 4},
{IFD_DATE_TIME_ORIGINAL, "Date Time Original", IFD_ASCII_STRING, 20},
@@ -262,348 +242,42 @@ static const struct IFD_tag IFD_tags[] = {
{IFD_FOCAL_LENGTH, "Focal Length", IFD_UNSIGNED_RATIONAL, 1},
{IFD_MAKER_NOTE, "Maker Note", IFD_UNDEFINED, 0},
{IFD_USER_COMMENT, "User Comment", IFD_UNDEFINED, 0},
+ {IFD_SUBSEC_TIME, "Subsec Time", IFD_ASCII_STRING, 0},
+ {IFD_SUBSEC_TIME_ORIGINAL, "Subsec Time Original", IFD_ASCII_STRING, 0},
+ {IFD_SUBSEC_TIME_DIGITIZED, "Subsec Time Digitized", IFD_ASCII_STRING, 0},
{IFD_FLASH_PIX_VERSION, "Flash Pix Version", IFD_UNDEFINED, 4},
{IFD_COLOR_SPACE, "Color Space", IFD_UNSIGNED_SHORT, 1},
/* these two may be short in some cases */
{IFD_EXIF_IMAGE_WIDTH, "Exif Image Width", IFD_UNSIGNED_LONG, 1},
{IFD_EXIF_IMAGE_HEIGHT, "Exif Image Height", IFD_UNSIGNED_LONG, 1},
{IFD_RELATED_SOUND_FILE, "Related Soundfile", IFD_ASCII_STRING, 0},
+ {IFD_INTEROPERABILITY_OFFSET, "Interoperability Offset", IFD_UNSIGNED_LONG, 1},
{IFD_FOCAL_PLANE_X_RESOLUTION, "Focal Plane X Resolution", IFD_UNSIGNED_RATIONAL, 1},
{IFD_FOCAL_PLANE_Y_RESOLUTION, "Focal Plane Y Resolution", IFD_UNSIGNED_RATIONAL, 1},
{IFD_FOCAL_PLANE_RESOLUTION_UNIT, "Focal Plane Resolution Unit", IFD_UNSIGNED_SHORT, 1},
{IFD_SENSING_METHOD, "Sensing Method", IFD_UNSIGNED_SHORT, 1},
{IFD_FILE_SOURCE, "File Source", IFD_UNDEFINED, 1},
{IFD_SCENE_TYPE, "Scene Type", IFD_UNDEFINED, 1},
+ {IFD_CFA_PATTERN, "CFA Pattern", IFD_UNDEFINED, 0},
{IFD_CUSTOM_RENDERER, "Custom Renderer", IFD_UNSIGNED_SHORT, 1},
{IFD_EXPOSURE_MODE, "Exposure Mode", IFD_UNSIGNED_SHORT, 1},
{IFD_WHITE_BALANCE, "White Balance", IFD_UNSIGNED_SHORT, 1},
+ {IFD_DIGITAL_ZOOM_RATIO, "Digital Zoom Ratio", IFD_UNSIGNED_RATIONAL, 1},
+ {IFD_FOCAL_LENGTH_IN_35_MM_FILM, "Focal Lenght In 35mm Film", IFD_UNSIGNED_SHORT, 1},
{IFD_SCENE_CAPTURE_TYPE, "Scene Capture Type", IFD_UNSIGNED_SHORT, 1},
+ {IFD_GAIN_CONTROL, "Gain Control", IFD_UNSIGNED_SHORT, 1},
{IFD_CONTRAST, "Contrast", IFD_UNSIGNED_SHORT, 1},
{IFD_SATURATION, "Saturation", IFD_UNSIGNED_SHORT, 1},
{IFD_SHARPNESS, "Sharpness", IFD_UNSIGNED_SHORT, 1},
+ {IFD_SUBJECT_DISTANCE_RANGE, "Subject Distance Range", IFD_UNSIGNED_SHORT, 1},
+ {IFD_IMAGE_UNIQUE_ID, "Image Unique ID", IFD_ASCII_STRING, 33},
+ {IFD_PRINT_IM, "Print IM", IFD_UNDEFINED, 0},
+ {IFD_PADDING, "Padding", IFD_UNDEFINED, 0},
+ {IFD_OFFSET_SCHEMA, "Offset Schema", IFD_SIGNED_LONG, 1},
};
-static const char *IFD_format_name(uint16_t format)
-{
- if (format == 0 || format > IFD_FORMAT_LAST)
- return "Unknown";
-
- return IFD_format_names[format - 1];
-}
-
-static const struct IFD_tag *IFD_tag_get(uint16_t tag)
-{
- int left = 0;
- int right = sizeof(IFD_tags)/sizeof(struct IFD_tag) - 1;
-
- while (right - left > 1) {
- int middle = (right + left)/2;
-
- if (IFD_tags[middle].tag == tag)
- return &IFD_tags[middle];
-
-
- if (IFD_tags[middle].tag > tag)
- right = middle;
- else
- left = middle;
- }
-
- if (IFD_tags[left].tag == tag)
- return &IFD_tags[left];
-
- if (IFD_tags[right].tag == tag)
- return &IFD_tags[right];
-
- return NULL;
-}
-
-static const char *IFD_tag_name(uint16_t tag)
-{
- const struct IFD_tag *res = IFD_tag_get(tag);
-
- if (res == NULL)
- return "Unknown";
- else
- return res->name;
-}
-
-static int get_buf(GP_IO *io, off_t offset, char *buf, size_t len)
-{
- off_t off;
-
- off = GP_IOTell(io);
-
- if (GP_IOSeek(io, offset, GP_IO_SEEK_SET) == -1) {
- GP_WARN("Failed to seek to data");
- return 1;
- }
-
- if (GP_IOFill(io, buf, len)) {
- GP_WARN("Failed to read data");
- return 1;
- }
-
- if (GP_IOSeek(io, off, GP_IO_SEEK_SET) == -1) {
- GP_WARN("Failed to seek back");
- return 1;
- }
-
- return 0;
-}
-
-static int load_string(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
- const char *id, uint32_t num_comp, uint32_t *val)
-{
- size_t max_len = GP_MIN(num_comp, 1024u);
- char buf[max_len];
-
- /* Short strings are stored in the value directly */
- if (num_comp <= 4) {
- memcpy(buf, val, num_comp);
- buf[num_comp > 0 ? num_comp - 1 : num_comp] = 0;
- goto add;
- }
-
- /* Longer are stored at offset starting from II or MM */
- if (get_buf(io, *val + 6, buf, max_len))
- return 1;
-
- buf[max_len - 1] = '0';
-
-add:
- GP_DEBUG(2, "ASCII String value = '%s'", buf);
-
- return GP_DataStorageAddString(storage, node, id, buf) != NULL;
-}
-
-static int load_rat(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
- const char *id, uint32_t num_comp, uint32_t val)
-{
- uint32_t buf[2];
-
- return GP_DataStorageAddRational(storage, node, id, 0, 0) != NULL;
-}
-
-/*
-static int rat_num(void *buf, uint32_t offset, size_t buf_len, int swap)
-{
- int ret;
-
- GET_32(ret, buf, offset, buf_len, swap);
-
- return ret;
-}
-
-static int rat_den(void *buf, uint32_t offset, size_t buf_len, int swap)
-{
- int ret;
-
- GET_32(ret, buf, offset + 4, buf_len, swap);
-
- return ret;
-}
-*/
-
-static int load_tag(GP_IO *io, GP_DataStorage *storage,
- GP_DataNode* node, int endian,
- uint16_t tag, uint16_t format,
- uint32_t num_comp, uint32_t val)
-{
- const struct IFD_tag *res = IFD_tag_get(tag);
-
- if (res == NULL) {
- GP_TODO("Skipping unknown IFD tag 0x%02x format %s",
- tag, IFD_format_name(format));
- return 0;
- }
-
- if (res->format != format) {
- GP_WARN("Unexpected tag '%s' format '%s' (0x%02x) "
- "expected '%s'", res->name,
- IFD_format_name(format), format,
- IFD_format_name(res->format));
- }
-
- if ((res->num_components != 0) &&
- (res->num_components != num_comp)) {
- GP_WARN("Unexpected tag '%s' num_components %u expected %u",
- res->name, num_comp, res->num_components);
- }
-
- switch (format) {
- case IFD_ASCII_STRING:
- if (load_string(io, storage, node, res->name, num_comp, &val))
- return 1;
- break;
- //case IFD_UNSIGNED_LONG:
- case IFD_UNSIGNED_SHORT:
- if (num_comp == 1)
- GP_DataStorageAddInt(storage, node, res->name, val);
- else
- goto unused;
- break;
-
- case IFD_UNSIGNED_RATIONAL:
- case IFD_SIGNED_RATIONAL:
- if (load_rat(io, storage, node, res->name, num_comp, val))
- return 1;
-
-/* if (num_comp == 1) {
- rec.type = GP_DATA_RATIONAL;
- rec.value.rat.
- GP_MetaDataCreateRat(self, res->name,
- rat_num(buf, val, buf_len, swap),
- rat_den(buf, val, buf_len, swap));
- } else {
- goto unused;
- }
-*/
- break;
- case IFD_UNDEFINED:
- switch (res->tag) {
- case IFD_EXIF_VERSION:
- case IFD_FLASH_PIX_VERSION:
- case IFD_MAKER_NOTE:
- if (load_string(io, storage, node, res->name, num_comp, &val))
- return 1;
- break;
- default:
- goto unused;
- }
- break;
-
- unused:
- default:
- GP_TODO("Unused record '%s' format '%s' (0x%02x)", res->name,
- IFD_format_name(format), format);
- }
-
- return 0;
-}
-
-static int load_IFD(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
- uint32_t IFD_offset, int endian)
-{
- uint16_t IFD_entries_count;
- uint16_t i2 = endian == 'I' ? GP_IO_L2 : GP_IO_B2;
-
- uint16_t IFD_header[] = {
- GP_IO_IGN | IFD_offset,
- i2,
- GP_IO_END,
- };
-
- if (GP_IOReadF(io, IFD_header, &IFD_entries_count) != 2) {
- GP_DEBUG(1, "Failed to read IFD entries count");
- return 1;
- }
-
- GP_DEBUG(2, "-- IFD Offset 0x%08x Entries 0x%04x --",
- IFD_offset, IFD_entries_count);
-
- uint16_t IFD_record_LE[] = {
- GP_IO_L2, /* Tag */
- GP_IO_L2, /* Format */
- GP_IO_L4, /* Number of components */
- GP_IO_L4, /* Value */
- GP_IO_END,
- };
-
- uint16_t IFD_record_BE[] = {
- GP_IO_B2, /* Tag */
- GP_IO_B2, /* Format */
- GP_IO_B4, /* Number of components */
- GP_IO_B4, /* Value */
- GP_IO_END,
- };
-
- uint16_t *IFD_record = endian == 'I' ? IFD_record_LE : IFD_record_BE;
-
- int i;
-
- for (i = 0; i < IFD_entries_count; i++) {
- uint16_t tag, format;
- uint32_t num_comp, val;
- off_t cur_off;
-
- if (GP_IOReadF(io, IFD_record, &tag, &format, &num_comp, &val) != 4) {
- GP_DEBUG(1, "Failed to read IFD record");
- return 1;
- }
-
- GP_DEBUG(3, "IFD Entry tag 0x%04x format (0x%04x) components 0x%08x val 0x%08x",
- tag, format, num_comp, val);
-
- GP_DEBUG(3, "IFD Entry tag '%s' format '%s'",
- IFD_tag_name(tag), IFD_format_name(format));
-
-
- if (tag == IFD_EXIF_OFFSET) {
- cur_off = GP_IOTell(io);
-
- /* Offset is counted from the II or MM in the Exif header */
- if (val + 6 < cur_off)
- GP_DEBUG(1, "Negative offset!");
- else
- load_IFD(io, storage, node, val + 6 - cur_off, endian);
- } else {
- load_tag(io, storage, node, endian, tag, format, num_comp, val);
- }
- }
-
-/*
- GET_32(IFD_offset, buf, IFD_offset, buf_len, swap);
-
- if (IFD_offset != 0x00000000)
- load_IFD(self, buf, buf_len, IFD_offset, swap);
-*/
- return 0;
-}
-
-int GP_ReadExif(GP_IO *io, GP_DataStorage *storage)
-{
- static int swap = 0;
- char b1, b2;
- uint32_t IFD_offset;
-
- uint16_t exif_header[] = {
- 'E', 'x', 'i', 'f', 0, 0, /* EXIF signature */
- GP_IO_BYTE, GP_IO_BYTE, /* Endianity markers II or MM */
- 0x2a, 0x00, /* TIFF tag */
- GP_IO_L4, /* IFD offset */
- GP_IO_END,
- };
-
- if (GP_IOReadF(io, exif_header, &b1, &b2, &IFD_offset) != 11) {
- GP_DEBUG(1, "Failed to read Exif header");
- return 1;
- }
-
- if (b1 != b2 || (b1 != 'I' && b1 != 'M')) {
- GP_WARN("Expected II or MM got %x%x, corrupt header?", b1, b2);
- errno = EINVAL;
- return 1;
- }
-
- swap = (b1 == 'M');
-
- GP_DEBUG(2, "TIFF aligment is '%c%c' swap = %i", b1, b1, swap);
-
- if (swap) {
- //SWAP IFD_offset
- }
-
- GP_DEBUG(2, "IFD offset is 0x%08x", IFD_offset);
-
- if (IFD_offset < 8) {
- GP_WARN("Invalid (negative) IFD offset");
- errno = EINVAL;
- return 1;
- }
-
- GP_DataNode *exif_root = GP_DataStorageAddDict(storage, NULL, "Exif");
-
- /* The offset starts from the II or MM */
- return load_IFD(io, storage, exif_root, IFD_offset - 8, b1);
-}
+static const struct IFD_tags IFD_EXIF_tags = {
+ .tags = IFD_EXIF_taglist,
+ .tag_cnt = GP_ARRAY_SIZE(IFD_EXIF_taglist),
+ .id = "Exif",
+};
diff --git a/libs/loaders/GP_ExifGPS.h b/libs/loaders/GP_ExifGPS.h
new file mode 100644
index 0000000..5e921f7
--- /dev/null
+++ b/libs/loaders/GP_ExifGPS.h
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2014 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+enum IFD_GPS_tags {
+ IFD_GPS_VERSION_ID = 0x0,
+ /* 'N' = North, 'S' = South */
+ IFD_GPS_LATITUDE_REF = 0x1,
+ /* Degrees, Minutes, Seconds */
+ IFD_GPS_LATITUDE = 0x2,
+ /* 'E' = East, 'W' = West */
+ IFD_GPS_LONGITUDE_REF = 0x3,
+ /* Degrees, Minutes, Seconds */
+ IFD_GPS_LONGITUDE = 0x4,
+ /* 0 = Sea level, 1 = Sea level reference (negative value) */
+ IFD_GPS_ALTITUDE_REF = 0x5,
+ /* Altitude in meters */
+ IFD_GPS_ALTITUDE = 0x6,
+ /* Hour, Minute, Second */
+ IFD_GPS_TIMESTAMP = 0x7,
+
+ /* 'TOKYO' or 'WGS-84' */
+ IFD_GPS_MAP_DATUM = 0x12,
+};
+
+/* MUST SORTED BY TAG */
+static const struct IFD_tag IFD_GPS_taglist[] = {
+ {IFD_GPS_VERSION_ID, "Version Info", IFD_UNSIGNED_BYTE, 4},
+ {IFD_GPS_LATITUDE_REF, "Latitude Ref", IFD_ASCII_STRING, 2},
+ {IFD_GPS_LATITUDE, "Latitude", IFD_UNSIGNED_RATIONAL, 3},
+ {IFD_GPS_LONGITUDE_REF, "Longitude Ref", IFD_ASCII_STRING, 2},
+ {IFD_GPS_LONGITUDE, "Longitude", IFD_UNSIGNED_RATIONAL, 3},
+ {IFD_GPS_ALTITUDE_REF, "Altitude Ref", IFD_UNSIGNED_BYTE, 1},
+ {IFD_GPS_ALTITUDE, "Altitude", IFD_UNSIGNED_RATIONAL, 1},
+ {IFD_GPS_TIMESTAMP, "Time Stamp", IFD_UNSIGNED_RATIONAL, 3},
+
+ {IFD_GPS_MAP_DATUM, "Map Datum", IFD_ASCII_STRING, 0},
+};
+
+static const struct IFD_tags IFD_GPS_tags = {
+ .tags = IFD_GPS_taglist,
+ .tag_cnt = GP_ARRAY_SIZE(IFD_GPS_taglist),
+ .id = "GPS",
+};
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_DataStorage.c | 2 +-
libs/loaders/GP_Exif.c | 383 +++++-------------
libs/loaders/{GP_Exif.c => GP_Exif.h} | 462 ++++------------------
tests/loaders/PBM.h => libs/loaders/GP_ExifGPS.h | 67 ++--
4 files changed, 209 insertions(+), 705 deletions(-)
copy libs/loaders/{GP_Exif.c => GP_Exif.h} (53%)
copy tests/loaders/PBM.h => libs/loaders/GP_ExifGPS.h (56%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
08 Feb '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 143e4e08779b9dcd3aeed69e2de28c64d9c3d4d0 (commit)
via 6d6eb1804dbbcf8a8507f2cd2474a3c282a1633b (commit)
from 84df46f7a343005a0edbb3a744e8a62a109864ea (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/143e4e08779b9dcd3aeed69e2de28c64d9c3…
commit 143e4e08779b9dcd3aeed69e2de28c64d9c3d4d0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 10:58:16 2015 +0100
Exif: Add a few more tags.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.c
index f936589..99f49f7 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.c
@@ -174,16 +174,29 @@ enum IFD_tags {
IFD_EXIF_IMAGE_HEIGHT = 0xa003,
/* May store related audio filename */
IFD_RELATED_SOUND_FILE = 0xa004,
+ /* */
+ IFD_FOCAL_PLANE_X_RESOLUTION = 0xa20e,
+ IFD_FOCAL_PLANE_Y_RESOLUTION = 0xa20f,
+ /* 1 = No unit, 2 = Inch (default), 3 = Centimeter */
+ IFD_FOCAL_PLANE_RESOLUTION_UNIT = 0xa210,
/* TODO: enum of sensing methods */
IFD_SENSING_METHOD = 0xa217,
IFD_FILE_SOURCE = 0xa300,
IFD_SCENE_TYPE = 0xa301,
/* 0 = Normal, 1 = Custom */
- IFD_CUSTOM_RENDERER = 0x0a401,
+ IFD_CUSTOM_RENDERER = 0xa401,
/* 0 = Auto, 1 = Manual, 2 = Auto bracket */
- IFD_EXPOSURE_MODE = 0x0a402,
+ IFD_EXPOSURE_MODE = 0xa402,
/* 0 = Auto, 1 = Manual */
- IFD_WHITE_BALANCE = 0x0a403,
+ IFD_WHITE_BALANCE = 0xa403,
+ /* 0 = Standard, 1 = Landscape, 2 = Portrait, 3 = Night Scene */
+ IFD_SCENE_CAPTURE_TYPE = 0xa406,
+ /* 0 = Normal, 1 = Soft, 2 = Hard */
+ IFD_CONTRAST = 0xa408,
+ /* 0 = Normal, 1 = Low Saturation, 2 = Hight Saturation */
+ IFD_SATURATION = 0xa409,
+ /* 0 = Normal, 1 = Sort, 2 = Hard */
+ IFD_SHARPNESS = 0xa40a,
};
struct IFD_tag {
@@ -255,12 +268,19 @@ static const struct IFD_tag IFD_tags[] = {
{IFD_EXIF_IMAGE_WIDTH, "Exif Image Width", IFD_UNSIGNED_LONG, 1},
{IFD_EXIF_IMAGE_HEIGHT, "Exif Image Height", IFD_UNSIGNED_LONG, 1},
{IFD_RELATED_SOUND_FILE, "Related Soundfile", IFD_ASCII_STRING, 0},
+ {IFD_FOCAL_PLANE_X_RESOLUTION, "Focal Plane X Resolution", IFD_UNSIGNED_RATIONAL, 1},
+ {IFD_FOCAL_PLANE_Y_RESOLUTION, "Focal Plane Y Resolution", IFD_UNSIGNED_RATIONAL, 1},
+ {IFD_FOCAL_PLANE_RESOLUTION_UNIT, "Focal Plane Resolution Unit", IFD_UNSIGNED_SHORT, 1},
{IFD_SENSING_METHOD, "Sensing Method", IFD_UNSIGNED_SHORT, 1},
{IFD_FILE_SOURCE, "File Source", IFD_UNDEFINED, 1},
{IFD_SCENE_TYPE, "Scene Type", IFD_UNDEFINED, 1},
{IFD_CUSTOM_RENDERER, "Custom Renderer", IFD_UNSIGNED_SHORT, 1},
{IFD_EXPOSURE_MODE, "Exposure Mode", IFD_UNSIGNED_SHORT, 1},
{IFD_WHITE_BALANCE, "White Balance", IFD_UNSIGNED_SHORT, 1},
+ {IFD_SCENE_CAPTURE_TYPE, "Scene Capture Type", IFD_UNSIGNED_SHORT, 1},
+ {IFD_CONTRAST, "Contrast", IFD_UNSIGNED_SHORT, 1},
+ {IFD_SATURATION, "Saturation", IFD_UNSIGNED_SHORT, 1},
+ {IFD_SHARPNESS, "Sharpness", IFD_UNSIGNED_SHORT, 1},
};
static const char *IFD_format_name(uint16_t format)
http://repo.or.cz/w/gfxprim.git/commit/6d6eb1804dbbcf8a8507f2cd2474a3c282a1…
commit 6d6eb1804dbbcf8a8507f2cd2474a3c282a1633b
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Feb 8 11:26:04 2015 +0100
loaders: DataStorage: Fix segfault.
Fix segfault in GP_DataStorageGetByPath() in debug message that
dereferenced possibly NULL pointer.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_DataStorage.c b/libs/loaders/GP_DataStorage.c
index b6e9db9..cb02425 100644
--- a/libs/loaders/GP_DataStorage.c
+++ b/libs/loaders/GP_DataStorage.c
@@ -320,6 +320,9 @@ static struct GP_DataNode *get_by_path(GP_DataNode *node, const char *path)
node = lookup(node, path, i);
+ if (!node)
+ return NULL;
+
GP_DEBUG(3, "Lookup has node '%s'", node->id);
if (path[i] == '/')
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_DataStorage.c | 3 +++
libs/loaders/GP_Exif.c | 26 +++++++++++++++++++++++---
2 files changed, 26 insertions(+), 3 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
07 Feb '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 84df46f7a343005a0edbb3a744e8a62a109864ea (commit)
via d63cd2b2a46aacac0683b804d887a571a3a1a1a7 (commit)
via fcb2c2cfccb1d7122b5d6683481ac7ed57fc59c2 (commit)
via b71fd317db698aa14a847020003be950257ae83d (commit)
via c440a1bcd759c147b8f2b6739f41f9f94159ce64 (commit)
via 32b937c63052f6686b1d818744f172c8658d4be2 (commit)
via e42857ad289d9333411766b2df90cffea906cf11 (commit)
from 1109c295817003da4e1da28179040c3060dc1326 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/84df46f7a343005a0edbb3a744e8a62a1098…
commit 84df46f7a343005a0edbb3a744e8a62a109864ea
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 7 22:24:13 2015 +0100
spiv: Implement EXIF autorotation
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 75af202..91b1a2a 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -309,7 +309,7 @@ static void update_display(struct loader_params *params, GP_Context *img,
struct cpu_timer timer;
GP_ProgressCallback callback = {.callback = image_loader_callback};
- switch (config.orientation) {
+ switch (config.combined_orientation) {
case ROTATE_0:
break;
case ROTATE_90:
@@ -324,6 +324,8 @@ static void update_display(struct loader_params *params, GP_Context *img,
callback.priv = "Rotating image (270)";
img = GP_FilterRotate270Alloc(img, &callback);
break;
+ default:
+ break;
}
if (img == NULL)
@@ -384,7 +386,7 @@ static void update_display(struct loader_params *params, GP_Context *img,
show_info(params, img, orig_img);
- if (config.orientation)
+ if (config.combined_orientation)
GP_ContextFree(img);
GP_BackendFlip(backend);
@@ -465,6 +467,39 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
return img;
}
+static void exif_autorotate(void)
+{
+ GP_DataNode *orientation;
+
+ config.combined_orientation = config.orientation;
+
+ if (!config.exif_autorotate)
+ return;
+
+ orientation = GP_DataStorageGetByPath(image_loader_get_meta_data(),
+ NULL, "/Exif/Orientation");
+ if (!orientation)
+ return;
+
+ switch (orientation->value.i) {
+ case GP_EXIF_UPPER_LEFT:
+ config.combined_orientation += ROTATE_0;
+ break;
+ case GP_EXIF_LOWER_RIGHT:
+ config.combined_orientation += ROTATE_180;
+ break;
+ case GP_EXIF_UPPER_RIGHT:
+ config.combined_orientation += ROTATE_90;
+ break;
+ case GP_EXIF_LOWER_LEFT:
+ config.combined_orientation += ROTATE_270;
+ break;
+ }
+
+ if (config.combined_orientation > ROTATE_270)
+ config.combined_orientation -= ROTATE_360;
+}
+
static float calc_img_size(struct loader_params *params,
uint32_t img_w, uint32_t img_h,
uint32_t win_w, uint32_t win_h)
@@ -473,7 +508,9 @@ static float calc_img_size(struct loader_params *params,
unsigned int max_win_w = config.max_win_w;
unsigned int max_win_h = config.max_win_h;
- switch (config.orientation) {
+ exif_autorotate();
+
+ switch (config.combined_orientation) {
case ROTATE_90:
case ROTATE_270:
GP_SWAP(win_w, win_h);
@@ -488,7 +525,7 @@ static float calc_img_size(struct loader_params *params,
win_w = GP_MIN(max_win_w, img_w * params->zoom_rat + 0.5);
win_h = GP_MIN(max_win_h, img_h * params->zoom_rat + 0.5);
- switch (config.orientation) {
+ switch (config.combined_orientation) {
case ROTATE_90:
case ROTATE_270:
GP_BackendResize(backend, win_h, win_w);
@@ -527,7 +564,7 @@ static float calc_img_size(struct loader_params *params,
win_h = rat * img_h + 0.5;
}
- switch (config.orientation) {
+ switch (config.combined_orientation) {
case ROTATE_90:
case ROTATE_270:
GP_BackendResize(backend, win_h, win_w);
@@ -885,13 +922,13 @@ int main(int argc, char *argv[])
config.orientation++;
if (config.orientation > ROTATE_270)
- config.orientation = 0;
+ config.orientation = ROTATE_0;
params.show_progress_once = 1;
show_image(¶ms);
break;
case GP_KEY_E:
- if (config.orientation > 0)
+ if (config.orientation > ROTATE_0)
config.orientation--;
else
config.orientation = ROTATE_270;
diff --git a/demos/spiv/spiv_config.c b/demos/spiv/spiv_config.c
index 6fa95f4..73db91b 100644
--- a/demos/spiv/spiv_config.c
+++ b/demos/spiv/spiv_config.c
@@ -39,6 +39,7 @@ struct spiv_config config = {
.zoom_strategy = ZOOM_IMAGE_DOWNSCALE,
.win_strategy = ZOOM_WIN_FIXED,
.full_screen = 0,
+ .exif_autorotate = 1,
.max_win_w = 1024,
.max_win_h = 768,
@@ -132,6 +133,9 @@ static int set_opt(struct cfg_opt *self, unsigned int lineno)
case 't':
config.timers = 1;
break;
+ case 'r':
+ config.exif_autorotate = 0;
+ break;
}
return 0;
@@ -339,6 +343,14 @@ struct cfg_opt spiv_opts[] = {
.help = "Orientation, one of 0, 90, 180, 270",
},
{.name_space = "Gui",
+ .key = "DisableExifAutorotate",
+ .opt = 'r',
+ .opt_long = "disable_exif_autorotate",
+ .opt_has_value = 0,
+ .set = set_opt,
+ .help = "Disables automatic rotation by EXIF",
+ },
+ {.name_space = "Gui",
.key = "FullScreen",
.opt = 'f',
.opt_long = "full-screen",
diff --git a/demos/spiv/spiv_config.h b/demos/spiv/spiv_config.h
index 144ec6e..e8c713d 100644
--- a/demos/spiv/spiv_config.h
+++ b/demos/spiv/spiv_config.h
@@ -30,6 +30,7 @@ enum orientation {
ROTATE_90,
ROTATE_180,
ROTATE_270,
+ ROTATE_360,
};
enum zoom_strategy {
@@ -46,7 +47,10 @@ enum zoom_strategy {
struct spiv_config {
float slideshow_delay;
+ /* orientation set by user */
enum orientation orientation;
+ /* combined orientation (user orientation + EXIF rotation) */
+ enum orientation combined_orientation;
int win_strategy:2;
int zoom_strategy:2;
/* Maximal window size */
@@ -58,6 +62,7 @@ struct spiv_config {
int floyd_steinberg:1;
int timers:1;
int full_screen:1;
+ int exif_autorotate:1;
char backend_init[128];
GP_PixelType emul_type;
http://repo.or.cz/w/gfxprim.git/commit/d63cd2b2a46aacac0683b804d887a571a3a1…
commit d63cd2b2a46aacac0683b804d887a571a3a1a1a7
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 7 22:02:37 2015 +0100
DataStorage: Implement GP_DataStorageGetByPath()
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 79ada50..5f8d749 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -154,6 +154,7 @@ GP_DataStorageClear
GP_DataStorageRoot
GP_DataDictFirst
GP_DataStorageGet
+GP_DataStorageGetByPath
GP_DataStorageAdd
GP_DataStorageAddInt
GP_DataStorageAddDouble
diff --git a/include/loaders/GP_DataStorage.h b/include/loaders/GP_DataStorage.h
index e8b3279..4ad9705 100644
--- a/include/loaders/GP_DataStorage.h
+++ b/include/loaders/GP_DataStorage.h
@@ -108,6 +108,17 @@ GP_DataNode *GP_DataStorageGet(GP_DataStorage *self,
GP_DataNode *node, const char *id);
/*
+ * Returns data node by a path in the data storage.
+ *
+ * Example path: "/Exif/Orientation"
+ *
+ * The path works like filesystem path. The equivalent to working
+ * directory is the node pointer.
+ */
+GP_DataNode *GP_DataStorageGetByPath(GP_DataStorage *self, GP_DataNode *node,
+ const char *path);
+
+/*
* Adds data into a dict.
*
* If node is NULL, data storage root is used.
diff --git a/include/loaders/GP_Exif.h b/include/loaders/GP_Exif.h
index f00cb69..5f42973 100644
--- a/include/loaders/GP_Exif.h
+++ b/include/loaders/GP_Exif.h
@@ -42,4 +42,14 @@ int GP_ReadExif(GP_IO *io, GP_DataStorage *storage);
*/
int GP_MatchExif(const void *buf);
+/*
+ * Defines position to 0,0 coordinate.
+ */
+enum GP_EXIF_ORIENTATION {
+ GP_EXIF_UPPER_LEFT = 1,
+ GP_EXIF_LOWER_RIGHT = 3,
+ GP_EXIF_UPPER_RIGHT = 6,
+ GP_EXIF_LOWER_LEFT = 8,
+};
+
#endif /* LOADERS_GP_EXIF_H */
diff --git a/libs/loaders/GP_DataStorage.c b/libs/loaders/GP_DataStorage.c
index 2257699..b6e9db9 100644
--- a/libs/loaders/GP_DataStorage.c
+++ b/libs/loaders/GP_DataStorage.c
@@ -293,6 +293,60 @@ GP_DataNode *GP_DataStorageGet(GP_DataStorage *self,
return NULL;
}
+static struct GP_DataNode *lookup(GP_DataNode *node, const char *id,
+ const int id_len)
+{
+ struct GP_DataNode *i;
+
+ if (!node)
+ return NULL;
+
+ for (i = GP_DataDictFirst(node); i; i = i->next) {
+ if (!strncmp(i->id, id, id_len))
+ return i;
+ }
+
+ return NULL;
+}
+
+static struct GP_DataNode *get_by_path(GP_DataNode *node, const char *path)
+{
+ unsigned int i;
+
+ for (i = 0; path[i] && path[i] != '/'; i++);
+
+ if (!i)
+ return node;
+
+ node = lookup(node, path, i);
+
+ GP_DEBUG(3, "Lookup has node '%s'", node->id);
+
+ if (path[i] == '/')
+ path++;
+
+ path+=i;
+
+ return get_by_path(node, path);
+}
+
+GP_DataNode *GP_DataStorageGetByPath(GP_DataStorage *self, GP_DataNode *node,
+ const char *path)
+{
+ GP_DEBUG(3, "Looking for '%s' in %p", path, node);
+
+ if (path[0] == '/') {
+
+ if (!self)
+ return NULL;
+
+ node = GP_DataStorageRoot(self);
+ path++;
+ }
+
+ return get_by_path(node, path);
+}
+
static void padd_printf(size_t padd, const char *id, size_t id_padd,
const char *fmt, ...)
http://repo.or.cz/w/gfxprim.git/commit/fcb2c2cfccb1d7122b5d6683481ac7ed57fc…
commit fcb2c2cfccb1d7122b5d6683481ac7ed57fc59c2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jan 25 21:28:40 2015 +0100
backends: X11: Catch UnmapNotify events.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/backends/GP_X11_Input.h b/libs/backends/GP_X11_Input.h
index c4364b4..6305874 100644
--- a/libs/backends/GP_X11_Input.h
+++ b/libs/backends/GP_X11_Input.h
@@ -276,6 +276,9 @@ static void x11_input_event_put(struct GP_EventQueue *event_queue,
case GravityNotify:
GP_DEBUG(1, "GravityNotify event received");
break;
+ case UnmapNotify:
+ GP_DEBUG(1, "UnmapNotify event received");
+ break;
default:
GP_WARN("Unhandled X11 event type %u", ev->type);
}
http://repo.or.cz/w/gfxprim.git/commit/b71fd317db698aa14a847020003be950257a…
commit b71fd317db698aa14a847020003be950257ae83d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 17:20:51 2015 +0100
bogoman: Do screenshot on pressing s key.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/bogoman/Makefile b/demos/bogoman/Makefile
index a448fee..c998522 100644
--- a/demos/bogoman/Makefile
+++ b/demos/bogoman/Makefile
@@ -4,7 +4,7 @@ include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
INCLUDE=
-LDLIBS+=-lgfxprim-backends
+LDLIBS+=-lgfxprim-backends -lgfxprim-loaders
APPS=bogoman
diff --git a/demos/bogoman/bogoman.c b/demos/bogoman/bogoman.c
index a83cba3..36402c8 100644
--- a/demos/bogoman/bogoman.c
+++ b/demos/bogoman/bogoman.c
@@ -62,6 +62,8 @@ static struct GP_Backend *backend;
static void event_loop(struct bogoman_render *render, GP_Backend *backend)
{
struct bogoman_map *map = render->map;
+ char path[128];
+ static int screenshots;
while (GP_BackendEventsQueued(backend)) {
GP_Event ev;
@@ -90,6 +92,11 @@ static void event_loop(struct bogoman_render *render, GP_Backend *backend)
case GP_KEY_DOWN:
bogoman_map_player_move(map, 0, 1);
break;
+ case GP_KEY_S:
+ snprintf(path, sizeof(path),
+ "screenshot%04i.png", screenshots++);
+ save_png(map, render->map_elem_size, path);
+ break;
}
bogoman_render(render, BOGOMAN_RENDER_DIRTY);
break;
http://repo.or.cz/w/gfxprim.git/commit/c440a1bcd759c147b8f2b6739f41f9f94159…
commit c440a1bcd759c147b8f2b6739f41f9f94159ce64
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 16:48:19 2015 +0100
build: Add missing histogram symbol.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Filters_symbols.txt b/build/syms/Filters_symbols.txt
index 4304919..52e078f 100644
--- a/build/syms/Filters_symbols.txt
+++ b/build/syms/Filters_symbols.txt
@@ -59,6 +59,7 @@ GP_FilterHLinearConvolution_Raw
GP_FilterHistogram
GP_HistogramAlloc
GP_HistogramFree
+GP_HistogramChannelByName
GP_FilterKernelPrint_Raw
http://repo.or.cz/w/gfxprim.git/commit/32b937c63052f6686b1d818744f172c8658d…
commit 32b937c63052f6686b1d818744f172c8658d4be2
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 16:44:18 2015 +0100
core: Get rid of GP_Color.
Special thanks to coccinelle and spatch for making this easy job. :)
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Core_symbols.txt b/build/syms/Core_symbols.txt
index 902dbdb..47acec5 100644
--- a/build/syms/Core_symbols.txt
+++ b/build/syms/Core_symbols.txt
@@ -28,8 +28,6 @@ GP_SetDebugHandler
GP_PrintAbortInfo
-GP_ColorToPixel
-GP_ColorLoadPixels
GP_RGBA8888ToPixel
GP_PixelRGBMatch
GP_PixelTypeByName
@@ -63,9 +61,6 @@ GP_PutPixel
GP_GetPixel
GP_PixelRGBLookup
GP_PixelToRGB888
-GP_ColorNameToPixel
-GP_ColorNameToColor
-GP_ColorToColorName
GP_PixelToRGBA8888
GP_Fill
diff --git a/demos/c_simple/SDL_glue.c b/demos/c_simple/SDL_glue.c
index a613159..8e9e216 100644
--- a/demos/c_simple/SDL_glue.c
+++ b/demos/c_simple/SDL_glue.c
@@ -102,8 +102,8 @@ int main(void)
GP_ContextFromSDLSurface(&context, display);
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, &context);
- darkgray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, &context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, &context);
+ darkgray_pixel = GP_RGBToContextPixel(0x7f, 0x7f, 0x7f, &context);
redraw_screen();
SDL_Flip(display);
diff --git a/demos/c_simple/backend_example.c b/demos/c_simple/backend_example.c
index 651ffff..5e87ff1 100644
--- a/demos/c_simple/backend_example.c
+++ b/demos/c_simple/backend_example.c
@@ -34,8 +34,8 @@ static void redraw(GP_Backend *self)
GP_Context *context = self->context;
GP_Pixel white_pixel, black_pixel;
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
GP_Fill(context, black_pixel);
GP_Line(context, 0, 0, context->w - 1, context->h - 1, white_pixel);
diff --git a/demos/c_simple/backend_timers_example.c b/demos/c_simple/backend_timers_example.c
index 8d860e5..7b7aae2 100644
--- a/demos/c_simple/backend_timers_example.c
+++ b/demos/c_simple/backend_timers_example.c
@@ -32,7 +32,7 @@
static void redraw(GP_Backend *self)
{
GP_Context *context = self->context;
- GP_Pixel black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
+ GP_Pixel black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
GP_Fill(context, black_pixel);
diff --git a/demos/c_simple/blittest.c b/demos/c_simple/blittest.c
index c6cd275..ecdb39a 100644
--- a/demos/c_simple/blittest.c
+++ b/demos/c_simple/blittest.c
@@ -174,8 +174,8 @@ int main(void)
win->context->pixel_type);
change_bitmap();
- black = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
- white = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, win->context);
+ white = GP_RGBToContextPixel(0xff, 0xff, 0xff, win->context);
GP_Fill(win->context, black);
GP_BackendFlip(win);
diff --git a/demos/c_simple/fileview.c b/demos/c_simple/fileview.c
index 2d06dae..972514b 100644
--- a/demos/c_simple/fileview.c
+++ b/demos/c_simple/fileview.c
@@ -263,12 +263,12 @@ int main(int argc, char *argv[])
win = backend->context;
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, win);
- gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, win);
- dark_gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, win);
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, win);
- red_pixel = GP_ColorToContextPixel(GP_COL_RED, win);
- blue_pixel = GP_ColorToContextPixel(GP_COL_BLUE, win);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, win);
+ gray_pixel = GP_RGBToContextPixel(0xbe, 0xbe, 0xbe, win);
+ dark_gray_pixel = GP_RGBToContextPixel(0x7f, 0x7f, 0x7f, win);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, win);
+ red_pixel = GP_RGBToContextPixel(0xff, 0x00, 0x00, win);
+ blue_pixel = GP_RGBToContextPixel(0x00, 0x00, 0xff, win);
redraw_screen();
GP_BackendFlip(backend);
diff --git a/demos/c_simple/fonttest.c b/demos/c_simple/fonttest.c
index 4e33020..9a3aff1 100644
--- a/demos/c_simple/fonttest.c
+++ b/demos/c_simple/fonttest.c
@@ -277,12 +277,12 @@ int main(int argc, char *argv[])
return 1;
}
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
- gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, win->context);
- dark_gray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, win->context);
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
- red_pixel = GP_ColorToContextPixel(GP_COL_RED, win->context);
- blue_pixel = GP_ColorToContextPixel(GP_COL_BLUE, win->context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, win->context);
+ gray_pixel = GP_RGBToContextPixel(0xbe, 0xbe, 0xbe, win->context);
+ dark_gray_pixel = GP_RGBToContextPixel(0x7f, 0x7f, 0x7f, win->context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, win->context);
+ red_pixel = GP_RGBToContextPixel(0xff, 0x00, 0x00, win->context);
+ blue_pixel = GP_RGBToContextPixel(0x00, 0x00, 0xff, win->context);
redraw_screen();
GP_BackendFlip(win);
diff --git a/demos/c_simple/input_example.c b/demos/c_simple/input_example.c
index 3b94ce3..3a294d2 100644
--- a/demos/c_simple/input_example.c
+++ b/demos/c_simple/input_example.c
@@ -150,10 +150,10 @@ int main(int argc, char *argv[])
win = backend->context;
- red = GP_ColorToContextPixel(GP_COL_RED, win);
- green = GP_ColorToContextPixel(GP_COL_GREEN, win);
- white = GP_ColorToContextPixel(GP_COL_WHITE, win);
- black = GP_ColorToContextPixel(GP_COL_BLACK, win);
+ red = GP_RGBToContextPixel(0xff, 0x00, 0x00, win);
+ green = GP_RGBToContextPixel(0x00, 0xff, 0x00, win);
+ white = GP_RGBToContextPixel(0xff, 0xff, 0xff, win);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, win);
GP_Fill(win, black);
GP_BackendFlip(backend);
diff --git a/demos/c_simple/koch.c b/demos/c_simple/koch.c
index 335815d..5bb1538 100644
--- a/demos/c_simple/koch.c
+++ b/demos/c_simple/koch.c
@@ -138,10 +138,10 @@ int main(void)
context = backend->context;
- black = GP_ColorToContextPixel(GP_COL_BLACK, context);
- blue = GP_ColorToContextPixel(GP_COL_BLUE, context);
- gray = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, context);
- red = GP_ColorToContextPixel(GP_COL_RED, context);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ blue = GP_RGBToContextPixel(0x00, 0x00, 0xff, context);
+ gray = GP_RGBToContextPixel(0xbe, 0xbe, 0xbe, context);
+ red = GP_RGBToContextPixel(0xff, 0x00, 0x00, context);
iter = 0;
draw(context->w/2, context->h/2, l, iter);
diff --git a/demos/c_simple/linetest.c b/demos/c_simple/linetest.c
index 1df6e6e..19a0244 100644
--- a/demos/c_simple/linetest.c
+++ b/demos/c_simple/linetest.c
@@ -135,8 +135,8 @@ int main(int argc, char *argv[])
return 1;
}
- white = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
- black = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
+ white = GP_RGBToContextPixel(0xff, 0xff, 0xff, win->context);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, win->context);
redraw_screen();
diff --git a/demos/c_simple/randomshapetest.c b/demos/c_simple/randomshapetest.c
index f3dbaa1..e5f4e5d 100644
--- a/demos/c_simple/randomshapetest.c
+++ b/demos/c_simple/randomshapetest.c
@@ -268,8 +268,8 @@ int main(void)
return 1;
}
- white = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
- black = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
+ white = GP_RGBToContextPixel(0xff, 0xff, 0xff, win->context);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, win->context);
for (;;) {
GP_BackendPoll(win);
diff --git a/demos/c_simple/shapetest.c b/demos/c_simple/shapetest.c
index db32938..b114fd8 100644
--- a/demos/c_simple/shapetest.c
+++ b/demos/c_simple/shapetest.c
@@ -505,13 +505,13 @@ int main(int argc, char *argv[])
center_y = win->h / 2;
/* Load colors compatible with the display */
- black = GP_ColorToContextPixel(GP_COL_BLACK, win);
- white = GP_ColorToContextPixel(GP_COL_WHITE, win);
- yellow = GP_ColorToContextPixel(GP_COL_YELLOW, win);
- green = GP_ColorToContextPixel(GP_COL_GREEN, win);
- red = GP_ColorToContextPixel(GP_COL_RED, win);
- gray = GP_ColorToContextPixel(GP_COL_GRAY_LIGHT, win);
- darkgray = GP_ColorToContextPixel(GP_COL_GRAY_DARK, win);
+ black = GP_RGBToContextPixel(0x00, 0x00, 0x00, win);
+ white = GP_RGBToContextPixel(0xff, 0xff, 0xff, win);
+ yellow = GP_RGBToContextPixel(0xff, 0xff, 0x00, win);
+ green = GP_RGBToContextPixel(0x00, 0xff, 0x00, win);
+ red = GP_RGBToContextPixel(0xff, 0x00, 0x00, win);
+ gray = GP_RGBToContextPixel(0xbe, 0xbe, 0xbe, win);
+ darkgray = GP_RGBToContextPixel(0x7f, 0x7f, 0x7f, win);
print_instructions();
redraw_screen();
diff --git a/demos/c_simple/textaligntest.c b/demos/c_simple/textaligntest.c
index 70b2fd2..5e2fbd6 100644
--- a/demos/c_simple/textaligntest.c
+++ b/demos/c_simple/textaligntest.c
@@ -181,13 +181,13 @@ int main(int argc, char *argv[])
return 1;
}
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, win->context);
- red_pixel = GP_ColorToContextPixel(GP_COL_RED, win->context);
- blue_pixel = GP_ColorToContextPixel(GP_COL_BLUE, win->context);
- green_pixel = GP_ColorToContextPixel(GP_COL_GREEN, win->context);
- yellow_pixel = GP_ColorToContextPixel(GP_COL_YELLOW, win->context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, win->context);
- darkgray_pixel = GP_ColorToContextPixel(GP_COL_GRAY_DARK, win->context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, win->context);
+ red_pixel = GP_RGBToContextPixel(0xff, 0x00, 0x00, win->context);
+ blue_pixel = GP_RGBToContextPixel(0x00, 0x00, 0xff, win->context);
+ green_pixel = GP_RGBToContextPixel(0x00, 0xff, 0x00, win->context);
+ yellow_pixel = GP_RGBToContextPixel(0xff, 0xff, 0x00, win->context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, win->context);
+ darkgray_pixel = GP_RGBToContextPixel(0x7f, 0x7f, 0x7f, win->context);
redraw_screen();
GP_BackendFlip(win);
diff --git a/demos/c_simple/virtual_backend_example.c b/demos/c_simple/virtual_backend_example.c
index 925a3d6..5ef5a8e 100644
--- a/demos/c_simple/virtual_backend_example.c
+++ b/demos/c_simple/virtual_backend_example.c
@@ -93,11 +93,11 @@ int main(int argc, char *argv[])
context = backend->context;
/* Now draw some testing patters */
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
- red_pixel = GP_ColorToContextPixel(GP_COL_RED, context);
- blue_pixel = GP_ColorToContextPixel(GP_COL_BLUE, context);
- green_pixel = GP_ColorToContextPixel(GP_COL_GREEN, context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
+ red_pixel = GP_RGBToContextPixel(0xff, 0x00, 0x00, context);
+ blue_pixel = GP_RGBToContextPixel(0x00, 0x00, 0xff, context);
+ green_pixel = GP_RGBToContextPixel(0x00, 0xff, 0x00, context);
GP_Fill(context, white_pixel);
diff --git a/demos/c_simple/x11_windows.c b/demos/c_simple/x11_windows.c
index fa52cc2..1c5b2d0 100644
--- a/demos/c_simple/x11_windows.c
+++ b/demos/c_simple/x11_windows.c
@@ -33,8 +33,8 @@ static void redraw(struct GP_Context *context)
{
GP_Pixel white_pixel, black_pixel;
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
GP_Fill(context, black_pixel);
GP_Line(context, 0, 0, context->w - 1, context->h - 1, white_pixel);
diff --git a/demos/particle/particle_demo.c b/demos/particle/particle_demo.c
index 2b902a0..46fafe2 100644
--- a/demos/particle/particle_demo.c
+++ b/demos/particle/particle_demo.c
@@ -90,8 +90,8 @@ int main(int argc, char *argv[])
context = backend->context;
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
GP_Fill(context, black_pixel);
GP_BackendFlip(backend);
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 40a5687..75af202 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -818,8 +818,8 @@ int main(int argc, char *argv[])
context = backend->context;
- black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+ black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
gray_pixel = GP_RGBToContextPixel(0x33, 0x33, 0x33, context);
GP_Fill(context, black_pixel);
diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c
index ef1f0c5..2d7eac9 100644
--- a/demos/spiv/spiv_help.c
+++ b/demos/spiv/spiv_help.c
@@ -235,8 +235,8 @@ static int last_line;
static int redraw_help(GP_Backend *backend, unsigned int loff, GP_Coord xoff)
{
GP_Context *c = backend->context;
- GP_Pixel black = GP_ColorToContextPixel(GP_COL_BLACK, c);
- GP_Pixel white = GP_ColorToContextPixel(GP_COL_WHITE, c);
+ GP_Pixel black = GP_RGBToContextPixel(0x00, 0x00, 0x00, c);
+ GP_Pixel white = GP_RGBToContextPixel(0xff, 0xff, 0xff, c);
int i;
int spacing = GP_TextHeight(config.style)/10 + 2;
diff --git a/demos/ttf2img/ttf2img.c b/demos/ttf2img/ttf2img.c
index 9bc4558..deaa37a 100644
--- a/demos/ttf2img/ttf2img.c
+++ b/demos/ttf2img/ttf2img.c
@@ -76,8 +76,8 @@ int main(int argc, char *argv[])
GP_Context *context = GP_ContextAlloc(img_w, img_h, GP_PIXEL_RGB888);
- GP_Pixel black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
- GP_Pixel white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+ GP_Pixel black_pixel = GP_RGBToContextPixel(0x00, 0x00, 0x00, context);
+ GP_Pixel white_pixel = GP_RGBToContextPixel(0xff, 0xff, 0xff, context);
GP_Fill(context, white_pixel);
diff --git a/doc/basic_types.txt b/doc/basic_types.txt
index 11ff214..3b6c6fd 100644
--- a/doc/basic_types.txt
+++ b/doc/basic_types.txt
@@ -17,75 +17,3 @@ values. The default typedef for 'GP_Pixel' is set to 32 bit integer, which may
be changed at compile time to support colors with more than 10 bits per
channel. The 'GP_Pixel' is thus used as opaque value big enough to hold any
supported pixel value.
-
-[[Color]]
-Color
-~~~~~
-
-The 'GP_Color' enumeration holds symbolic constants for basic colors.
-
-A 'GP_Color' can be converted into a 'GP_Pixel' for a given 'GP_PixelType'.
-Symbolic values can also be converted to/from strings (color name in English).
-
-The 'GP_Color' enum is defined as follows:
-
-[source,c]
---------------------------------------------------------------------------------
-typedef enum GP_Color {
- GP_COL_INVALID = -1,
-
- /* full-intensity RGB and CMYK */
- GP_COL_BLACK,
- GP_COL_RED,
- GP_COL_GREEN,
- GP_COL_BLUE,
- GP_COL_YELLOW,
- GP_COL_CYAN,
- GP_COL_MAGENTA,
-
- /* various common mixes */
- GP_COL_BROWN,
- GP_COL_ORANGE,
- GP_COL_GRAY_DARK, /* exactly half RGB values of white */
- GP_COL_GRAY_LIGHT,
- GP_COL_PURPLE,
-
- GP_COL_WHITE, /* full-intensity white */
- GP_COL_MAX,
-} GP_Color;
---------------------------------------------------------------------------------
-
-[source,c]
---------------------------------------------------------------------------------
-#include <core/GP_Color.h>
-/* or */
-#include <GP.h>
-
-GP_Pixel GP_ColorToPixel(GP_Color color, GP_PixelType pixel_type);
-GP_Pixel GP_ColorToContextPixel(GP_Color color, GP_Context *context);
-
-GP_Color GP_ColorNameToColor(const char *color_name);
-const char *GP_ColorToColorName(GP_Color color);
-
-bool GP_ColorNameToPixel(const char *color_name, GP_PixelType pixel_type,
- GP_Pixel *pixel);
-bool GP_ColorNameToContextPixel(const char *color_name, GP_Context *context,
- GP_Pixel *pixel);
---------------------------------------------------------------------------------
-
-Functions for conversion between colors, pixels and color names. The last two
-returns true if color with such name was found.
-
-[source,c]
---------------------------------------------------------------------------------
-#include <core/GP_Color.h>
-/* or */
-#include <GP.h>
-
-void GP_ColorLoadPixels(GP_Pixel pixels[], GP_PixelType pixel_type);
-void GP_ColorLoadContextPixels(GP_Pixel pixels[], GP_Context *context);
---------------------------------------------------------------------------------
-
-Loads array of 'GP_Pixel' of size 'GP_COL_MAX', the array is then used with
-the GP_Color enum as 'pixels[GP_COL_BLACK]'.
-
diff --git a/doc/convert.txt b/doc/convert.txt
index 9191805..f11f932 100644
--- a/doc/convert.txt
+++ b/doc/convert.txt
@@ -3,8 +3,6 @@ Pixel Conversions
This page describes RGB tripplet to pixels conversions.
-See also link:basic_types.html#Color[colors].
-
[source,c]
-------------------------------------------------------------------------------
#include <GP.h>
diff --git a/doc/core_python.txt b/doc/core_python.txt
index 487b903..108c859 100644
--- a/doc/core_python.txt
+++ b/doc/core_python.txt
@@ -101,15 +101,13 @@ Blit is clipped.
TIP: See link:example_py_showimage.html[example Blit usage].
-[[Colors_and_Pixels]]
-Colors and Pixels
-~~~~~~~~~~~~~~~~~
+[[Pixels]]
+Pixels
+~~~~~~
Pixel in GFXprim is a number large enough to store a pixel value. Pixel is
passed as a parameter to all drawing functions.
-Color is a more abstract representation for example RGB triplet.
-
There are several functions to create a pixel value for a particular pixel
type from color.
@@ -128,7 +126,6 @@ import gfxprim.core as core
These functions creates a pixel suitable for drawing into a bitmap with
particular pixel type.
-
[source,python]
-------------------------------------------------------------------------------
import gfxprim.core as core
diff --git a/include/core/GP_Color.h b/include/core/GP_Color.h
deleted file mode 100644
index de87e6a..0000000
--- a/include/core/GP_Color.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
- /*
-
- Color is enumeration of color names which may be converted into pixel values
- in desired pixel format.
-
- */
-
-#ifndef GP_COLOR_H
-#define GP_COLOR_H
-
-#include "GP_Context.h"
-#include "GP_Pixel.h"
-
-/*
- * Enumeration of color constants.
- */
-typedef enum GP_Color {
- GP_COL_INVALID = -1,
- GP_COL_BLACK,
- GP_COL_RED,
- GP_COL_GREEN,
- GP_COL_BLUE,
- GP_COL_YELLOW,
- GP_COL_CYAN,
- GP_COL_MAGENTA,
- GP_COL_BROWN,
- GP_COL_ORANGE,
- GP_COL_GRAY_DARK,
- GP_COL_GRAY_LIGHT,
- GP_COL_PURPLE,
- GP_COL_WHITE,
- GP_COL_MAX,
-} GP_Color;
-
-/*
- * Converts GP_Color to GP_Pixel.
- */
-GP_Pixel GP_ColorToPixel(GP_Color color, GP_PixelType pixel_type);
-
-/*
- * Converts GP_Color to GP_Pixel.
- */
-static inline GP_Pixel GP_ColorToContextPixel(GP_Color color,
- GP_Context *context)
-{
- return GP_ColorToPixel(color, context->pixel_type);
-}
-
-/*
- * Converts Color name (eg. string) to GP_Color.
- */
-GP_Color GP_ColorNameToColor(const char *color_name);
-
-/*
- * Converts GP_Color to color name.
- *
- * If color is not valid NULL is returned.
- */
-const char *GP_ColorToColorName(GP_Color color);
-
-/*
- * Converts Color name to Pixel.
- *
- * Returns true if conversion was successful false otherwise.
- */
-bool GP_ColorNameToPixel(const char *color_name, GP_PixelType pixel_type,
- GP_Pixel *pixel);
-
-/*
- * Converts Color name to Pixel.
- *
- * Returns true if conversion was successful false otherwise.
- */
-static inline bool GP_ColorNameToContextPixel(const char *color_name,
- GP_Context *context,
- GP_Pixel *pixel)
-{
- return GP_ColorNameToPixel(color_name, context->pixel_type, pixel);
-}
-
-/*
- * Loads all colors into array of GP_Pixel of size GP_COL_MAX.
- *
- * The colors are then used as pixels[GP_COL_XXX];
- */
-void GP_ColorLoadPixels(GP_Pixel pixels[], GP_PixelType pixel_type);
-
-/*
- * Loads all colors into array of GP_Pixel of size GP_COL_MAX.
- *
- * The colors are then used as pixels[GP_COL_XXX];
- */
-static inline void GP_ColorLoadContextPixels(GP_Pixel pixels[],
- GP_Context *context)
-{
- GP_ColorLoadPixels(pixels, context->pixel_type);
-}
-
-#endif /* GP_COLOR_H */
diff --git a/include/core/GP_Core.h b/include/core/GP_Core.h
index b9f1b6a..bef6834 100644
--- a/include/core/GP_Core.h
+++ b/include/core/GP_Core.h
@@ -65,9 +65,6 @@
/* Debug and debug level */
#include "core/GP_Debug.h"
-/* Color */
-#include "core/GP_Color.h"
-
/* Progress callback */
#include "core/GP_ProgressCallback.h"
diff --git a/libs/core/GP_Color.c b/libs/core/GP_Color.c
deleted file mode 100644
index 2c42d4a..0000000
--- a/libs/core/GP_Color.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <stdint.h>
-#include <string.h>
-
-#include "GP_Convert.h"
-
-#include "GP_Color.h"
-
-
-static char *color_names[] = {
- "Black",
- "Red",
- "Green",
- "Blue",
- "Yellow",
- "Cyan",
- "Magenta",
- "Brown",
- "Orange",
- "DarkGray",
- "LightGray",
- "Purple",
- "White"
-};
-
-static uint8_t rgb888_colors[][3] = {
- {0x00, 0x00, 0x00}, /* Black */
- {0xff, 0x00, 0x00}, /* Red */
- {0x00, 0xff, 0x00}, /* Green */
- {0x00, 0x00, 0xff}, /* Blue */
- {0xff, 0xff, 0x00}, /* Yellow */
- {0x00, 0xff, 0xff}, /* Cyan */
- {0xff, 0x00, 0xff}, /* Magenta */
- {0xa5, 0x2a, 0x2a}, /* Brown */
- {0xff, 0xa5, 0x00}, /* Orange */
- {0x7f, 0x7f, 0x7f}, /* DarkGray */
- {0xbe, 0xbe, 0xbe}, /* LightGray */
- {0xa0, 0x20, 0xf0}, /* Purple */
- {0xff, 0xff, 0xff}, /* White */
-};
-
-/* 3-2-3 RGB palette */
-static uint8_t p8_colors[] = {
- 0x00, /* Black */
- 0xe0, /* Red */
- 0x1c, /* Green */
- 0x03, /* Blue */
- 0xfc, /* Yellow */
- 0x1f, /* Cyan */
- 0xe7, /* Magenta */
- 0x88, /* Brown */
- 0xf0, /* Orange */
- 0x49, /* DarkGray */
- 0x92, /* LightGray */
- 0x8a, /* Purple */
- 0xff, /* White */
-};
-
-GP_Pixel GP_ColorToPixel(GP_Color color, GP_PixelType pixel_type)
-{
- GP_ASSERT(color < GP_COL_MAX);
- GP_ASSERT(color >= 0);
-
- if (pixel_type == GP_PIXEL_P8)
- return p8_colors[color];
-
- return GP_RGBToPixel(rgb888_colors[color][0],
- rgb888_colors[color][1],
- rgb888_colors[color][2],
- pixel_type);
-}
-
-GP_Color GP_ColorNameToColor(const char *color_name)
-{
- unsigned int i;
-
- for (i = 0; i < GP_COL_MAX; i++)
- if (!strcasecmp(color_name, color_names[i]))
- return i;
-
- return -1;
-}
-
-const char *GP_ColorToColorName(GP_Color color)
-{
- if (color < 0 || color >= GP_COL_MAX)
- return NULL;
-
- return color_names[color];
-}
-
-bool GP_ColorNameToPixel(const char *color_name, GP_PixelType pixel_type,
- GP_Pixel *pixel)
-{
- GP_Color color = GP_ColorNameToColor(color_name);
-
- if (color == GP_COL_INVALID)
- return false;
-
- *pixel = GP_ColorToPixel(color, pixel_type);
-
- return true;
-}
-
-void GP_ColorLoadPixels(GP_Pixel pixels[], GP_PixelType pixel_type)
-{
- unsigned int i;
-
- for (i = 0; i < GP_COL_MAX; i++)
- pixels[i] = GP_ColorToPixel(i, pixel_type);
-}
diff --git a/pylib/gfxprim/core/core.i b/pylib/gfxprim/core/core.i
index ff0c062..b0aff17 100644
--- a/pylib/gfxprim/core/core.i
+++ b/pylib/gfxprim/core/core.i
@@ -28,12 +28,8 @@
%include "GP_Debug.h"
/*
- * Color and pixel types
+ * Pixel types
*/
-
-ERROR_ON_NULL(GP_ColorToColorName);
-
-%include "GP_Color.h"
%include "GP_Pixel.h"
%include "GP_Pixel.gen.h" /* Includes enum GP_PixelType definition */
%include "GP_Convert.h"
http://repo.or.cz/w/gfxprim.git/commit/e42857ad289d9333411766b2df90cffea906…
commit e42857ad289d9333411766b2df90cffea906cf11
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 16:14:38 2015 +0100
spiv: Add support for metadata viewer.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/spiv/image_cache.c b/demos/spiv/image_cache.c
index c030405..5f270a8 100644
--- a/demos/spiv/image_cache.c
+++ b/demos/spiv/image_cache.c
@@ -27,6 +27,7 @@
struct image {
GP_Context *ctx;
+ GP_DataStorage *meta_data;
struct image *prev;
struct image *next;
@@ -72,15 +73,23 @@ size_t image_cache_get_ram_size(void)
/*
* Reports correct image record size.
*/
-static size_t image_size2(GP_Context *ctx, const char *path)
+static size_t image_size2(GP_Context *ctx, GP_DataStorage *meta_data,
+ const char *path)
{
- return ctx->bytes_per_row * ctx->h + sizeof(GP_Context) +
+ size_t meta_data_size = 0;
+ size_t context_size = ctx->bytes_per_row * ctx->h + sizeof(GP_Context);
+
+ //TODO! 4096 is a size of single block, data storage may have more blocks
+ if (meta_data)
+ meta_data_size = 4096;
+
+ return meta_data_size + context_size +
sizeof(struct image) + strlen(path) + 1;
}
static size_t image_size(struct image *img)
{
- return image_size2(img->ctx, img->path);
+ return image_size2(img->ctx, NULL, img->path);
}
struct image_cache *image_cache_create(unsigned int max_size_kbytes)
@@ -127,6 +136,7 @@ static void remove_img_free(struct image_cache *self,
remove_img(self, img, size);
GP_ContextFree(img->ctx);
+ GP_DataStorageDestroy(img->meta_data);
free(img);
}
@@ -149,13 +159,13 @@ static void add_img(struct image_cache *self, struct image *img, size_t size)
self->end = img;
}
-GP_Context *image_cache_get(struct image_cache *self, int elevate,
- const char *key)
+int image_cache_get(struct image_cache *self, GP_Context **img,
+ GP_DataStorage **meta_data, int elevate, const char *key)
{
struct image *i;
if (self == NULL)
- return NULL;
+ return 1;
GP_DEBUG(2, "Looking for image '%s'", key);
@@ -164,7 +174,7 @@ GP_Context *image_cache_get(struct image_cache *self, int elevate,
break;
if (i == NULL)
- return NULL;
+ return 1;
/* Push the image to the root of the list */
if (elevate) {
@@ -178,7 +188,13 @@ GP_Context *image_cache_get(struct image_cache *self, int elevate,
i->elevated++;
}
- return i->ctx;
+ if (img)
+ *img = i->ctx;
+
+ if (meta_data)
+ *meta_data = i->meta_data;
+
+ return 0;
}
GP_Context *image_cache_get2(struct image_cache *self, int elevate,
@@ -268,14 +284,14 @@ static int assert_size(struct image_cache *self, size_t size)
}
int image_cache_put(struct image_cache *self, GP_Context *ctx,
- const char *key)
+ GP_DataStorage *meta_data, const char *key)
{
size_t size;
if (self == NULL)
return 1;
- size = image_size2(ctx, key);
+ size = image_size2(ctx, meta_data, key);
/*
* We try to create room for the image. If this fails we add the image
@@ -292,6 +308,7 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx,
}
img->ctx = ctx;
+ img->meta_data = meta_data;
img->elevated = 0;
strcpy(img->path, key);
@@ -303,7 +320,7 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx,
}
int image_cache_put2(struct image_cache *self, GP_Context *ctx,
- const char *fmt, ...)
+ GP_DataStorage *meta_data, const char *fmt, ...)
{
size_t size, len;
va_list va;
@@ -316,7 +333,7 @@ int image_cache_put2(struct image_cache *self, GP_Context *ctx,
va_end(va);
//TODO: FIX THIS
- size = image_size2(ctx, "") + len + 1;
+ size = image_size2(ctx, meta_data, "") + len + 1;
/*
* We try to create room for the image. If this fails we add the image
@@ -333,6 +350,7 @@ int image_cache_put2(struct image_cache *self, GP_Context *ctx,
}
img->ctx = ctx;
+ img->meta_data = meta_data;
img->elevated = 0;
va_start(va, fmt);
diff --git a/demos/spiv/image_cache.h b/demos/spiv/image_cache.h
index b08ed48..f2ea1fa 100644
--- a/demos/spiv/image_cache.h
+++ b/demos/spiv/image_cache.h
@@ -47,8 +47,9 @@ struct image_cache *image_cache_create(unsigned int max_size_kbytes);
* If elevate set and image is found, the image is elevated to the top so
* it has lesser chance of being freed.
*/
-GP_Context *image_cache_get(struct image_cache *self, int elevate,
- const char *key);
+int image_cache_get(struct image_cache *self, GP_Context **img,
+ GP_DataStorage **meta_data, int elevate,
+ const char *key);
GP_Context *image_cache_get2(struct image_cache *self, int elevate,
const char *fmt, ...)
@@ -57,11 +58,11 @@ GP_Context *image_cache_get2(struct image_cache *self, int elevate,
* Puts an image into a cache.
*/
int image_cache_put(struct image_cache *self, GP_Context *img,
- const char *key);
+ GP_DataStorage *meta_data, const char *key);
int image_cache_put2(struct image_cache *self, GP_Context *img,
- const char *fmt, ...)
- __attribute__ ((format (printf, 3, 4)));
+ GP_DataStorage *meta_data, const char *fmt, ...)
+ __attribute__ ((format (printf, 4, 5)));
/*
* Drop all image in cache.
diff --git a/demos/spiv/image_loader.c b/demos/spiv/image_loader.c
index d033529..c7e0f9b 100644
--- a/demos/spiv/image_loader.c
+++ b/demos/spiv/image_loader.c
@@ -35,6 +35,7 @@
static struct image_cache *img_cache;
static struct image_list *img_list;
static GP_Context *cur_img;
+static GP_DataStorage *cur_meta_data;
static GP_Container *cur_cont;
int image_loader_init(const char *args[], unsigned int cache_max_bytes)
@@ -61,30 +62,31 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
struct cpu_timer timer;
const char *path;
GP_Context *img;
- int err;
+ int err, ret;
if (cur_img)
return cur_img;
if (cur_cont) {
cpu_timer_start(&timer, "Loading");
- cur_img = GP_ContainerLoad(cur_cont, callback);
+ cur_meta_data = GP_DataStorageCreate();
+ GP_ContainerLoadEx(cur_cont, &cur_img, cur_meta_data, callback);
cpu_timer_stop(&timer);
return cur_img;
}
path = image_list_img_path(img_list);
- cur_img = image_cache_get(img_cache, elevate, path);
-
- if (cur_img)
+ if (!image_cache_get(img_cache, &cur_img, &cur_meta_data, elevate, path))
return cur_img;
cpu_timer_start(&timer, "Loading");
- img = GP_LoadImage(path, callback);
+ cur_meta_data = GP_DataStorageCreate();
- if (!img) {
+ ret = GP_LoadImageEx(path, &img, cur_meta_data, callback);
+
+ if (ret) {
err = errno;
/*
@@ -95,7 +97,7 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
cur_cont = GP_OpenZip(path);
if (cur_cont) {
- img = GP_ContainerLoad(cur_cont, callback);
+ GP_ContainerLoadEx(cur_cont, &img, cur_meta_data, callback);
if (img) {
cur_img = img;
@@ -111,13 +113,18 @@ GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate)
return NULL;
}
- image_cache_put(img_cache, img, path);
+ image_cache_put(img_cache, img, cur_meta_data, path);
cpu_timer_stop(&timer);
return img;
}
+GP_DataStorage *image_loader_get_meta_data(void)
+{
+ return cur_meta_data;
+}
+
const char *image_loader_img_path(void)
{
//TODO: Make this more elegant
@@ -146,10 +153,13 @@ static void drop_cur_img(void)
/*
* Currently loaded image is too big to be cached -> free it.
*/
- if (!image_cache_get(img_cache, 0, path))
+ if (image_cache_get(img_cache, NULL, NULL, 0, path)) {
GP_ContextFree(cur_img);
+ GP_DataStorageDestroy(cur_meta_data);
+ }
cur_img = NULL;
+ cur_meta_data = NULL;
}
void image_loader_seek(enum img_seek_offset offset, int whence)
diff --git a/demos/spiv/image_loader.h b/demos/spiv/image_loader.h
index 46b65fa..9992bca 100644
--- a/demos/spiv/image_loader.h
+++ b/demos/spiv/image_loader.h
@@ -49,6 +49,11 @@ int image_loader_init(const char *args[], unsigned int cache_max_bytes);
GP_Context *image_loader_get_image(GP_ProgressCallback *callback, int elevate);
/*
+ * Retruns current image meta data or NULL there are none.
+ */
+GP_DataStorage *image_loader_get_meta_data(void);
+
+/*
* Returns path to current image.
*/
const char *image_loader_img_path(void);
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 3cf212c..40a5687 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -213,6 +213,39 @@ static void info_printf(GP_Context *ctx, GP_Coord x, GP_Coord y,
va_end(va);
}
+static unsigned int print_meta_data(GP_DataNode *node, GP_Context *context,
+ unsigned int th, unsigned int y, int level)
+{
+ GP_DataNode *i;
+ unsigned int x;
+
+ for (i = GP_DataDictFirst(node); i; i = i->next) {
+ y += th;
+ x = th * level + 10;
+ switch (i->type) {
+ case GP_DATA_INT:
+ info_printf(context, x, y, "%s : %li", i->id, i->value.i);
+ break;
+ case GP_DATA_DOUBLE:
+ info_printf(context, x, y, "%s : %lf", i->id, i->value.d);
+ break;
+ case GP_DATA_STRING:
+ info_printf(context, x, y, "%s : %s", i->id, i->value.str);
+ break;
+ case GP_DATA_RATIONAL:
+ info_printf(context, x, y, "%s : %li/%li",
+ i->id, i->value.rat.num, i->value.rat.den);
+ break;
+ case GP_DATA_DICT:
+ info_printf(context, x, y, "%s", i->id);
+ y = print_meta_data(i, context, th, y, level+1);
+ break;
+ }
+ }
+
+ return y;
+}
+
static void show_info(struct loader_params *params, GP_Context *img,
GP_Context *orig_img)
{
@@ -248,14 +281,25 @@ static void show_info(struct loader_params *params, GP_Context *img,
info_printf(context, 10, y, "%u of %u", pos, count);
y += th + 2;
- if (!image_loader_is_in_dir())
+ if (image_loader_is_in_dir()) {
+ unsigned int dir_count = image_loader_dir_count();
+ unsigned int dir_pos = image_loader_dir_pos() + 1;
+
+ info_printf(context, 10, y,
+ "%u of %u in directory", dir_pos, dir_count);
+ }
+
+ GP_DataStorage *meta_data = image_loader_get_meta_data();
+
+ if (!meta_data)
return;
- unsigned int dir_count = image_loader_dir_count();
- unsigned int dir_pos = image_loader_dir_pos() + 1;
+ GP_DataNode *node = GP_DataStorageRoot(meta_data);
+
+ if (node->type != GP_DATA_DICT)
+ return;
- info_printf(context, 10, y,
- "%u of %u in directory", dir_pos, dir_count);
+ print_meta_data(node, context, th + 2, y + th, 0);
}
static void update_display(struct loader_params *params, GP_Context *img,
@@ -414,7 +458,7 @@ GP_Context *load_resized_image(struct loader_params *params, GP_Size w, GP_Size
if (img == NULL)
return NULL;
- image_cache_put2(params->img_resized_cache, img, "%s %ux%u r%i l%i",
+ image_cache_put2(params->img_resized_cache, img, NULL, "%s %ux%u r%i l%i",
img_path, w, h, params->resampling_method,
params->use_low_pass);
-----------------------------------------------------------------------
Summary of changes:
build/syms/Core_symbols.txt | 5 -
build/syms/Filters_symbols.txt | 1 +
build/syms/Loaders_symbols.txt | 1 +
demos/bogoman/Makefile | 2 +-
demos/bogoman/bogoman.c | 7 ++
demos/c_simple/SDL_glue.c | 4 +-
demos/c_simple/backend_example.c | 4 +-
demos/c_simple/backend_timers_example.c | 2 +-
demos/c_simple/blittest.c | 4 +-
demos/c_simple/fileview.c | 12 ++--
demos/c_simple/fonttest.c | 12 ++--
demos/c_simple/input_example.c | 8 +-
demos/c_simple/koch.c | 8 +-
demos/c_simple/linetest.c | 4 +-
demos/c_simple/randomshapetest.c | 4 +-
demos/c_simple/shapetest.c | 14 ++--
demos/c_simple/textaligntest.c | 14 ++--
demos/c_simple/virtual_backend_example.c | 10 +-
demos/c_simple/x11_windows.c | 4 +-
demos/particle/particle_demo.c | 4 +-
demos/spiv/image_cache.c | 42 +++++++---
demos/spiv/image_cache.h | 11 ++-
demos/spiv/image_loader.c | 30 +++++--
demos/spiv/image_loader.h | 5 +
demos/spiv/spiv.c | 111 +++++++++++++++++++++----
demos/spiv/spiv_config.c | 12 +++
demos/spiv/spiv_config.h | 5 +
demos/spiv/spiv_help.c | 4 +-
demos/ttf2img/ttf2img.c | 4 +-
doc/basic_types.txt | 72 ----------------
doc/convert.txt | 2 -
doc/core_python.txt | 9 +--
include/core/GP_Color.h | 124 ---------------------------
include/core/GP_Core.h | 3 -
include/loaders/GP_DataStorage.h | 11 +++
include/loaders/GP_Exif.h | 10 ++
libs/backends/GP_X11_Input.h | 3 +
libs/core/GP_Color.c | 135 ------------------------------
libs/loaders/GP_DataStorage.c | 54 ++++++++++++
pylib/gfxprim/core/core.i | 6 +-
40 files changed, 324 insertions(+), 453 deletions(-)
delete mode 100644 include/core/GP_Color.h
delete mode 100644 libs/core/GP_Color.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
16 Jan '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
discards 3b9e7725969eafa310c5358783ec8547773f04e4 (commit)
via 1109c295817003da4e1da28179040c3060dc1326 (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (3b9e7725969eafa310c5358783ec8547773f04e4)
N -- N -- N (1109c295817003da4e1da28179040c3060dc1326)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/1109c295817003da4e1da28179040c3060dc…
commit 1109c295817003da4e1da28179040c3060dc1326
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 10:29:10 2015 +0100
filters: Get rid of FilterParams
* Remove FilterParams
* Rewrite histogram code
* Add GP_PixelChannelCount(), GP_PixelChannelBits() and
GP_PixelChannelName()
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Filters_symbols.txt b/build/syms/Filters_symbols.txt
index d048bdc6..43049197 100644
--- a/build/syms/Filters_symbols.txt
+++ b/build/syms/Filters_symbols.txt
@@ -57,8 +57,8 @@ GP_FilterHConvolutionMP_Raw
GP_FilterHLinearConvolution_Raw
GP_FilterHistogram
-GP_FilterHistogramAlloc
-GP_FilterHistogram_Raw
+GP_HistogramAlloc
+GP_HistogramFree
GP_FilterKernelPrint_Raw
@@ -89,27 +89,6 @@ GP_FilterMultiply
GP_FilterMultiplyAlloc
GP_FilterMultiply_Raw
-GP_FilterParamChannel
-GP_FilterParamChannels
-GP_FilterParamCheckChannels
-GP_FilterParamCheckPixelType
-GP_FilterParamCreate
-GP_FilterParamDestroy
-GP_FilterParamFreePtrAll
-GP_FilterParamInitChannels
-GP_FilterParamPrintFloat
-GP_FilterParamPrintInt
-GP_FilterParamPrintPtr
-GP_FilterParamPrintUInt
-GP_FilterParamSetFloat
-GP_FilterParamSetFloatAll
-GP_FilterParamSetInt
-GP_FilterParamSetIntAll
-GP_FilterParamSetPtr
-GP_FilterParamSetPtrAll
-GP_FilterParamSetUInt
-GP_FilterParamSetUIntAll
-
GP_FilterResize
GP_FilterResizeAlloc
diff --git a/demos/grinder/histogram.c b/demos/grinder/histogram.c
index 00bffbdf..9706315b 100644
--- a/demos/grinder/histogram.c
+++ b/demos/grinder/histogram.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -24,10 +24,15 @@
void histogram_to_png(const GP_Context *src, const char *filename)
{
- GP_FILTER_PARAMS(src->pixel_type, params);
+ GP_Histogram *hist;
- GP_FilterHistogramAlloc(src->pixel_type, params);
- GP_FilterHistogram(src, params, NULL);
+ hist = GP_HistogramAlloc(src->pixel_type);
+ if (!hist) {
+ fprintf(stderr, "Failed to allocate histogramn");
+ return;
+ }
+
+ GP_FilterHistogram(hist, src, NULL);
unsigned int i, j;
@@ -35,27 +40,22 @@ void histogram_to_png(const GP_Context *src, const char *filename)
GP_Fill(res, 0xffffff);
- GP_Histogram *hist_r;
- hist_r = (GP_FilterParamChannel(params, "R"))->val.ptr;
+ GP_HistogramChannel *hist_r = GP_HistogramChannelByName(hist, "R");
for (i = 0; i < hist_r->len; i++)
GP_VLineXYH(res, i, 256, -255.00 * hist_r->hist[i] / hist_r->max + 0.5 , 0xff0000);
- GP_Histogram *hist_g;
- hist_g = (GP_FilterParamChannel(params, "G"))->val.ptr;
+ GP_HistogramChannel *hist_g = GP_HistogramChannelByName(hist, "G");
for (i = 0; i < hist_g->len; i++)
GP_VLineXYH(res, i+257, 256, -255.00 * hist_g->hist[i] / hist_g->max + 0.5 , 0x00ff00);
- GP_Histogram *hist_b;
- hist_b = (GP_FilterParamChannel(params, "B"))->val.ptr;
+ GP_HistogramChannel *hist_b = GP_HistogramChannelByName(hist, "B");
for (i = 0; i < hist_b->len; i++)
GP_VLineXYH(res, i+514, 256, -255.00 * hist_b->hist[i] / hist_b->max + 0.5 , 0x0000ff);
- uint32_t max = GP_MAX(hist_r->max, hist_g->max);
-
- max = GP_MAX(max, hist_b->max);
+ uint32_t max = GP_MAX3(hist_r->max, hist_g->max, hist_b->max);
for (i = 0; i < hist_r->len; i++) {
for (j = 0; j < hist_r->len; j++) {
@@ -77,5 +77,5 @@ void histogram_to_png(const GP_Context *src, const char *filename)
GP_SavePNG(res, filename, NULL);
GP_ContextFree(res);
- GP_FilterHistogramFree(params);
+ GP_HistogramFree(hist);
}
diff --git a/doc/pixels.txt b/doc/pixels.txt
index ffc3fa1e..59462ce7 100644
--- a/doc/pixels.txt
+++ b/doc/pixels.txt
@@ -87,6 +87,12 @@ const char *GP_PixelTypeName(GP_PixelType type);
uint32_t GP_PixelSize(GP_PixelType type);
+unsigned int GP_PixelChannelCount(GP_PixelType type);
+
+uint8_t GP_PixelChannelBits(GP_PixelType type, uint8_t channel);
+
+const char *GP_PixelChannelName(GP_PixelType type, uint8_t channel);
+
int GP_PixelHasFlags(GP_PixelType pixel_type, GP_PixelFlags flags);
-------------------------------------------------------------------------------
@@ -99,6 +105,12 @@ The 'GP_PixelTypeName()' function returns static string with pixel type name.
The 'GP_PixelSize()' returns pixel size in bits.
+The 'GP_PixelChannelCount()' returns number of pixel channels.
+
+The 'GP_PixelChannelBits()' returns number of bits for respective channel.
+
+The 'GP_PixelChannelName()' returns channel name.
+
The 'GP_PixelHasFlags()' function returns true if particular pixel type
contains the bitmask of pixel flags.
diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h
index bfe7d7fa..1f11a590 100644
--- a/include/core/GP_Pixel.h
+++ b/include/core/GP_Pixel.h
@@ -19,7 +19,7 @@
* Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
* Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
* *
@@ -153,6 +153,25 @@ static inline const GP_PixelTypeDescription *GP_PixelTypeDesc(GP_PixelType type)
return &GP_PixelTypes[type];
}
+static inline unsigned int GP_PixelChannelCount(GP_PixelType type)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].numchannels;
+}
+
+static inline uint8_t GP_PixelChannelBits(GP_PixelType type, uint8_t channel)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].channels[channel].size;
+}
+
+static inline const char *GP_PixelChannelName(GP_PixelType type,
+ uint8_t channel)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].channels[channel].name;
+}
+
/*
* Print a human-readable representation of a pixel value to a string.
* Arguments as for snprintf().
diff --git a/include/filters/GP_Filter.h b/include/filters/GP_Filter.h
index 690a64b8..bc36e2ed 100644
--- a/include/filters/GP_Filter.h
+++ b/include/filters/GP_Filter.h
@@ -32,6 +32,4 @@
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "GP_FilterParam.h"
-
#endif /* FILTERS_GP_FILTER_H */
diff --git a/include/filters/GP_FilterParam.h b/include/filters/GP_FilterParam.h
deleted file mode 100644
index 31b7ab66..00000000
--- a/include/filters/GP_FilterParam.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-/*
-
- Filter per channel parameter passing code.
-
- */
-
-#ifndef FILTERS_GP_FILTER_PARAM_H
-#define FILTERS_GP_FILTER_PARAM_H
-
-#include "core/GP_Pixel.h"
-
-#include <stdint.h>
-
-typedef union GP_FilterParamVal {
- float f;
- uint32_t ui;
- int32_t i;
- void *ptr;
-} GP_FilterParamVal;
-
-/*
- * Filter parameter structure for one channel.
- *
- * Filter takes, empty channel name terminated, arrray of these as parameter.
- */
-typedef struct GP_FilterParam {
- //TODO: this must be > than maximal channel name (now it's 2)
- char channel_name[2];
- union GP_FilterParamVal val;
-} GP_FilterParam;
-
-/*
- * Creates filter param structure large enough for given pixel_type.
- *
- * The returned structure has initalized channel_names and terminator.
- */
-GP_FilterParam *GP_FilterParamCreate(GP_PixelType pixel_type);
-
-/*
- * Destroys filter param structure.
- */
-void GP_FilterParamDestroy(GP_FilterParam *self);
-
-/*
- * Takes array of filter parameters and returns filter parameter by a channel
- * name.
- *
- * Returns NULL if channel wasn't found.
- */
-GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[],
- const char *channel_name);
-
-/*
- * Returns number of filter channels.
- */
-uint32_t GP_FilterParamChannels(GP_FilterParam params[]);
-
-/*
- * Compares param channels and pixel type channels. Returns zero if channels
- * match.
- */
-int GP_FilterParamCheckPixelType(GP_FilterParam params[],
- GP_PixelType pixel_type);
-
-/*
- * Returns zero only if params have exactly same channels as array of
- * channel_names.
- */
-int GP_FilterParamCheckChannels(GP_FilterParam params[],
- const char *channel_names[]);
-
-/*
- * Create and initalize the structure on the stack
- */
-#define GP_FILTER_PARAMS(pixel_type, name) - GP_FilterParam name[GP_PixelTypes[pixel_type].numchannels + 1]; - GP_FilterParamInitChannels(name, pixel_type);
-
-/*
- * Initalize param names and terminator.
- *
- * Sets all values to 0.
- */
-void GP_FilterParamInitChannels(GP_FilterParam params[],
- GP_PixelType pixel_type);
-
-/*
- * Sets all values to integer value.
- */
-void GP_FilterParamSetIntAll(GP_FilterParam params[], int32_t val);
-
-/*
- * Sets integer value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetInt(GP_FilterParam params[], const char *channel_name,
- int32_t val);
-
-/*
- * Sets all values to float value.
- */
-void GP_FilterParamSetFloatAll(GP_FilterParam params[], float val);
-
-/*
- * Sets float value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetFloat(GP_FilterParam params[], const char *channel_name,
- float val);
-
-/*
- * Sets all values to unsigned integer value.
- */
-void GP_FilterParamSetUIntAll(GP_FilterParam params[], uint32_t val);
-
-/*
- * Sets unsigned integer value. Returns 0 if such value was found, non-zero
- * otherwise.
- */
-int GP_FilterParamSetUInt(GP_FilterParam params[], const char *channel_name,
- uint32_t val);
-
-/*
- * Sets all values to pointer value.
- */
-void GP_FilterParamSetPtrAll(GP_FilterParam params[], void *ptr);
-
-/*
- * Sets pointer value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetPtr(GP_FilterParam params[], const char *channel_name,
- void *ptr);
-
-/*
- * Call free on all pointer values.
- */
-void GP_FilterParamFreePtrAll(GP_FilterParam params[]);
-
-/*
- * Functions to print the array.
- */
-void GP_FilterParamPrintInt(GP_FilterParam params[]);
-void GP_FilterParamPrintUInt(GP_FilterParam params[]);
-void GP_FilterParamPrintFloat(GP_FilterParam params[]);
-void GP_FilterParamPrintPtr(GP_FilterParam params[]);
-
-#endif /* FILTERS_GP_FILTER_PARAM_H */
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h
index 3fe7afbd..1b68c71f 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_Filters.h
@@ -32,9 +32,6 @@
#ifndef FILTERS_GP_FILTERS_H
#define FILTERS_GP_FILTERS_H
-/* Filter per channel parameter passing interface */
-#include "filters/GP_FilterParam.h"
-
/* Point filters, brightness, contrast ... */
#include "filters/GP_Point.h"
diff --git a/include/filters/GP_Stats.h b/include/filters/GP_Stats.h
index 6ad62dff..8d780fe2 100644
--- a/include/filters/GP_Stats.h
+++ b/include/filters/GP_Stats.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -31,34 +31,39 @@
#include "GP_Filter.h"
-typedef struct GP_Histogram {
- uint32_t min;
- uint32_t max;
+typedef struct GP_HistogramChannel {
+ const char *chan_name;
+ GP_Pixel min;
+ GP_Pixel max;
uint32_t len;
uint32_t hist[];
+} GP_HistogramChannel;
+
+typedef struct GP_Histogram {
+ GP_PixelType pixel_type;
+ GP_HistogramChannel *channels[];
} GP_Histogram;
/*
- * Histogram filter.
- *
- * The filter param is expected to hold pointers to struct GP_Histogram
+ * Allocates histogram for a given pixel type
*/
-int GP_FilterHistogram(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback);
+GP_Histogram *GP_HistogramAlloc(GP_PixelType pixel_type);
/*
- * Allocate and initalize struct GP_Histogram for each channel and stores the
- * pointer to filter params array. The pixel type must match the params[]
- * channels.
+ * Frees histogram.
*/
-void GP_FilterHistogramAlloc(GP_PixelType type, GP_FilterParam params[]);
+void GP_HistogramFree(GP_Histogram *self);
/*
- * Free the histogram arrays.
+ * Returns pointer to channel given channel name.
*/
-static inline void GP_FilterHistogramFree(GP_FilterParam params[])
-{
- GP_FilterParamFreePtrAll(params);
-}
+GP_HistogramChannel *GP_HistogramChannelByName(GP_Histogram *self,
+ const char *name);
+
+/*
+ * Computes histogram. Returns non-zero on failure (i.e. canceled by callback).
+ */
+int GP_FilterHistogram(GP_Histogram *self, const GP_Context *src,
+ GP_ProgressCallback *callback);
#endif /* FILTERS_GP_STATS_H */
diff --git a/libs/filters/GP_FilterParam.c b/libs/filters/GP_FilterParam.c
deleted file mode 100644
index fe7537c5..00000000
--- a/libs/filters/GP_FilterParam.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <string.h>
-
-#include "core/GP_Debug.h"
-
-#include "GP_FilterParam.h"
-
-GP_FilterParam *GP_FilterParamCreate(GP_PixelType pixel_type)
-{
- GP_FilterParam *ret;
-
- ret = malloc((GP_PixelTypes[pixel_type].numchannels + 1)
- * sizeof(GP_FilterParam));
-
- if (ret == NULL) {
- GP_WARN("Malloc Failed");
- return NULL;
- }
-
- GP_FilterParamInitChannels(ret, pixel_type);
-
- return ret;
-}
-
-void GP_FilterParamDestroy(GP_FilterParam *self)
-{
- free(self);
-}
-
-static unsigned int count_channels(GP_FilterParam params[])
-{
- unsigned int i = 0;
-
- while (params[i].channel_name[0] != '0')
- i++;
-
- return i;
-}
-
-GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[],
- const char *channel_name)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- if (!strcmp(params[i].channel_name, channel_name))
- return ¶ms[i];
-
- return NULL;
-}
-
-uint32_t GP_FilterParamChannels(GP_FilterParam params[])
-{
- return count_channels(params);
-}
-
-int GP_FilterParamCheckPixelType(GP_FilterParam params[],
- GP_PixelType pixel_type)
-{
- unsigned int i, num_channels;
- const GP_PixelTypeChannel *channels;
-
- num_channels = GP_PixelTypes[pixel_type].numchannels;
- channels = GP_PixelTypes[pixel_type].channels;
-
- i = count_channels(params);
-
- if (i != num_channels)
- return 1;
-
- for (i = 0; i < num_channels; i++)
- if (GP_FilterParamChannel(params, channels[i].name) == NULL)
- return 1;
-
- return 0;
-}
-
-int GP_FilterParamCheckChannels(GP_FilterParam params[],
- const char *channel_names[])
-{
- unsigned int i;
-
- for (i = 0; channel_names[i] != NULL; i++)
- if (GP_FilterParamChannel(params, channel_names[i]) == NULL)
- return 1;
-
- if (i != count_channels(params))
- return 1;
-
- return 0;
-}
-
-void GP_FilterParamInitChannels(GP_FilterParam params[],
- GP_PixelType pixel_type)
-{
- unsigned int i, num_channels;
- const GP_PixelTypeChannel *channels;
-
- num_channels = GP_PixelTypes[pixel_type].numchannels;
- channels = GP_PixelTypes[pixel_type].channels;
-
- for (i = 0; i < num_channels; i++) {
- strcpy(params[i].channel_name, channels[i].name);
- memset(¶ms[i].val, 0, sizeof(GP_FilterParamVal));
- }
-
- params[i].channel_name[0] = '0';
-}
-
-void GP_FilterParamSetIntAll(GP_FilterParam params[],
- int32_t val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.i = val;
-}
-
-int GP_FilterParamSetInt(GP_FilterParam params[], const char *channel_name,
- int32_t val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.i = val;
- return 0;
-}
-
-void GP_FilterParamSetFloatAll(GP_FilterParam params[],
- float val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.f = val;
-}
-
-int GP_FilterParamSetFloat(GP_FilterParam params[], const char *channel_name,
- float val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.f = val;
- return 0;
-}
-
-void GP_FilterParamSetUIntAll(GP_FilterParam params[],
- uint32_t val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.ui = val;
-}
-
-int GP_FilterParamSetUInt(GP_FilterParam params[], const char *channel_name,
- uint32_t val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.ui = val;
- return 0;
-}
-
-void GP_FilterParamSetPtrAll(GP_FilterParam params[],
- void *ptr)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.ptr = ptr;
-}
-
-int GP_FilterParamSetPtr(GP_FilterParam params[], const char *channel_name,
- void *ptr)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.ptr = ptr;
- return 0;
-}
-
-void GP_FilterParamFreePtrAll(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- free(params[i].val.ptr);
-}
-
-void GP_FilterParamPrintInt(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %in", params[i].channel_name, params[i].val.i);
-}
-
-void GP_FilterParamPrintUInt(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %un", params[i].channel_name, params[i].val.ui);
-}
-
-void GP_FilterParamPrintFloat(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %fn", params[i].channel_name, params[i].val.f);
-}
-
-void GP_FilterParamPrintPtr(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %pn", params[i].channel_name, params[i].val.ptr);
-}
diff --git a/libs/filters/GP_Stats.c b/libs/filters/GP_Histogram.c
similarity index 53%
rename from libs/filters/GP_Stats.c
rename to libs/filters/GP_Histogram.c
index 3ed5b683..8657c876 100644
--- a/libs/filters/GP_Stats.c
+++ b/libs/filters/GP_Histogram.c
@@ -16,72 +16,72 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
#include <string.h>
+#include <errno.h>
-#include <GP_Debug.h>
-
+#include <core/GP_Debug.h>
#include "GP_Stats.h"
-int GP_FilterHistogram_Raw(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback);
-
-int GP_FilterHistogram(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback)
+GP_Histogram *GP_HistogramAlloc(GP_PixelType pixel_type)
{
- int ret;
-
- ret = GP_FilterHistogram_Raw(src, histogram, callback);
-
- if (ret)
- return ret;
-
+ size_t hsize, size = 0;
unsigned int i;
+ GP_Histogram *hist;
- for (i = 0; histogram[i].channel_name[0] != '0'; i++) {
- unsigned int j;
- GP_Histogram *hist = histogram[i].val.ptr;
+ GP_DEBUG(1, "Allocating histogram for %s",
+ GP_PixelTypeName(pixel_type));
- hist->max = hist->hist[0];
- hist->min = hist->hist[0];
+ hsize = sizeof(GP_Histogram) +
+ GP_PixelChannelCount(pixel_type) * sizeof(void*);
- for (j = 1; j < hist->len; j++) {
- if (hist->hist[j] > hist->max)
- hist->max = hist->hist[j];
-
- if (hist->hist[j] < hist->min)
- hist->min = hist->hist[j];
- }
+ for (i = 0; i < GP_PixelChannelCount(pixel_type); i++) {
+ size += sizeof(GP_HistogramChannel) +
+ sizeof(uint32_t) * (1<<GP_PixelChannelBits(pixel_type, i));
}
- return 0;
-}
+ hist = malloc(hsize + size);
+ if (!hist) {
+ GP_WARN("Malloc failed :(");
+ errno = ENOMEM;
+ return NULL;
+ }
-void GP_FilterHistogramAlloc(GP_PixelType type, GP_FilterParam params[])
-{
- uint32_t i;
+ hist->pixel_type = pixel_type;
- GP_FilterParamSetPtrAll(params, NULL);
+ for (i = 0; i < GP_PixelChannelCount(pixel_type); i++) {
+ size_t chan_size = 1<<GP_PixelChannelBits(pixel_type, i);
- const GP_PixelTypeChannel *channels = GP_PixelTypes[type].channels;
+ hist->channels[i] = (void*)hist + hsize;
- for (i = 0; i < GP_PixelTypes[type].numchannels; i++) {
- size_t chan_size = 1<<channels[i].size;
+ hsize += sizeof(GP_HistogramChannel) +
+ sizeof(uint32_t) * chan_size;
- GP_Histogram *hist = malloc(sizeof(struct GP_Histogram) +
- sizeof(uint32_t) * chan_size);
+ hist->channels[i]->len = chan_size;
+ hist->channels[i]->chan_name = GP_PixelChannelName(pixel_type, i);
+ }
- if (hist == NULL) {
- GP_FilterHistogramFree(params);
- return;
- }
+ return hist;
+}
- hist->len = chan_size;
- memset(hist->hist, 0, sizeof(uint32_t) * chan_size);
+GP_HistogramChannel *GP_HistogramChannelByName(GP_Histogram *self,
+ const char *name)
+{
+ unsigned int i;
- (GP_FilterParamChannel(params, channels[i].name))->val.ptr = hist;
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ if (!strcmp(self->channels[i]->chan_name, name))
+ return self->channels[i];
}
+
+ return NULL;
+}
+
+void GP_HistogramFree(GP_Histogram *self)
+{
+ GP_DEBUG(1, "Freeing histogram %p", self);
+ free(self);
}
diff --git a/libs/filters/GP_Histogram.gen.c.t b/libs/filters/GP_Histogram.gen.c.t
index 3436aa63..52bfc5c1 100644
--- a/libs/filters/GP_Histogram.gen.c.t
+++ b/libs/filters/GP_Histogram.gen.c.t
@@ -2,27 +2,34 @@
/*
* Histogram filter -- Compute image histogram
*
- * Copyright (C) 2009-2014 Cyril Hrubis <metan(a)ucw.cz>
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz>
*/
-#include "core/GP_Context.h"
-#include "core/GP_Pixel.h"
-#include "core/GP_GetPutPixel.h"
-#include "core/GP_Debug.h"
-#include "GP_Filter.h"
+#include <string.h>
+#include <errno.h>
-#include "GP_Stats.h"
+#include <core/GP_Context.h>
+#include <core/GP_Pixel.h>
+#include <core/GP_GetPutPixel.h>
+#include <core/GP_Debug.h>
+#include <filters/GP_Filter.h>
+#include <filters/GP_Stats.h>
@ for pt in pixeltypes:
@ if not pt.is_unknown() and not pt.is_palette():
-static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
- GP_FilterParam histogram[], GP_ProgressCallback *callback)
+static int GP_FilterHistogram_{{ pt.name }}(GP_Histogram *self,
+ const GP_Context *src, GP_ProgressCallback *callback)
{
- GP_ASSERT(GP_FilterParamCheckPixelType(histogram, GP_PIXEL_{{ pt.name }}) == 0,
- "Invalid params channels for context pixel type");
+ if (self->pixel_type != src->pixel_type) {
+ GP_WARN("Histogram (%s) and context (%s) pixel type must match",
+ GP_PixelTypeName(self->pixel_type),
+ GP_PixelTypeName(src->pixel_type));
+ errno = EINVAL;
+ return 1;
+ }
@ for c in pt.chanslist:
- GP_Histogram *{{ c.name }}_hist = (GP_FilterParamChannel(histogram, "{{ c.name }}"))->val.ptr;
+ GP_HistogramChannel *chan_{{ c.name }} = self->channels[{{ c.idx }}];
@ end
uint32_t x, y;
@@ -35,7 +42,7 @@ static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
@ end
@ for c in pt.chanslist:
- {{ c.name }}_hist->hist[{{ c.name }}]++;
+ chan_{{ c.name }}->hist[{{ c.name }}]++;
@ end
}
@@ -49,20 +56,50 @@ static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
@ end
@
-int GP_FilterHistogram_Raw(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback)
+int GP_FilterHistogram(GP_Histogram *self, const GP_Context *src,
+ GP_ProgressCallback *callback)
{
- GP_DEBUG(1, "Running filter Histogram");
+ unsigned int i, j;
+ int ret;
+
+ GP_DEBUG(1, "Running Histogram filter");
+
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ GP_HistogramChannel *chan = self->channels[i];
+ printf("CHAN %i %i %pn", i, chan->len, chan->hist);
+ memset(chan->hist, 0, sizeof(uint32_t) * chan->len);
+ }
switch (src->pixel_type) {
@ for pt in pixeltypes:
@ if not pt.is_unknown() and not pt.is_palette():
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterHistogram_{{ pt.name }}(src, histogram, callback);
+ ret = GP_FilterHistogram_{{ pt.name }}(self, src, callback);
+ break;
@ end
default:
+ errno = ENOSYS;
+ return 1;
break;
}
- return 1;
+ if (ret)
+ return ret;
+
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ GP_HistogramChannel *chan = self->channels[i];
+
+ chan->max = chan->hist[0];
+ chan->min = chan->hist[0];
+
+ for (j = 1; j < chan->len; j++) {
+ if (chan->hist[j] > chan->max)
+ chan->max = chan->hist[j];
+
+ if (chan->hist[j] < chan->min)
+ chan->min = chan->hist[j];
+ }
+ }
+
+ return 0;
}
-----------------------------------------------------------------------
Summary of changes:
doc/pixels.txt | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
16 Jan '15
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 3b9e7725969eafa310c5358783ec8547773f04e4 (commit)
via b39970be125155a45b6d9b9199e7cde4857b57bd (commit)
via f86cf9cc008444620c01b79d1cdffe8352a36825 (commit)
via 54959be6241f6fe85a39f72e9ba88e3d42d06835 (commit)
via 380af9d42b91493a3cb726a075279e29030ba679 (commit)
via 69fbdb92d0f48c5d030d2cc0cb0c475b75464774 (commit)
via 80386afaf5cbd6c805140ae1e0f8e37918666e23 (commit)
via aefa0cab17b7f75cada9bc97678055313642e1e6 (commit)
via 9af41a3215a074981988fbcf5ed8c1f45739b9d4 (commit)
from c410d038596cfd83b39c4729dcfaf0e99e3e48b0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/3b9e7725969eafa310c5358783ec8547773f…
commit 3b9e7725969eafa310c5358783ec8547773f04e4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 16 10:29:10 2015 +0100
filters: Get rid of FilterParams
* Remove FilterParams
* Rewrite histogram code
* Add GP_PixelChannelCount(), GP_PixelChannelBits() and
GP_PixelChannelName()
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Filters_symbols.txt b/build/syms/Filters_symbols.txt
index d048bdc6..43049197 100644
--- a/build/syms/Filters_symbols.txt
+++ b/build/syms/Filters_symbols.txt
@@ -57,8 +57,8 @@ GP_FilterHConvolutionMP_Raw
GP_FilterHLinearConvolution_Raw
GP_FilterHistogram
-GP_FilterHistogramAlloc
-GP_FilterHistogram_Raw
+GP_HistogramAlloc
+GP_HistogramFree
GP_FilterKernelPrint_Raw
@@ -89,27 +89,6 @@ GP_FilterMultiply
GP_FilterMultiplyAlloc
GP_FilterMultiply_Raw
-GP_FilterParamChannel
-GP_FilterParamChannels
-GP_FilterParamCheckChannels
-GP_FilterParamCheckPixelType
-GP_FilterParamCreate
-GP_FilterParamDestroy
-GP_FilterParamFreePtrAll
-GP_FilterParamInitChannels
-GP_FilterParamPrintFloat
-GP_FilterParamPrintInt
-GP_FilterParamPrintPtr
-GP_FilterParamPrintUInt
-GP_FilterParamSetFloat
-GP_FilterParamSetFloatAll
-GP_FilterParamSetInt
-GP_FilterParamSetIntAll
-GP_FilterParamSetPtr
-GP_FilterParamSetPtrAll
-GP_FilterParamSetUInt
-GP_FilterParamSetUIntAll
-
GP_FilterResize
GP_FilterResizeAlloc
diff --git a/demos/grinder/histogram.c b/demos/grinder/histogram.c
index 00bffbdf..9706315b 100644
--- a/demos/grinder/histogram.c
+++ b/demos/grinder/histogram.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -24,10 +24,15 @@
void histogram_to_png(const GP_Context *src, const char *filename)
{
- GP_FILTER_PARAMS(src->pixel_type, params);
+ GP_Histogram *hist;
- GP_FilterHistogramAlloc(src->pixel_type, params);
- GP_FilterHistogram(src, params, NULL);
+ hist = GP_HistogramAlloc(src->pixel_type);
+ if (!hist) {
+ fprintf(stderr, "Failed to allocate histogramn");
+ return;
+ }
+
+ GP_FilterHistogram(hist, src, NULL);
unsigned int i, j;
@@ -35,27 +40,22 @@ void histogram_to_png(const GP_Context *src, const char *filename)
GP_Fill(res, 0xffffff);
- GP_Histogram *hist_r;
- hist_r = (GP_FilterParamChannel(params, "R"))->val.ptr;
+ GP_HistogramChannel *hist_r = GP_HistogramChannelByName(hist, "R");
for (i = 0; i < hist_r->len; i++)
GP_VLineXYH(res, i, 256, -255.00 * hist_r->hist[i] / hist_r->max + 0.5 , 0xff0000);
- GP_Histogram *hist_g;
- hist_g = (GP_FilterParamChannel(params, "G"))->val.ptr;
+ GP_HistogramChannel *hist_g = GP_HistogramChannelByName(hist, "G");
for (i = 0; i < hist_g->len; i++)
GP_VLineXYH(res, i+257, 256, -255.00 * hist_g->hist[i] / hist_g->max + 0.5 , 0x00ff00);
- GP_Histogram *hist_b;
- hist_b = (GP_FilterParamChannel(params, "B"))->val.ptr;
+ GP_HistogramChannel *hist_b = GP_HistogramChannelByName(hist, "B");
for (i = 0; i < hist_b->len; i++)
GP_VLineXYH(res, i+514, 256, -255.00 * hist_b->hist[i] / hist_b->max + 0.5 , 0x0000ff);
- uint32_t max = GP_MAX(hist_r->max, hist_g->max);
-
- max = GP_MAX(max, hist_b->max);
+ uint32_t max = GP_MAX3(hist_r->max, hist_g->max, hist_b->max);
for (i = 0; i < hist_r->len; i++) {
for (j = 0; j < hist_r->len; j++) {
@@ -77,5 +77,5 @@ void histogram_to_png(const GP_Context *src, const char *filename)
GP_SavePNG(res, filename, NULL);
GP_ContextFree(res);
- GP_FilterHistogramFree(params);
+ GP_HistogramFree(hist);
}
diff --git a/doc/pixels.txt b/doc/pixels.txt
index ffc3fa1e..804898b4 100644
--- a/doc/pixels.txt
+++ b/doc/pixels.txt
@@ -87,6 +87,10 @@ const char *GP_PixelTypeName(GP_PixelType type);
uint32_t GP_PixelSize(GP_PixelType type);
+unsigned int GP_PixelChannelCount(GP_PixelType type);
+
+uint8_t GP_PixelChannelBits(GP_PixelType type, uint8_t channel);
+
int GP_PixelHasFlags(GP_PixelType pixel_type, GP_PixelFlags flags);
-------------------------------------------------------------------------------
@@ -99,6 +103,10 @@ The 'GP_PixelTypeName()' function returns static string with pixel type name.
The 'GP_PixelSize()' returns pixel size in bits.
+The 'GP_PixelChannelCount()' returns number of pixel channels.
+
+The 'GP_PixelChannelBits()' returns number of bits for respective channel.
+
The 'GP_PixelHasFlags()' function returns true if particular pixel type
contains the bitmask of pixel flags.
diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h
index bfe7d7fa..1f11a590 100644
--- a/include/core/GP_Pixel.h
+++ b/include/core/GP_Pixel.h
@@ -19,7 +19,7 @@
* Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
* Copyright (C) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
* *
@@ -153,6 +153,25 @@ static inline const GP_PixelTypeDescription *GP_PixelTypeDesc(GP_PixelType type)
return &GP_PixelTypes[type];
}
+static inline unsigned int GP_PixelChannelCount(GP_PixelType type)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].numchannels;
+}
+
+static inline uint8_t GP_PixelChannelBits(GP_PixelType type, uint8_t channel)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].channels[channel].size;
+}
+
+static inline const char *GP_PixelChannelName(GP_PixelType type,
+ uint8_t channel)
+{
+ GP_CHECK_VALID_PIXELTYPE(type);
+ return GP_PixelTypes[type].channels[channel].name;
+}
+
/*
* Print a human-readable representation of a pixel value to a string.
* Arguments as for snprintf().
diff --git a/include/filters/GP_Filter.h b/include/filters/GP_Filter.h
index 690a64b8..bc36e2ed 100644
--- a/include/filters/GP_Filter.h
+++ b/include/filters/GP_Filter.h
@@ -32,6 +32,4 @@
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
-#include "GP_FilterParam.h"
-
#endif /* FILTERS_GP_FILTER_H */
diff --git a/include/filters/GP_FilterParam.h b/include/filters/GP_FilterParam.h
deleted file mode 100644
index 31b7ab66..00000000
--- a/include/filters/GP_FilterParam.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-/*
-
- Filter per channel parameter passing code.
-
- */
-
-#ifndef FILTERS_GP_FILTER_PARAM_H
-#define FILTERS_GP_FILTER_PARAM_H
-
-#include "core/GP_Pixel.h"
-
-#include <stdint.h>
-
-typedef union GP_FilterParamVal {
- float f;
- uint32_t ui;
- int32_t i;
- void *ptr;
-} GP_FilterParamVal;
-
-/*
- * Filter parameter structure for one channel.
- *
- * Filter takes, empty channel name terminated, arrray of these as parameter.
- */
-typedef struct GP_FilterParam {
- //TODO: this must be > than maximal channel name (now it's 2)
- char channel_name[2];
- union GP_FilterParamVal val;
-} GP_FilterParam;
-
-/*
- * Creates filter param structure large enough for given pixel_type.
- *
- * The returned structure has initalized channel_names and terminator.
- */
-GP_FilterParam *GP_FilterParamCreate(GP_PixelType pixel_type);
-
-/*
- * Destroys filter param structure.
- */
-void GP_FilterParamDestroy(GP_FilterParam *self);
-
-/*
- * Takes array of filter parameters and returns filter parameter by a channel
- * name.
- *
- * Returns NULL if channel wasn't found.
- */
-GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[],
- const char *channel_name);
-
-/*
- * Returns number of filter channels.
- */
-uint32_t GP_FilterParamChannels(GP_FilterParam params[]);
-
-/*
- * Compares param channels and pixel type channels. Returns zero if channels
- * match.
- */
-int GP_FilterParamCheckPixelType(GP_FilterParam params[],
- GP_PixelType pixel_type);
-
-/*
- * Returns zero only if params have exactly same channels as array of
- * channel_names.
- */
-int GP_FilterParamCheckChannels(GP_FilterParam params[],
- const char *channel_names[]);
-
-/*
- * Create and initalize the structure on the stack
- */
-#define GP_FILTER_PARAMS(pixel_type, name) - GP_FilterParam name[GP_PixelTypes[pixel_type].numchannels + 1]; - GP_FilterParamInitChannels(name, pixel_type);
-
-/*
- * Initalize param names and terminator.
- *
- * Sets all values to 0.
- */
-void GP_FilterParamInitChannels(GP_FilterParam params[],
- GP_PixelType pixel_type);
-
-/*
- * Sets all values to integer value.
- */
-void GP_FilterParamSetIntAll(GP_FilterParam params[], int32_t val);
-
-/*
- * Sets integer value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetInt(GP_FilterParam params[], const char *channel_name,
- int32_t val);
-
-/*
- * Sets all values to float value.
- */
-void GP_FilterParamSetFloatAll(GP_FilterParam params[], float val);
-
-/*
- * Sets float value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetFloat(GP_FilterParam params[], const char *channel_name,
- float val);
-
-/*
- * Sets all values to unsigned integer value.
- */
-void GP_FilterParamSetUIntAll(GP_FilterParam params[], uint32_t val);
-
-/*
- * Sets unsigned integer value. Returns 0 if such value was found, non-zero
- * otherwise.
- */
-int GP_FilterParamSetUInt(GP_FilterParam params[], const char *channel_name,
- uint32_t val);
-
-/*
- * Sets all values to pointer value.
- */
-void GP_FilterParamSetPtrAll(GP_FilterParam params[], void *ptr);
-
-/*
- * Sets pointer value. Returns 0 if such value was found, non-zero otherwise.
- */
-int GP_FilterParamSetPtr(GP_FilterParam params[], const char *channel_name,
- void *ptr);
-
-/*
- * Call free on all pointer values.
- */
-void GP_FilterParamFreePtrAll(GP_FilterParam params[]);
-
-/*
- * Functions to print the array.
- */
-void GP_FilterParamPrintInt(GP_FilterParam params[]);
-void GP_FilterParamPrintUInt(GP_FilterParam params[]);
-void GP_FilterParamPrintFloat(GP_FilterParam params[]);
-void GP_FilterParamPrintPtr(GP_FilterParam params[]);
-
-#endif /* FILTERS_GP_FILTER_PARAM_H */
diff --git a/include/filters/GP_Filters.h b/include/filters/GP_Filters.h
index 3fe7afbd..1b68c71f 100644
--- a/include/filters/GP_Filters.h
+++ b/include/filters/GP_Filters.h
@@ -32,9 +32,6 @@
#ifndef FILTERS_GP_FILTERS_H
#define FILTERS_GP_FILTERS_H
-/* Filter per channel parameter passing interface */
-#include "filters/GP_FilterParam.h"
-
/* Point filters, brightness, contrast ... */
#include "filters/GP_Point.h"
diff --git a/include/filters/GP_Stats.h b/include/filters/GP_Stats.h
index 6ad62dff..8d780fe2 100644
--- a/include/filters/GP_Stats.h
+++ b/include/filters/GP_Stats.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -31,34 +31,39 @@
#include "GP_Filter.h"
-typedef struct GP_Histogram {
- uint32_t min;
- uint32_t max;
+typedef struct GP_HistogramChannel {
+ const char *chan_name;
+ GP_Pixel min;
+ GP_Pixel max;
uint32_t len;
uint32_t hist[];
+} GP_HistogramChannel;
+
+typedef struct GP_Histogram {
+ GP_PixelType pixel_type;
+ GP_HistogramChannel *channels[];
} GP_Histogram;
/*
- * Histogram filter.
- *
- * The filter param is expected to hold pointers to struct GP_Histogram
+ * Allocates histogram for a given pixel type
*/
-int GP_FilterHistogram(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback);
+GP_Histogram *GP_HistogramAlloc(GP_PixelType pixel_type);
/*
- * Allocate and initalize struct GP_Histogram for each channel and stores the
- * pointer to filter params array. The pixel type must match the params[]
- * channels.
+ * Frees histogram.
*/
-void GP_FilterHistogramAlloc(GP_PixelType type, GP_FilterParam params[]);
+void GP_HistogramFree(GP_Histogram *self);
/*
- * Free the histogram arrays.
+ * Returns pointer to channel given channel name.
*/
-static inline void GP_FilterHistogramFree(GP_FilterParam params[])
-{
- GP_FilterParamFreePtrAll(params);
-}
+GP_HistogramChannel *GP_HistogramChannelByName(GP_Histogram *self,
+ const char *name);
+
+/*
+ * Computes histogram. Returns non-zero on failure (i.e. canceled by callback).
+ */
+int GP_FilterHistogram(GP_Histogram *self, const GP_Context *src,
+ GP_ProgressCallback *callback);
#endif /* FILTERS_GP_STATS_H */
diff --git a/libs/filters/GP_FilterParam.c b/libs/filters/GP_FilterParam.c
deleted file mode 100644
index fe7537c5..00000000
--- a/libs/filters/GP_FilterParam.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <string.h>
-
-#include "core/GP_Debug.h"
-
-#include "GP_FilterParam.h"
-
-GP_FilterParam *GP_FilterParamCreate(GP_PixelType pixel_type)
-{
- GP_FilterParam *ret;
-
- ret = malloc((GP_PixelTypes[pixel_type].numchannels + 1)
- * sizeof(GP_FilterParam));
-
- if (ret == NULL) {
- GP_WARN("Malloc Failed");
- return NULL;
- }
-
- GP_FilterParamInitChannels(ret, pixel_type);
-
- return ret;
-}
-
-void GP_FilterParamDestroy(GP_FilterParam *self)
-{
- free(self);
-}
-
-static unsigned int count_channels(GP_FilterParam params[])
-{
- unsigned int i = 0;
-
- while (params[i].channel_name[0] != '0')
- i++;
-
- return i;
-}
-
-GP_FilterParam *GP_FilterParamChannel(GP_FilterParam params[],
- const char *channel_name)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- if (!strcmp(params[i].channel_name, channel_name))
- return ¶ms[i];
-
- return NULL;
-}
-
-uint32_t GP_FilterParamChannels(GP_FilterParam params[])
-{
- return count_channels(params);
-}
-
-int GP_FilterParamCheckPixelType(GP_FilterParam params[],
- GP_PixelType pixel_type)
-{
- unsigned int i, num_channels;
- const GP_PixelTypeChannel *channels;
-
- num_channels = GP_PixelTypes[pixel_type].numchannels;
- channels = GP_PixelTypes[pixel_type].channels;
-
- i = count_channels(params);
-
- if (i != num_channels)
- return 1;
-
- for (i = 0; i < num_channels; i++)
- if (GP_FilterParamChannel(params, channels[i].name) == NULL)
- return 1;
-
- return 0;
-}
-
-int GP_FilterParamCheckChannels(GP_FilterParam params[],
- const char *channel_names[])
-{
- unsigned int i;
-
- for (i = 0; channel_names[i] != NULL; i++)
- if (GP_FilterParamChannel(params, channel_names[i]) == NULL)
- return 1;
-
- if (i != count_channels(params))
- return 1;
-
- return 0;
-}
-
-void GP_FilterParamInitChannels(GP_FilterParam params[],
- GP_PixelType pixel_type)
-{
- unsigned int i, num_channels;
- const GP_PixelTypeChannel *channels;
-
- num_channels = GP_PixelTypes[pixel_type].numchannels;
- channels = GP_PixelTypes[pixel_type].channels;
-
- for (i = 0; i < num_channels; i++) {
- strcpy(params[i].channel_name, channels[i].name);
- memset(¶ms[i].val, 0, sizeof(GP_FilterParamVal));
- }
-
- params[i].channel_name[0] = '0';
-}
-
-void GP_FilterParamSetIntAll(GP_FilterParam params[],
- int32_t val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.i = val;
-}
-
-int GP_FilterParamSetInt(GP_FilterParam params[], const char *channel_name,
- int32_t val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.i = val;
- return 0;
-}
-
-void GP_FilterParamSetFloatAll(GP_FilterParam params[],
- float val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.f = val;
-}
-
-int GP_FilterParamSetFloat(GP_FilterParam params[], const char *channel_name,
- float val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.f = val;
- return 0;
-}
-
-void GP_FilterParamSetUIntAll(GP_FilterParam params[],
- uint32_t val)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.ui = val;
-}
-
-int GP_FilterParamSetUInt(GP_FilterParam params[], const char *channel_name,
- uint32_t val)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.ui = val;
- return 0;
-}
-
-void GP_FilterParamSetPtrAll(GP_FilterParam params[],
- void *ptr)
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- params[i].val.ptr = ptr;
-}
-
-int GP_FilterParamSetPtr(GP_FilterParam params[], const char *channel_name,
- void *ptr)
-{
- GP_FilterParam *param;
- param = GP_FilterParamChannel(params, channel_name);
-
- if (param == NULL)
- return 1;
-
- param->val.ptr = ptr;
- return 0;
-}
-
-void GP_FilterParamFreePtrAll(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- free(params[i].val.ptr);
-}
-
-void GP_FilterParamPrintInt(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %in", params[i].channel_name, params[i].val.i);
-}
-
-void GP_FilterParamPrintUInt(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %un", params[i].channel_name, params[i].val.ui);
-}
-
-void GP_FilterParamPrintFloat(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %fn", params[i].channel_name, params[i].val.f);
-}
-
-void GP_FilterParamPrintPtr(GP_FilterParam params[])
-{
- unsigned int i;
-
- for (i = 0; params[i].channel_name[0] != '0'; i++)
- printf("Chann '%s' = %pn", params[i].channel_name, params[i].val.ptr);
-}
diff --git a/libs/filters/GP_Stats.c b/libs/filters/GP_Histogram.c
similarity index 53%
rename from libs/filters/GP_Stats.c
rename to libs/filters/GP_Histogram.c
index 3ed5b683..8657c876 100644
--- a/libs/filters/GP_Stats.c
+++ b/libs/filters/GP_Histogram.c
@@ -16,72 +16,72 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
#include <string.h>
+#include <errno.h>
-#include <GP_Debug.h>
-
+#include <core/GP_Debug.h>
#include "GP_Stats.h"
-int GP_FilterHistogram_Raw(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback);
-
-int GP_FilterHistogram(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback)
+GP_Histogram *GP_HistogramAlloc(GP_PixelType pixel_type)
{
- int ret;
-
- ret = GP_FilterHistogram_Raw(src, histogram, callback);
-
- if (ret)
- return ret;
-
+ size_t hsize, size = 0;
unsigned int i;
+ GP_Histogram *hist;
- for (i = 0; histogram[i].channel_name[0] != '0'; i++) {
- unsigned int j;
- GP_Histogram *hist = histogram[i].val.ptr;
+ GP_DEBUG(1, "Allocating histogram for %s",
+ GP_PixelTypeName(pixel_type));
- hist->max = hist->hist[0];
- hist->min = hist->hist[0];
+ hsize = sizeof(GP_Histogram) +
+ GP_PixelChannelCount(pixel_type) * sizeof(void*);
- for (j = 1; j < hist->len; j++) {
- if (hist->hist[j] > hist->max)
- hist->max = hist->hist[j];
-
- if (hist->hist[j] < hist->min)
- hist->min = hist->hist[j];
- }
+ for (i = 0; i < GP_PixelChannelCount(pixel_type); i++) {
+ size += sizeof(GP_HistogramChannel) +
+ sizeof(uint32_t) * (1<<GP_PixelChannelBits(pixel_type, i));
}
- return 0;
-}
+ hist = malloc(hsize + size);
+ if (!hist) {
+ GP_WARN("Malloc failed :(");
+ errno = ENOMEM;
+ return NULL;
+ }
-void GP_FilterHistogramAlloc(GP_PixelType type, GP_FilterParam params[])
-{
- uint32_t i;
+ hist->pixel_type = pixel_type;
- GP_FilterParamSetPtrAll(params, NULL);
+ for (i = 0; i < GP_PixelChannelCount(pixel_type); i++) {
+ size_t chan_size = 1<<GP_PixelChannelBits(pixel_type, i);
- const GP_PixelTypeChannel *channels = GP_PixelTypes[type].channels;
+ hist->channels[i] = (void*)hist + hsize;
- for (i = 0; i < GP_PixelTypes[type].numchannels; i++) {
- size_t chan_size = 1<<channels[i].size;
+ hsize += sizeof(GP_HistogramChannel) +
+ sizeof(uint32_t) * chan_size;
- GP_Histogram *hist = malloc(sizeof(struct GP_Histogram) +
- sizeof(uint32_t) * chan_size);
+ hist->channels[i]->len = chan_size;
+ hist->channels[i]->chan_name = GP_PixelChannelName(pixel_type, i);
+ }
- if (hist == NULL) {
- GP_FilterHistogramFree(params);
- return;
- }
+ return hist;
+}
- hist->len = chan_size;
- memset(hist->hist, 0, sizeof(uint32_t) * chan_size);
+GP_HistogramChannel *GP_HistogramChannelByName(GP_Histogram *self,
+ const char *name)
+{
+ unsigned int i;
- (GP_FilterParamChannel(params, channels[i].name))->val.ptr = hist;
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ if (!strcmp(self->channels[i]->chan_name, name))
+ return self->channels[i];
}
+
+ return NULL;
+}
+
+void GP_HistogramFree(GP_Histogram *self)
+{
+ GP_DEBUG(1, "Freeing histogram %p", self);
+ free(self);
}
diff --git a/libs/filters/GP_Histogram.gen.c.t b/libs/filters/GP_Histogram.gen.c.t
index 3436aa63..52bfc5c1 100644
--- a/libs/filters/GP_Histogram.gen.c.t
+++ b/libs/filters/GP_Histogram.gen.c.t
@@ -2,27 +2,34 @@
/*
* Histogram filter -- Compute image histogram
*
- * Copyright (C) 2009-2014 Cyril Hrubis <metan(a)ucw.cz>
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz>
*/
-#include "core/GP_Context.h"
-#include "core/GP_Pixel.h"
-#include "core/GP_GetPutPixel.h"
-#include "core/GP_Debug.h"
-#include "GP_Filter.h"
+#include <string.h>
+#include <errno.h>
-#include "GP_Stats.h"
+#include <core/GP_Context.h>
+#include <core/GP_Pixel.h>
+#include <core/GP_GetPutPixel.h>
+#include <core/GP_Debug.h>
+#include <filters/GP_Filter.h>
+#include <filters/GP_Stats.h>
@ for pt in pixeltypes:
@ if not pt.is_unknown() and not pt.is_palette():
-static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
- GP_FilterParam histogram[], GP_ProgressCallback *callback)
+static int GP_FilterHistogram_{{ pt.name }}(GP_Histogram *self,
+ const GP_Context *src, GP_ProgressCallback *callback)
{
- GP_ASSERT(GP_FilterParamCheckPixelType(histogram, GP_PIXEL_{{ pt.name }}) == 0,
- "Invalid params channels for context pixel type");
+ if (self->pixel_type != src->pixel_type) {
+ GP_WARN("Histogram (%s) and context (%s) pixel type must match",
+ GP_PixelTypeName(self->pixel_type),
+ GP_PixelTypeName(src->pixel_type));
+ errno = EINVAL;
+ return 1;
+ }
@ for c in pt.chanslist:
- GP_Histogram *{{ c.name }}_hist = (GP_FilterParamChannel(histogram, "{{ c.name }}"))->val.ptr;
+ GP_HistogramChannel *chan_{{ c.name }} = self->channels[{{ c.idx }}];
@ end
uint32_t x, y;
@@ -35,7 +42,7 @@ static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
@ end
@ for c in pt.chanslist:
- {{ c.name }}_hist->hist[{{ c.name }}]++;
+ chan_{{ c.name }}->hist[{{ c.name }}]++;
@ end
}
@@ -49,20 +56,50 @@ static int GP_FilterHistogram_{{ pt.name }}(const GP_Context *src,
@ end
@
-int GP_FilterHistogram_Raw(const GP_Context *src, GP_FilterParam histogram[],
- GP_ProgressCallback *callback)
+int GP_FilterHistogram(GP_Histogram *self, const GP_Context *src,
+ GP_ProgressCallback *callback)
{
- GP_DEBUG(1, "Running filter Histogram");
+ unsigned int i, j;
+ int ret;
+
+ GP_DEBUG(1, "Running Histogram filter");
+
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ GP_HistogramChannel *chan = self->channels[i];
+ printf("CHAN %i %i %pn", i, chan->len, chan->hist);
+ memset(chan->hist, 0, sizeof(uint32_t) * chan->len);
+ }
switch (src->pixel_type) {
@ for pt in pixeltypes:
@ if not pt.is_unknown() and not pt.is_palette():
case GP_PIXEL_{{ pt.name }}:
- return GP_FilterHistogram_{{ pt.name }}(src, histogram, callback);
+ ret = GP_FilterHistogram_{{ pt.name }}(self, src, callback);
+ break;
@ end
default:
+ errno = ENOSYS;
+ return 1;
break;
}
- return 1;
+ if (ret)
+ return ret;
+
+ for (i = 0; i < GP_PixelChannelCount(self->pixel_type); i++) {
+ GP_HistogramChannel *chan = self->channels[i];
+
+ chan->max = chan->hist[0];
+ chan->min = chan->hist[0];
+
+ for (j = 1; j < chan->len; j++) {
+ if (chan->hist[j] > chan->max)
+ chan->max = chan->hist[j];
+
+ if (chan->hist[j] < chan->min)
+ chan->min = chan->hist[j];
+ }
+ }
+
+ return 0;
}
http://repo.or.cz/w/gfxprim.git/commit/b39970be125155a45b6d9b9199e7cde4857b…
commit b39970be125155a45b6d9b9199e7cde4857b57bd
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jan 15 20:28:53 2015 +0100
loaders: Get rid of TmpFile.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 0266e70d..79ada509 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -104,9 +104,6 @@ GP_PSD
GP_ReadExif
-GP_SaveTmpFile
-GP_LoadTmpFile
-
GP_LoaderBySignature
GP_LoaderByFilename
GP_LoaderLoadImage
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index 654df984..13464238 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -13,7 +13,7 @@ INCLUDE=
LDLIBS+=-lrt
APPS=backend_example loaders_example loaders filters_symmetry gfx_koch- virtual_backend_example meta_data tmp_file showimage+ virtual_backend_example meta_data showimage v4l2_show v4l2_grab convolution weighted_median shapetest koch input_example fileview linetest randomshapetest fonttest loaders_register blittest textaligntest sin_AA x11_windows@@ -32,7 +32,6 @@ backend_timers_example: LDLIBS+=-lgfxprim-backends
virtual_backend_example: LDLIBS+=-lgfxprim-backends -lm
loaders_example: LDLIBS+=-lgfxprim-loaders
loaders: LDLIBS+=-lgfxprim-loaders
-tmp_file: LDLIBS+=-lgfxprim-loaders
filters_symmetry: LDLIBS+=-lgfxprim-loaders
gfx_koch: LDLIBS+=-lgfxprim-loaders -lm
meta_data: LDLIBS+=-lgfxprim-loaders
diff --git a/demos/c_simple/tmp_file.c b/demos/c_simple/tmp_file.c
deleted file mode 100644
index 6daf3991..00000000
--- a/demos/c_simple/tmp_file.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
- /*
-
- Tmp file is interface for storing GP_Context data on disk in uncompressed
- fast but non-portable format (more or less GP_Context dump).
-
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <GP.h>
-
-struct callback_priv {
- char *op;
- char *name;
-};
-
-static int progress_callback(GP_ProgressCallback *self)
-{
- struct callback_priv *priv = self->priv;
-
- printf("r%s '%s' %3.1f%%", priv->op, priv->name, self->percentage);
- fflush(stdout);
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- GP_Context *img;
- struct callback_priv priv;
- GP_ProgressCallback callback = {.callback = progress_callback,
- .priv = &priv};
-
- if (argc != 2) {
- fprintf(stderr, "Takes an image as an parametern");
- return 1;
- }
-
- priv.op = "Loading";
- priv.name = argv[1];
-
- img = GP_LoadImage(argv[1], &callback);
-
- if (img == NULL) {
- fprintf(stderr, "Failed to load image '%s':%sn", argv[1],
- strerror(errno));
- return 1;
- }
-
- printf("n");
-
- priv.op = "Saving";
- priv.name = "tmp.gfx";
-
- if (GP_SaveTmpFile(img, priv.name, &callback)) {
- fprintf(stderr, "Failed to save temp file %sn", strerror(errno));
- return 1;
- }
-
- printf("n");
-
- GP_ContextFree(img);
-
- priv.op = "Loading";
-
- img = GP_LoadTmpFile(priv.name, &callback);
-
- if (img == NULL) {
- fprintf(stderr, "Failed to load temp file %sn", strerror(errno));
- return 1;
- }
-
- priv.op = "Saving";
- priv.name = "out.png";
-
- printf("n");
-
- if (GP_SavePNG(img, "out.png", &callback)) {
- fprintf(stderr, "Failed to save image %sn", strerror(errno));
- return 1;
- }
-
- printf("n");
-
- return 0;
-}
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h
index 4c32ceb5..bb2f6998 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Loaders.h
@@ -46,8 +46,6 @@
#include "loaders/GP_PSP.h"
#include "loaders/GP_PSD.h"
-#include "loaders/GP_TmpFile.h"
-
#include "loaders/GP_DataStorage.h"
#include "loaders/GP_Exif.h"
diff --git a/include/loaders/GP_TmpFile.h b/include/loaders/GP_TmpFile.h
deleted file mode 100644
index 819962ba..00000000
--- a/include/loaders/GP_TmpFile.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
- /*
-
- This is interface for saving GP_Context into non-portable uncompressed file,
- which is usefull for caching GP_Context to disk.
-
- */
-
-#ifndef LOADERS_GP_TMP_FILE_H
-#define LOADERS_GP_TMP_FILE_H
-
-#include "core/GP_Context.h"
-#include "core/GP_ProgressCallback.h"
-
-/*
- * The possible errno values:
- *
- * - Anything FILE operation may return (fopen(), fclose(), fseek(), ...).
- * - EIO for fread()/fwrite() failure
- * - ENOMEM from malloc()
- * - ECANCELED when call was aborted from callback
- */
-
-/*
- * Opens up and loads file.
- *
- * On failure NULL is returned and errno is set.
- */
-GP_Context *GP_LoadTmpFile(const char *src_path, GP_ProgressCallback *callback);
-
-/*
- * Saves context into a file. On failure non-zero is returned and errno is set.
- */
-int GP_SaveTmpFile(const GP_Context *src, const char *dst_path,
- GP_ProgressCallback *callback);
-
-#endif /* LOADERS_GP_TMP_FILE_H */
diff --git a/libs/loaders/GP_TmpFile.c b/libs/loaders/GP_TmpFile.c
deleted file mode 100644
index 0dbb5ad7..00000000
--- a/libs/loaders/GP_TmpFile.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*****************************************************************************
- * This file is part of gfxprim library. *
- * *
- * Gfxprim is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * Gfxprim is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with gfxprim; if not, write to the Free Software *
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
- * Boston, MA 02110-1301 USA *
- * *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "core/GP_Debug.h"
-
-#include "GP_TmpFile.h"
-
-static const char file_sig[] = {'G', 'F', 'X', 'p', 'r', 'i', 'm'};
-
-GP_Context *GP_LoadTmpFile(const char *src_path, GP_ProgressCallback *callback)
-{
- FILE *f;
- uint32_t w, h, y;
- uint8_t offset, flags;
- uint32_t bpr;
- enum GP_PixelType pixel_type;
- char sig[sizeof(file_sig)];
- GP_Context *ret;
- int err, i;
-
- f = fopen(src_path, "r");
-
- if (f == NULL)
- return NULL;
-
- /* Read an signature */
- if (fread(sig, sizeof(sig), 1, f) != 1) {
- err = EIO;
- goto err0;
- }
-
- if (strncmp(sig, file_sig, sizeof(sig))) {
- GP_WARN("Invalid file '%s' signature", src_path);
- err = EINVAL;
- goto err0;
- }
-
- /* Read context metadata */
- i = fread(&w, sizeof(w), 1, f);
- i += fread(&h, sizeof(h), 1, f);
- i += fread(&offset, sizeof(offset), 1, f);
- i += fread(&bpr, sizeof(bpr), 1, f);
- i += fread(&pixel_type, sizeof(pixel_type), 1, f);
- i += fread(&flags, 1, 1, f);
-
- if (i != 6 || ferror(f)) {
- err = EIO;
- goto err0;
- }
-
- ret = GP_ContextAlloc(w, h, pixel_type);
-
- if (ret == NULL) {
- err = errno;
- goto err0;
- }
-
- //TODO: We may disagree here on ill aligned subcontexts
- GP_ASSERT(ret->bytes_per_row == bpr, "Invalid bytes per row");
-
- ret->offset = offset;
-
- /* And pixels */
- for (y = 0; y < h; y++) {
- if (fread(ret->pixels + bpr * y, bpr, 1, f) != 1) {
- err = EIO;
- goto err1;
- }
-
- GP_ProgressCallbackReport(callback, y, h, w);
- }
-
- /* Set the rotation flags */
- if (flags & 0x01)
- ret->axes_swap = 1;
-
- if (flags & 0x02)
- ret->x_swap = 1;
-
- if (flags & 0x04)
- ret->y_swap = 1;
-
- fclose(f);
-
- GP_ProgressCallbackDone(callback);
-
- return ret;
-err1:
- GP_ContextFree(ret);
-err0:
- fclose(f);
- errno = err;
- return NULL;
-}
-
-int GP_SaveTmpFile(const GP_Context *src, const char *dst_path,
- GP_ProgressCallback *callback)
-{
- FILE *f;
- int err;
- uint32_t y, i;
-
- f = fopen(dst_path, "w");
-
- if (f == NULL)
- return 1;
-
- /* Write a signature */
- i = fwrite(file_sig, sizeof(file_sig), 1, f);
-
- /* Write block of metadata */
- i += fwrite(&src->w, sizeof(src->w), 1, f);
- i += fwrite(&src->h, sizeof(src->h), 1, f);
- i += fwrite(&src->offset, sizeof(src->offset), 1, f);
- i += fwrite(&src->bytes_per_row, sizeof(src->bytes_per_row), 1, f);
- i += fwrite(&src->pixel_type, sizeof(src->pixel_type), 1, f);
-
- uint8_t flags = 0;
-
- if (src->axes_swap)
- flags |= 0x01;
-
- if (src->x_swap)
- flags |= 0x02;
-
- if (src->y_swap)
- flags |= 0x04;
-
- i += fwrite(&flags, 1, 1, f);
-
- if (i != 7) {
- err = EIO;
- goto err1;
- }
-
- /* And pixels */
- for (y = 0; y < src->h; y++) {
- if (fwrite(src->pixels + src->bytes_per_row * y, src->bytes_per_row, 1, f) != 1) {
- err = EIO;
- goto err1;
- }
-
- GP_ProgressCallbackReport(callback, y, src->h, src->w);
- }
-
- if (fclose(f)) {
- err = errno;
- goto err0;
- }
-
- GP_ProgressCallbackDone(callback);
-
- return 0;
-err1:
- fclose(f);
-err0:
- unlink(dst_path);
- errno = err;
- return 1;
-}
http://repo.or.cz/w/gfxprim.git/commit/f86cf9cc008444620c01b79d1cdffe8352a3…
commit f86cf9cc008444620c01b79d1cdffe8352a36825
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jan 15 20:14:50 2015 +0100
loaders: Add Ex loading function to container API
And fix the ZIP loader as well.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/include/loaders/GP_Container.h b/include/loaders/GP_Container.h
index 2670bc58..c1df3946 100644
--- a/include/loaders/GP_Container.h
+++ b/include/loaders/GP_Container.h
@@ -33,6 +33,8 @@
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
+#include "loaders/GP_DataStorage.h"
+
struct GP_Container;
enum GP_ContainerWhence {
@@ -52,8 +54,8 @@ struct GP_ContainerOps {
/*
* Just loads current image, does not advance to the next image.
*/
- GP_Context *(*Load)(struct GP_Container *self,
- GP_ProgressCallback *callback);
+ int (*LoadEx)(struct GP_Container *self, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback);
/*
* Close callback, use the inline function defined below.
@@ -109,7 +111,18 @@ static inline GP_Context *GP_ContainerLoadNext(GP_Container *self,
/*
* Just loads current image, does not advance to the next one.
*/
-GP_Context *GP_ContainerLoad(GP_Container *self, GP_ProgressCallback *callback);
+int GP_ContainerLoadEx(GP_Container *self, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback);
+
+static inline GP_Context *GP_ContainerLoad(GP_Container *self,
+ GP_ProgressCallback *callback)
+{
+ GP_Context *ret = NULL;
+
+ GP_ContainerLoadEx(self, &ret, NULL, callback);
+
+ return ret;
+}
int GP_ContainerSeek(GP_Container *self, int offset,
enum GP_ContainerWhence whence);
diff --git a/libs/loaders/GP_Container.c b/libs/loaders/GP_Container.c
index 1a90289b..f2dfcc9b 100644
--- a/libs/loaders/GP_Container.c
+++ b/libs/loaders/GP_Container.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2014 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -31,20 +31,22 @@ int GP_ContainerSeek(GP_Container *self, int offset,
if (!self->ops->Seek) {
GP_DEBUG(1, "Seek not implemented in %s container",
self->ops->type);
+ errno = ENOSYS;
return ENOSYS;
}
return self->ops->Seek(self, offset, whence);
}
-GP_Context *GP_ContainerLoad(GP_Container *self, GP_ProgressCallback *callback)
+int GP_ContainerLoadEx(GP_Container *self, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback)
{
- if (!self->ops->Load) {
+ if (!self->ops->LoadEx) {
GP_DEBUG(1, "Load not implemented in %s container",
self->ops->type);
errno = ENOSYS;
- return NULL;
+ return ENOSYS;
}
- return self->ops->Load(self, callback);
+ return self->ops->LoadEx(self, img, storage, callback);
}
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c
index 728f3841..f9ae413c 100644
--- a/libs/loaders/GP_ZIP.c
+++ b/libs/loaders/GP_ZIP.c
@@ -37,8 +37,8 @@
#include <core/GP_Common.h>
#include <core/GP_Debug.h>
-#include <loaders/GP_Loader.h>
-#include <loaders/GP_IOZlib.h>
+#include "loaders/GP_Loader.h"
+#include "loaders/GP_IOZlib.h"
#include "loaders/GP_ZIP.h"
#ifdef HAVE_ZLIB
@@ -241,11 +241,12 @@ static int zip_read_data_desc(GP_IO *io, struct zip_local_header *header)
return 0;
}
-static GP_Context *zip_next_file(struct zip_priv *priv,
- GP_ProgressCallback *callback)
+static int zip_next_file(struct zip_priv *priv, GP_Context **img,
+ GP_DataStorage *storage,
+ GP_ProgressCallback *callback)
{
struct zip_local_header header = {.file_name = NULL};
- int err = 0;
+ int err = 0, res;
GP_Context *ret = NULL;
GP_IO *io;
@@ -302,8 +303,8 @@ static GP_Context *zip_next_file(struct zip_priv *priv,
GP_IOMark(priv->io, GP_IO_MARK);
- ret = GP_ReadImage(priv->io, callback);
- if (errno == ECANCELED)
+ res = GP_ReadImageEx(priv->io, &ret, storage, callback);
+ if (res && errno == ECANCELED)
err = errno;
GP_IOSeek(priv->io, priv->io->mark + header.comp_size, GP_IO_SEEK_SET);
@@ -311,26 +312,15 @@ static GP_Context *zip_next_file(struct zip_priv *priv,
goto out;
break;
case COMPRESS_DEFLATE:
- /* if ((err = read_deflate(priv->io, &header, &io))) {
+ io = GP_IOZlib(priv->io, header.comp_size);
+ if (!io) {
err = errno;
goto out;
}
- GP_DEBUG(1, "Reading image");
- ret = GP_ReadImage(io, callback);
- if (errno == ECANCELED)
- err = errno;
-
- GP_IOClose(io);
- goto out;
- */
-
- io = GP_IOZlib(priv->io, header.comp_size);
- if (!io)
- goto out;
GP_DEBUG(1, "Reading image");
- ret = GP_ReadImage(io, callback);
- if (errno == ECANCELED)
+ res = GP_ReadImageEx(io, &ret, storage, callback);
+ if (res && errno == ECANCELED)
err = errno;
/*
@@ -361,7 +351,8 @@ static GP_Context *zip_next_file(struct zip_priv *priv,
out:
free(header.file_name);
errno = err;
- return ret;
+ *img = ret;
+ return err;
}
static unsigned int last_offset_idx(struct zip_priv *priv)
@@ -421,33 +412,39 @@ static void record_offset(struct zip_priv *priv, long offset)
*/
}
-static GP_Context *zip_load_next(GP_Container *self,
- GP_ProgressCallback *callback)
+static int zip_load_next(GP_Container *self, GP_Context **img,
+ GP_DataStorage *storage,
+ GP_ProgressCallback *callback)
{
struct zip_priv *priv = GP_CONTAINER_PRIV(self);
- GP_Context *ret;
- long offset;
+ int err;
GP_DEBUG(1, "Trying to load next image from ZIP container");
- do {
- offset = GP_IOTell(priv->io);
- ret = zip_next_file(priv, callback);
- } while (ret == NULL && errno == 0);
+ *img = NULL;
- if (!ret)
- return NULL;
+ do {
+ err = zip_next_file(priv, img, storage, callback);
+ } while (!*img && errno == 0);
- if (ret)
- record_offset(priv, offset);
+ if (err)
+ return 1;
record_offset(priv, GP_IOTell(priv->io));
priv->cur_pos++;
- //self->cur_img++;
self->cur_img = priv->cur_pos;
- return ret;
+ return 0;
+}
+
+static GP_Context *load_next(GP_Container *self, GP_ProgressCallback *callback)
+{
+ GP_Context *img = NULL;
+
+ zip_load_next(self, &img, NULL, callback);
+
+ return img;
}
/* Seek to the current position */
@@ -573,19 +570,15 @@ static int zip_seek(GP_Container *self, int offset,
return ret;
}
-static GP_Context *zip_load(GP_Container *self,
- GP_ProgressCallback *callback)
+static int zip_load(GP_Container *self, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback)
{
- GP_Context *img;
-
- img = zip_load_next(self, callback);
-
- if (!img)
- return NULL;
+ if (zip_load_next(self, img, storage, callback))
+ return 1;
zip_seek(self, -1, GP_CONT_CUR);
- return img;
+ return 0;
}
static void zip_close(GP_Container *self)
@@ -649,8 +642,8 @@ err0:
}
static const struct GP_ContainerOps zip_ops = {
- .LoadNext = zip_load_next,
- .Load = zip_load,
+ .LoadNext = load_next,
+ .LoadEx = zip_load,
.Close = zip_close,
.Seek = zip_seek,
.type = "ZIP",
http://repo.or.cz/w/gfxprim.git/commit/54959be6241f6fe85a39f72e9ba88e3d42d0…
commit 54959be6241f6fe85a39f72e9ba88e3d42d06835
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jan 2 11:35:18 2015 +0100
demos: bogoman: Many improvements.
* New type of blocks
* Rendering optimalizations
* Fixed window resize handling
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/bogoman/bogoman.c b/demos/bogoman/bogoman.c
index 0f745847..a83cba38 100644
--- a/demos/bogoman/bogoman.c
+++ b/demos/bogoman/bogoman.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -27,7 +27,7 @@
#include "bogoman_loader.h"
#include "bogoman_render.h"
-#define ELEM_SIZE 33
+#define ELEM_SIZE 27
static void save_png(struct bogoman_map *map, unsigned int elem_size,
const char *filename)
@@ -59,8 +59,10 @@ static void save_png(struct bogoman_map *map, unsigned int elem_size,
static struct GP_Backend *backend;
-static void event_loop(struct bogoman_map *map)
+static void event_loop(struct bogoman_render *render, GP_Backend *backend)
{
+ struct bogoman_map *map = render->map;
+
while (GP_BackendEventsQueued(backend)) {
GP_Event ev;
@@ -89,6 +91,19 @@ static void event_loop(struct bogoman_map *map)
bogoman_map_player_move(map, 0, 1);
break;
}
+ bogoman_render(render, BOGOMAN_RENDER_DIRTY);
+ break;
+ case GP_EV_SYS:
+ switch (ev.code) {
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(backend);
+ bogoman_render(render, BOGOMAN_RENDER_ALL);
+ break;
+ }
+ break;
+ case GP_EV_TMR:
+ bogoman_map_timer_tick(render->map);
+ bogoman_render(render, BOGOMAN_RENDER_DIRTY);
break;
}
}
@@ -99,6 +114,7 @@ static void event_loop(struct bogoman_map *map)
int main(int argc, char *argv[])
{
struct bogoman_map *map;
+ GP_TIMER_DECLARE(timer, 0, 300, "Refresh", NULL, NULL);
bogoman_set_dbg_level(10);
@@ -129,20 +145,17 @@ int main(int argc, char *argv[])
.map_x_offset = 0,
.map_y_offset = 0,
.ctx = backend->context,
+ .backend = backend,
.map_elem_size = ELEM_SIZE,
};
bogoman_render(&render, BOGOMAN_RENDER_ALL);
- GP_BackendFlip(backend);
-
- for (;;) {
- GP_BackendPoll(backend);
- event_loop(map);
- bogoman_render(&render, BOGOMAN_RENDER_DIRTY);
- GP_BackendFlip(backend);
+ GP_BackendAddTimer(backend, &timer);
- usleep(50000);
+ for (;;) {
+ GP_BackendWait(backend);
+ event_loop(&render, backend);
}
return 0;
diff --git a/demos/bogoman/bogoman_loader.c b/demos/bogoman/bogoman_loader.c
index 935bc3e3..e4e17c1d 100644
--- a/demos/bogoman/bogoman_loader.c
+++ b/demos/bogoman/bogoman_loader.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -81,6 +81,15 @@ static enum bogoman_map_elem_id id_from_char(const char ch)
return BOGOMAN_MOVEABLE;
case 'E':
return BOGOMAN_EDIBLE;
+ case '(':
+ case ')':
+ case 'O':
+ case 'o':
+ case '<':
+ case '>':
+ case '^':
+ case 'v':
+ return BOGOMAN_PARTICLE;
}
WARN("Unknown map character '%c'", ch);
@@ -93,6 +102,7 @@ static enum bogoman_map_elem_id id_from_char(const char ch)
struct line {
unsigned int len;
unsigned char line[LINE_MAX];
+ unsigned char input[LINE_MAX];
};
static void get_line(FILE *f, struct line *l)
@@ -106,6 +116,7 @@ static void get_line(FILE *f, struct line *l)
case 'n':
return;
default:
+ l->input[l->len] = ch;
l->line[l->len++] = id_from_char(ch);
break;
}
@@ -140,19 +151,19 @@ static void load_map(FILE *f, struct bogoman_map *map)
case BOGOMAN_WALL:
if (x > 0 &&
line_cur->line[x - 1] == BOGOMAN_WALL)
- elem->flags |= BOGOMAN_WALL_LEFT;
+ elem->flags |= BOGOMAN_LEFT;
if (x + 1 < line_cur->len &&
line_cur->line[x + 1] == BOGOMAN_WALL)
- elem->flags |= BOGOMAN_WALL_RIGHT;
+ elem->flags |= BOGOMAN_RIGHT;
if (y > 0 &&
- bogoman_map_is_id(map, x, y-1, BOGOMAN_WALL))
- elem->flags |= BOGOMAN_WALL_UP;
+ bogoman_map_elem_id(map, x, y-1) == BOGOMAN_WALL)
+ elem->flags |= BOGOMAN_UP;
if (x < line_next->len &&
line_next->line[x] == BOGOMAN_WALL)
- elem->flags |= BOGOMAN_WALL_DOWN;
+ elem->flags |= BOGOMAN_DOWN;
break;
case BOGOMAN_PLAYER:
@@ -168,6 +179,34 @@ static void load_map(FILE *f, struct bogoman_map *map)
case BOGOMAN_DIAMOND:
map->diamonds_total++;
break;
+ case BOGOMAN_PARTICLE:
+ switch (line_cur->input[x]) {
+ case '(':
+ elem->flags = BOGOMAN_LEFT | BOGOMAN_PARTICLE_ROUND;
+ break;
+ case ')':
+ elem->flags = BOGOMAN_RIGHT | BOGOMAN_PARTICLE_ROUND;
+ break;
+ case 'O':
+ elem->flags = BOGOMAN_UP | BOGOMAN_PARTICLE_ROUND;
+ break;
+ case 'o':
+ elem->flags = BOGOMAN_DOWN | BOGOMAN_PARTICLE_ROUND;
+ break;
+ case '<':
+ elem->flags = BOGOMAN_LEFT | BOGOMAN_PARTICLE_SQUARE;
+ break;
+ case '>':
+ elem->flags = BOGOMAN_RIGHT | BOGOMAN_PARTICLE_SQUARE;
+ break;
+ case '^':
+ elem->flags = BOGOMAN_UP | BOGOMAN_PARTICLE_SQUARE;
+ break;
+ case 'v':
+ elem->flags = BOGOMAN_DOWN | BOGOMAN_PARTICLE_SQUARE;
+ break;
+ }
+ break;
default:
break;
}
diff --git a/demos/bogoman/bogoman_map.c b/demos/bogoman/bogoman_map.c
index b9117441..2919fc00 100644
--- a/demos/bogoman/bogoman_map.c
+++ b/demos/bogoman/bogoman_map.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -30,22 +30,22 @@
static void print_wall(struct bogoman_map_elem *elem)
{
switch (elem->flags) {
- case BOGOMAN_WALL_LEFT:
- case BOGOMAN_WALL_RIGHT:
- case BOGOMAN_WALL_LEFT | BOGOMAN_WALL_RIGHT:
+ case BOGOMAN_LEFT:
+ case BOGOMAN_RIGHT:
+ case BOGOMAN_LEFT | BOGOMAN_RIGHT:
printf("-");
break;
- case BOGOMAN_WALL_UP:
- case BOGOMAN_WALL_DOWN:
- case BOGOMAN_WALL_UP | BOGOMAN_WALL_DOWN:
+ case BOGOMAN_UP:
+ case BOGOMAN_DOWN:
+ case BOGOMAN_UP | BOGOMAN_DOWN:
printf("|");
break;
- case BOGOMAN_WALL_UP | BOGOMAN_WALL_RIGHT:
- case BOGOMAN_WALL_DOWN | BOGOMAN_WALL_LEFT:
+ case BOGOMAN_UP | BOGOMAN_RIGHT:
+ case BOGOMAN_DOWN | BOGOMAN_LEFT:
printf("\");
break;
- case BOGOMAN_WALL_UP | BOGOMAN_WALL_LEFT:
- case BOGOMAN_WALL_DOWN | BOGOMAN_WALL_RIGHT:
+ case BOGOMAN_UP | BOGOMAN_LEFT:
+ case BOGOMAN_DOWN | BOGOMAN_RIGHT:
printf("/");
break;
default:
@@ -54,6 +54,48 @@ static void print_wall(struct bogoman_map_elem *elem)
}
}
+static void print_particle(struct bogoman_map_elem *elem)
+{
+ char c = '?';
+ int dir = elem->flags & BOGOMAN_DIRECTION_MASK;
+
+ if (elem->flags & BOGOMAN_PARTICLE_ROUND) {
+ switch (dir) {
+ case BOGOMAN_LEFT:
+ c = '(';
+ break;
+ case BOGOMAN_RIGHT:
+ c = ')';
+ break;
+ case BOGOMAN_UP:
+ c = 'O';
+ break;
+ case BOGOMAN_DOWN:
+ c = 'o';
+ break;
+ }
+ }
+
+ if (elem->flags & BOGOMAN_PARTICLE_SQUARE) {
+ switch (dir) {
+ case BOGOMAN_LEFT:
+ c = '<';
+ break;
+ case BOGOMAN_RIGHT:
+ c = '>';
+ break;
+ case BOGOMAN_UP:
+ c = '^';
+ break;
+ case BOGOMAN_DOWN:
+ c = 'v';
+ break;
+ }
+ }
+
+ putchar(c);
+}
+
void bogoman_map_dump(struct bogoman_map *map)
{
unsigned int x, y;
@@ -83,6 +125,9 @@ void bogoman_map_dump(struct bogoman_map *map)
case BOGOMAN_WALL:
print_wall(elem);
break;
+ case BOGOMAN_PARTICLE:
+ print_particle(elem);
+ break;
}
}
@@ -139,8 +184,6 @@ static void move_get_diamond(struct bogoman_map *map,
static int try_move_block(struct bogoman_map *map,
int x, int y, int dx, int dy)
{
- struct bogoman_map_elem *elem = bogoman_get_map_elem(map, x, y);
-
int new_x = (int)x + dx;
int new_y = (int)y + dy;
@@ -194,6 +237,7 @@ void bogoman_map_player_move(struct bogoman_map *map, int x, int y)
case BOGOMAN_DIAMOND:
move_get_diamond(map, px, py);
break;
+ case BOGOMAN_PARTICLE:
case BOGOMAN_MOVEABLE:
if (!try_move_block(map, px, py, dx, dy))
goto finish_move;
@@ -231,15 +275,75 @@ finish_move:
void bogoman_map_timer_tick(struct bogoman_map *map)
{
- unsigned int x, y;
+ unsigned int x, y, moved;
+ struct bogoman_map_elem *elem;
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
struct bogoman_map_elem *elem;
-
elem = bogoman_get_map_elem(map, x, y);
-
- //TODO
+ elem->moved = 0;
}
}
+
+ do {
+ moved = 0;
+
+ for (y = 0; y < map->h; y++) {
+ for (x = 0; x < map->w; x++) {
+ int dir_x = 0, dir_y = 0;
+ elem = bogoman_get_map_elem(map, x, y);
+
+ if (elem->id != BOGOMAN_PARTICLE)
+ continue;
+
+ if (elem->moved)
+ continue;
+
+ switch (elem->flags & BOGOMAN_DIRECTION_MASK) {
+ case BOGOMAN_LEFT:
+ dir_x = -1;
+ break;
+ case BOGOMAN_RIGHT:
+ dir_x = 1;
+ break;
+ case BOGOMAN_UP:
+ dir_y = -1;
+ break;
+ case BOGOMAN_DOWN:
+ dir_y = +1;
+ break;
+ default:
+ continue;
+ }
+
+ if (!bogoman_is_empty(map, x + dir_x, y + dir_y)) {
+ if (!(elem->flags & BOGOMAN_PARTICLE_ROUND))
+ continue;
+
+ if (dir_x) {
+ //TODO randomly choose direction
+ if (bogoman_is_empty(map, x+dir_x, y-1))
+ dir_y = -1;
+ if (bogoman_is_empty(map, x+dir_x, y+1))
+ dir_y = 1;
+ }
+
+ if (dir_y) {
+ if (bogoman_is_empty(map, x-1, y+dir_y))
+ dir_x = -1;
+ if (bogoman_is_empty(map, x+1, y+dir_y))
+ dir_x = 1;
+ }
+
+ if (!dir_x || !dir_y)
+ continue;
+ }
+
+ elem->moved = 1;
+ bogoman_switch(map, x, y, x + dir_x, y + dir_y);
+ moved++;
+ }
+ }
+ } while (moved);
}
diff --git a/demos/bogoman/bogoman_map.h b/demos/bogoman/bogoman_map.h
index fe7c1f14..e4d3c096 100644
--- a/demos/bogoman/bogoman_map.h
+++ b/demos/bogoman/bogoman_map.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -36,19 +36,27 @@ enum bogoman_map_elem_id {
BOGOMAN_MOVEABLE = 0x04,
/* like a diamond but doesn't counts to points */
BOGOMAN_EDIBLE = 0x05,
+ /* particles, move in defined direction unless stoppend by objects */
+ BOGOMAN_PARTICLE = 0x06,
- BOGOMAN_MAX = BOGOMAN_EDIBLE,
+ BOGOMAN_MAX = BOGOMAN_PARTICLE,
};
/*
- * Wall cal be applied as bitflags. Each bitflag determines wall continuation
- * in particular direction.
+ * Lower 8 bits defines continuation for walls, direction for particles, etc.
*/
-enum bogoman_wall_flags {
- BOGOMAN_WALL_LEFT = 0x01,
- BOGOMAN_WALL_RIGHT = 0x02,
- BOGOMAN_WALL_UP = 0x04,
- BOGOMAN_WALL_DOWN = 0x08,
+enum bogoman_direction_flags {
+ BOGOMAN_LEFT = 0x01,
+ BOGOMAN_RIGHT = 0x02,
+ BOGOMAN_UP = 0x04,
+ BOGOMAN_DOWN = 0x08,
+
+ BOGOMAN_DIRECTION_MASK = 0x0f,
+};
+
+enum bogoman_particle_flags {
+ BOGOMAN_PARTICLE_ROUND = 0x10,
+ BOGOMAN_PARTICLE_SQUARE = 0x20,
};
struct bogoman_map_elem {
@@ -57,6 +65,7 @@ struct bogoman_map_elem {
/* the element changed, needs to be redrawn */
unsigned char dirty:1;
+ unsigned char moved:1;
};
struct bogoman_map {
@@ -91,13 +100,13 @@ static inline enum bogoman_map_elem_id
return elem->id;
}
-static inline int bogoman_map_is_id(struct bogoman_map *map,
- unsigned int x, unsigned int y,
- enum bogoman_map_elem_id id)
+static inline enum bogoman_map_elem_id
+ bogoman_map_elem_id(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
{
struct bogoman_map_elem *elem = bogoman_get_map_elem(map, x, y);
- return elem->id == id;
+ return elem->id;
}
static inline int bogoman_coord_in_map(struct bogoman_map *map, int x, int y)
@@ -106,12 +115,30 @@ static inline int bogoman_coord_in_map(struct bogoman_map *map, int x, int y)
(y >= 0) && ((unsigned)y < map->w);
}
-static inline int bogoman_is_empty(struct bogoman_map *map,
- unsigned int x, unsigned int y)
+static inline int bogoman_is_empty(struct bogoman_map *map, int x, int y)
{
+ if (!bogoman_coord_in_map(map, x, y))
+ return 0;
+
return bogoman_get_map_elem_id(map, x, y) == BOGOMAN_NONE;
}
+static inline void bogoman_switch(struct bogoman_map *map,
+ int x1, int y1, int x2, int y2)
+{
+ struct bogoman_map_elem *i, *j, tmp;
+
+ i = bogoman_get_map_elem(map, x1, y1);
+ j = bogoman_get_map_elem(map, x2, y2);
+
+ tmp = *i;
+ *i = *j;
+ *j = tmp;
+
+ i->dirty = 1;
+ j->dirty = 1;
+}
+
void bogoman_map_player_move(struct bogoman_map *map, int x, int y);
void bogoman_map_timer_tick(struct bogoman_map *map);
diff --git a/demos/bogoman/bogoman_render.c b/demos/bogoman/bogoman_render.c
index c2ebc10b..bc47f7d2 100644
--- a/demos/bogoman/bogoman_render.c
+++ b/demos/bogoman/bogoman_render.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -48,19 +48,25 @@ struct render_colors {
/* edible color */
GP_Pixel edible;
+
+ /* particle colors */
+ GP_Pixel particle;
+ GP_Pixel particle_dir;
};
static struct render_colors colors;
static void init_colors(GP_Context *ctx, struct render_colors *colors)
{
- colors->bg = GP_RGBToContextPixel(0xee, 0xee, 0xee, ctx);
- colors->player = GP_RGBToContextPixel(0x00, 0xee, 0x00, ctx);
- colors->frames = GP_RGBToContextPixel(0x00, 0x00, 0x00, ctx);
- colors->diamond = GP_RGBToContextPixel(0x00, 0x00, 0xee, ctx);
- colors->wall = GP_RGBToContextPixel(0x66, 0x66, 0x66, ctx);
- colors->moveable = GP_RGBToContextPixel(0xff, 0xff, 0x60, ctx);
- colors->edible = GP_RGBToContextPixel(0xff, 0x7f, 0x50, ctx);
+ colors->bg = GP_RGBToContextPixel(0xee, 0xee, 0xee, ctx);
+ colors->player = GP_RGBToContextPixel(0x00, 0xee, 0x00, ctx);
+ colors->frames = GP_RGBToContextPixel(0x00, 0x00, 0x00, ctx);
+ colors->diamond = GP_RGBToContextPixel(0x00, 0x00, 0xee, ctx);
+ colors->wall = GP_RGBToContextPixel(0x66, 0x66, 0x66, ctx);
+ colors->moveable = GP_RGBToContextPixel(0xff, 0xff, 0x60, ctx);
+ colors->edible = GP_RGBToContextPixel(0xff, 0x7f, 0x50, ctx);
+ colors->particle = GP_RGBToContextPixel(0xff, 0xff, 0x00, ctx);
+ colors->particle_dir = GP_RGBToContextPixel(0xff, 0x44, 0x00, ctx);
}
static void render_none(struct bogoman_render *render,
@@ -83,8 +89,9 @@ static void render_player(struct bogoman_render *render,
(void) elem;
GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+
GP_FillCircle(render->ctx, x + w/2, y + w/2, w/2 - 1, colors.player);
- GP_Circle(render->ctx, x + w/2, y + w/2, w/2 - 1, colors.frames);
+ GP_FillRing(render->ctx, x + w/2, y + w/2, w/2 - 1, w/2 - 2, colors.frames);
}
static void render_wall(struct bogoman_render *render,
@@ -95,17 +102,25 @@ static void render_wall(struct bogoman_render *render,
GP_FillRectXYWH(render->ctx, x, y, w, w, colors.wall);
- if (!(elem->flags & BOGOMAN_WALL_LEFT))
+ if (!(elem->flags & BOGOMAN_LEFT)) {
GP_VLineXYH(render->ctx, x, y, w, colors.frames);
+ GP_VLineXYH(render->ctx, x+1, y, w, colors.frames);
+ }
- if (!(elem->flags & BOGOMAN_WALL_RIGHT))
+ if (!(elem->flags & BOGOMAN_RIGHT)) {
GP_VLineXYH(render->ctx, x + w - 1, y, w, colors.frames);
+ GP_VLineXYH(render->ctx, x + w - 2, y, w, colors.frames);
+ }
- if (!(elem->flags & BOGOMAN_WALL_UP))
+ if (!(elem->flags & BOGOMAN_UP)) {
GP_HLineXYW(render->ctx, x, y, w, colors.frames);
+ GP_HLineXYW(render->ctx, x, y+1, w, colors.frames);
+ }
- if (!(elem->flags & BOGOMAN_WALL_DOWN))
+ if (!(elem->flags & BOGOMAN_DOWN)) {
GP_HLineXYW(render->ctx, x, y + w - 1, w, colors.frames);
+ GP_HLineXYW(render->ctx, x, y + w - 2, w, colors.frames);
+ }
}
static void render_diamond(struct bogoman_render *render,
@@ -116,11 +131,15 @@ static void render_diamond(struct bogoman_render *render,
GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+ (void) elem;
+
GP_FillTetragon(render->ctx, x + w/2, y, x + w - 1, y + w/2,
x + w/2, y + w - 1, x, y + w/2, colors.diamond);
GP_Tetragon(render->ctx, x + w/2, y, x + w - 1, y + w/2,
x + w/2, y + w - 1, x, y + w/2, colors.frames);
+ GP_Tetragon(render->ctx, x + w/2, y+1, x + w - 2, y + w/2,
+ x + w/2, y + w - 2, x+1, y + w/2, colors.frames);
}
static void render_moveable(struct bogoman_render *render,
@@ -129,10 +148,13 @@ static void render_moveable(struct bogoman_render *render,
{
unsigned int w = render->map_elem_size;
+ (void) elem;
+
GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
GP_FillRectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.moveable);
GP_RectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.frames);
+ GP_RectXYWH(render->ctx, x + 2, y + 2, w - 4, w - 4, colors.frames);
}
static void render_edible(struct bogoman_render *render,
@@ -141,11 +163,62 @@ static void render_edible(struct bogoman_render *render,
{
unsigned int w = render->map_elem_size;
+ (void) elem;
+
GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
GP_FillRectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.edible);
}
+static void render_particle(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+ int dir = elem->flags & BOGOMAN_DIRECTION_MASK;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+
+ switch (elem->flags & ~BOGOMAN_DIRECTION_MASK) {
+ case BOGOMAN_PARTICLE_ROUND:
+ GP_FillCircle(render->ctx, x + w/2, y + w/2, w/2-1, colors.particle);
+ GP_FillRing(render->ctx, x + w/2, y + w/2, w/2 - 1, w/2 - 2, colors.frames);
+ break;
+ case BOGOMAN_PARTICLE_SQUARE:
+ GP_FillRectXYWH(render->ctx, x+1, y+1, w-2, w-2, colors.particle);
+ GP_RectXYWH(render->ctx, x+1, y+1, w-2, w-2, colors.frames);
+ GP_RectXYWH(render->ctx, x+2, y+2, w-4, w-4, colors.frames);
+ break;
+ }
+
+ switch (dir) {
+ case BOGOMAN_LEFT:
+ GP_FillTriangle(render->ctx, x + w/4, y + w/2,
+ x + 5*w/8, y + w/4, x + 5*w/8, y + 3*w/4, colors.particle_dir);
+ GP_Triangle(render->ctx, x + w/4, y + w/2,
+ x + 5*w/8, y + w/4, x + 5*w/8, y + 3*w/4, colors.frames);
+ break;
+ case BOGOMAN_RIGHT:
+ GP_FillTriangle(render->ctx, x + 3*w/4, y + w/2,
+ x + 3*w/8, y + w/4, x + 3*w/8, y + 3*w/4, colors.particle_dir);
+ GP_Triangle(render->ctx, x + 3*w/4, y + w/2,
+ x + 3*w/8, y + w/4, x + 3*w/8, y + 3*w/4, colors.frames);
+ break;
+ case BOGOMAN_UP:
+ GP_FillTriangle(render->ctx, x + w/2, y + w/4,
+ x + w/4, y + 5*w/8, x + 3*w/4, y + 5*w/8, colors.particle_dir);
+ GP_Triangle(render->ctx, x + w/2, y + w/4,
+ x + w/4, y + 5*w/8, x + 3*w/4, y + 5*w/8, colors.frames);
+ break;
+ case BOGOMAN_DOWN:
+ GP_FillTriangle(render->ctx, x + w/2, y + 3*w/4,
+ x + w/4, y + 3*w/8, x + 3*w/4, y + 3*w/8, colors.particle_dir);
+ GP_Triangle(render->ctx, x + w/2, y + 3*w/4,
+ x + w/4, y + 3*w/8, x + 3*w/4, y + 3*w/8, colors.frames);
+ break;
+ }
+}
+
static void (*renders[])(struct bogoman_render *render,
unsigned int x, unsigned int y,
struct bogoman_map_elem *elem) =
@@ -156,6 +229,7 @@ static void (*renders[])(struct bogoman_render *render,
render_diamond,
render_moveable,
render_edible,
+ render_particle,
};
static void render_elem(struct bogoman_render *render,
@@ -181,6 +255,12 @@ static void render_elem(struct bogoman_render *render,
WARN("Invalid elem ID %u at %ux%un", elem->id, x, y);
else
renders[elem->id](render, cx, cy, elem);
+
+ if (flags & BOGOMAN_RENDER_DIRTY && render->backend) {
+ GP_BackendUpdateRect(render->backend, cx, cy,
+ cx + render->map_elem_size,
+ cy + render->map_elem_size);
+ }
}
void bogoman_render(struct bogoman_render *render, int flags)
@@ -190,9 +270,14 @@ void bogoman_render(struct bogoman_render *render, int flags)
//TODO: Hack
init_colors(render->ctx, &colors);
+ if (flags & BOGOMAN_RENDER_ALL)
+ GP_Fill(render->ctx, colors.bg);
+
for (y = render->map_x_offset; y < render->map->h; y++) {
- for (x = render->map_x_offset; x < render->map->w; x++) {
+ for (x = render->map_x_offset; x < render->map->w; x++)
render_elem(render, x, y, flags);
- }
}
+
+ if (flags & BOGOMAN_RENDER_ALL && render->backend)
+ GP_BackendFlip(render->backend);
}
diff --git a/demos/bogoman/bogoman_render.h b/demos/bogoman/bogoman_render.h
index f813cdc1..e27744e2 100644
--- a/demos/bogoman/bogoman_render.h
+++ b/demos/bogoman/bogoman_render.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2015 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -37,14 +37,17 @@ struct bogoman_render {
/* context to be used for rendering */
struct GP_Context *ctx;
+ /* if not NULL is used to update screen */
+ struct GP_Backend *backend;
+
/* elem size in pixels */
unsigned int map_elem_size;
};
enum bogonam_render_flags {
/* renders all map elements, not only dirty ones */
- BOGOMAN_RENDER_ALL = 0x00,
- BOGOMAN_RENDER_DIRTY = 0x01,
+ BOGOMAN_RENDER_ALL = 0x01,
+ BOGOMAN_RENDER_DIRTY = 0x02,
};
void bogoman_render(struct bogoman_render *render, int flags);
diff --git a/demos/bogoman/levels/02-paticles.txt b/demos/bogoman/levels/02-paticles.txt
new file mode 100644
index 00000000..1c1dbf15
--- /dev/null
+++ b/demos/bogoman/levels/02-paticles.txt
@@ -0,0 +1,10 @@
+/------------+|$))))E @|
+|)))))E |
++------ |
+| |
+++++-E-++ |
++++/OOO++ |
+++/OOOOO+ |
+++$$$$$$$| |
++-------+---/
diff --git a/demos/bogoman/map.txt b/demos/bogoman/map.txt
index 337d07ca..3e360f91 100644
--- a/demos/bogoman/map.txt
+++ b/demos/bogoman/map.txt
@@ -1,8 +1,8 @@
+---------+ +----+
| | | | | $ |
| +----+ |
-| E @ |
+|> E @ (<|
+--M----------------+
| M |
-| |$|$|$| |
+|^v |$|$|$| |
+----------+-+-+-+--+
http://repo.or.cz/w/gfxprim.git/commit/380af9d42b91493a3cb726a075279e29030b…
commit 380af9d42b91493a3cb726a075279e29030ba679
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Dec 25 19:19:32 2014 +0100
loaders: Loader: Implement missing functions
* Implement GP_LoaderReadImageEx()
* Add missing LoadImageEx for BMP, PSD and PSP
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt
index 794755eb..0266e70d 100644
--- a/build/syms/Loaders_symbols.txt
+++ b/build/syms/Loaders_symbols.txt
@@ -20,15 +20,17 @@ GP_PNG
GP_MatchBMP
GP_WriteBMP
GP_LoadBMP
-GP_ReadBMPEx
+GP_LoadBMPEx
GP_ReadBMP
+GP_ReadBMPEx
GP_SaveBMP
GP_BMP
GP_MatchPSP
GP_ReadPSP
-GP_LoadPSP
GP_ReadPSPEx
+GP_LoadPSP
+GP_LoadPSPEx
GP_PSP
GP_MatchGIF
@@ -96,6 +98,7 @@ GP_PCX
GP_ReadPSD
GP_ReadPSDEx
GP_LoadPSD
+GP_LoadPSDEx
GP_MatchPSD
GP_PSD
@@ -122,6 +125,7 @@ GP_LoaderRegister
GP_LoaderUnregister
GP_ContainerLoad
+GP_ContainerLoadEx
GP_ContainerSeek
GP_MatchZip
diff --git a/libs/loaders/GP_BMP.c b/libs/loaders/GP_BMP.c
index 84d7c97f..8b890f90 100644
--- a/libs/loaders/GP_BMP.c
+++ b/libs/loaders/GP_BMP.c
@@ -733,6 +733,12 @@ GP_Context *GP_LoadBMP(const char *src_path, GP_ProgressCallback *callback)
return GP_LoaderLoadImage(&GP_BMP, src_path, callback);
}
+int GP_LoadBMPEx(const char *src_path, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback)
+{
+ return GP_LoaderLoadImageEx(&GP_BMP, src_path, img, storage, callback);
+}
+
/*
* Rows in bmp are four byte aligned.
*/
diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c
index 8bc9caf1..84461f99 100644
--- a/libs/loaders/GP_Loader.c
+++ b/libs/loaders/GP_Loader.c
@@ -296,7 +296,7 @@ int GP_LoaderLoadImageEx(const GP_Loader *self, const char *src_path,
if (!self->Read) {
errno = ENOSYS;
- return 1;
+ return ENOSYS;
}
io = GP_IOFile(src_path, GP_IO_RDONLY);
@@ -328,19 +328,30 @@ GP_Context *GP_LoaderReadImage(const GP_Loader *self, GP_IO *io,
{
GP_Context *ret = NULL;
+ GP_LoaderReadImageEx(self, io, &ret, NULL, callback);
+
+ return ret;
+}
+
+int GP_LoaderReadImageEx(const GP_Loader *self, GP_IO *io,
+ GP_Context **img, GP_DataStorage *data,
+ GP_ProgressCallback *callback)
+{
GP_DEBUG(1, "Reading image (I/O %p)", io);
- self->Read(io, &ret, NULL, callback);
+ if (!self->Read) {
+ errno = ENOSYS;
+ return ENOSYS;
+ }
- return ret;
+ return self->Read(io, img, data, callback);
}
GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback)
{
- GP_Context *ret;
+ GP_Context *ret = NULL;
- if (GP_LoadImageEx(src_path, &ret, NULL, callback))
- return NULL;
+ GP_LoadImageEx(src_path, &ret, NULL, callback);
return ret;
}
diff --git a/libs/loaders/GP_PSD.c b/libs/loaders/GP_PSD.c
index 0f3970a8..c6308113 100644
--- a/libs/loaders/GP_PSD.c
+++ b/libs/loaders/GP_PSD.c
@@ -843,6 +843,12 @@ GP_Context *GP_ReadPSD(GP_IO *io, GP_ProgressCallback *callback)
return GP_LoaderReadImage(&GP_PSD, io, callback);
}
+int GP_LoadPSDEx(const char *src_path, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback)
+{
+ return GP_LoaderLoadImageEx(&GP_PSD, src_path, img, storage, callback);
+}
+
struct GP_Loader GP_PSD = {
.Read = GP_ReadPSDEx,
.Match = GP_MatchPSD,
diff --git a/libs/loaders/GP_PSP.c b/libs/loaders/GP_PSP.c
index 2ace2619..02041632 100644
--- a/libs/loaders/GP_PSP.c
+++ b/libs/loaders/GP_PSP.c
@@ -524,6 +524,12 @@ GP_Context *GP_ReadPSP(GP_IO *io, GP_ProgressCallback *callback)
return GP_LoaderReadImage(&GP_PSP, io, callback);
}
+int GP_LoadPSPEx(const char *src_path, GP_Context **img,
+ GP_DataStorage *storage, GP_ProgressCallback *callback)
+{
+ return GP_LoaderLoadImageEx(&GP_PSP, src_path, img, storage, callback);
+}
+
struct GP_Loader GP_PSP = {
.Read = GP_ReadPSPEx,
.Match = GP_MatchPSP,
http://repo.or.cz/w/gfxprim.git/commit/69fbdb92d0f48c5d030d2cc0cb0c475b7546…
commit 69fbdb92d0f48c5d030d2cc0cb0c475b75464774
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Dec 25 19:08:36 2014 +0100
loaders: PSP: Add some more metadata.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_PSP.c b/libs/loaders/GP_PSP.c
index 74936f37..2ace2619 100644
--- a/libs/loaders/GP_PSP.c
+++ b/libs/loaders/GP_PSP.c
@@ -173,8 +173,19 @@ struct psp_img_attrs {
uint8_t subblock;
void *priv;
GP_Context *img;
+ GP_DataStorage *storage;
};
+static void fill_metadata(struct psp_img_attrs *attrs)
+{
+ GP_DataStorageAddInt(attrs->storage, NULL, "Width", attrs->w);
+ GP_DataStorageAddInt(attrs->storage, NULL, "Height", attrs->h);
+ GP_DataStorageAddString(attrs->storage, NULL, "Compression",
+ psp_comp_type_name(attrs->comp_type));
+ GP_DataStorageAddInt(attrs->storage, NULL, "Bit Depth",
+ attrs->bit_depth);
+}
+
static int psp_read_general_img_attr_chunk(GP_IO *io,
struct psp_img_attrs *attrs)
{
@@ -220,10 +231,13 @@ static int psp_read_general_img_attr_chunk(GP_IO *io,
attrs->bit_depth, attrs->grayscale_flag);
GP_DEBUG(3, "Image colors=%u, layer_count=%u, active_layer=%u",
- attrs->color_count, attrs->layer_count, attrs->active_layer);
+ attrs->color_count, attrs->layer_count, attrs->active_layer);
attrs->is_loaded = 1;
+ if (attrs->storage)
+ fill_metadata(attrs);
+
return 0;
}
@@ -449,7 +463,7 @@ int GP_ReadPSPEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
{
int err = 0;
struct psp_img_attrs attrs = {.is_loaded = 0, .subblock = 0,
- .priv = NULL, .img = NULL};
+ .priv = NULL, .img = NULL, .storage = storage};
struct psp_version version;
uint16_t psp_header[] = {
http://repo.or.cz/w/gfxprim.git/commit/80386afaf5cbd6c805140ae1e0f8e3791866…
commit 80386afaf5cbd6c805140ae1e0f8e37918666e23
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Dec 25 18:21:17 2014 +0100
demos: zip_container: Use clipped blit.
Otherwise the example fails on assert() in GP_Blit.c when image is
larger than screen window.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/demos/c_simple/zip_container.c b/demos/c_simple/zip_container.c
index 6e241087..1fe5e36f 100644
--- a/demos/c_simple/zip_container.c
+++ b/demos/c_simple/zip_container.c
@@ -58,7 +58,7 @@ static void load_next(void)
return;
}
- GP_Blit(image, 0, 0, image->w, image->h, backend->context, 0, 0);
+ GP_Blit_Clipped(image, 0, 0, image->w, image->h, backend->context, 0, 0);
GP_BackendFlip(backend);
}
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
}
/* Blit image into the window and show it */
- GP_Blit(image, 0, 0, image->w, image->h, backend->context, 0, 0);
+ GP_Blit_Clipped(image, 0, 0, image->w, image->h, backend->context, 0, 0);
GP_BackendFlip(backend);
/* Wait for events */
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
case GP_EV_SYS:
if (ev.code == GP_EV_SYS_RESIZE) {
GP_BackendResizeAck(backend);
- GP_Blit(image, 0, 0, image->w, image->h,
+ GP_Blit_Clipped(image, 0, 0, image->w, image->h,
backend->context, 0, 0);
GP_BackendFlip(backend);
}
http://repo.or.cz/w/gfxprim.git/commit/aefa0cab17b7f75cada9bc97678055313642…
commit aefa0cab17b7f75cada9bc97678055313642e1e6
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Dec 24 16:11:25 2014 +0100
Exif: Fix segfault on loading empty string.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Exif.c b/libs/loaders/GP_Exif.c
index b401fc97..f9365893 100644
--- a/libs/loaders/GP_Exif.c
+++ b/libs/loaders/GP_Exif.c
@@ -341,7 +341,7 @@ static int load_string(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
/* Short strings are stored in the value directly */
if (num_comp <= 4) {
memcpy(buf, val, num_comp);
- buf[num_comp - 1] = 0;
+ buf[num_comp > 0 ? num_comp - 1 : num_comp] = 0;
goto add;
}
@@ -351,9 +351,9 @@ static int load_string(GP_IO *io, GP_DataStorage *storage, GP_DataNode *node,
buf[max_len - 1] = '0';
+add:
GP_DEBUG(2, "ASCII String value = '%s'", buf);
-add:
return GP_DataStorageAddString(storage, node, id, buf) != NULL;
}
http://repo.or.cz/w/gfxprim.git/commit/9af41a3215a074981988fbcf5ed8c1f45739…
commit 9af41a3215a074981988fbcf5ed8c1f45739b9d4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Dec 24 13:42:08 2014 +0100
loaders: Add some metadata for JPG and PNM.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 386370fd..4921f246 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -207,6 +207,12 @@ static void read_jpg_metadata(struct jpeg_decompress_struct *cinfo,
{
jpeg_saved_marker_ptr marker;
+ GP_DataStorageAddInt(storage, NULL, "Width", cinfo->image_width);
+ GP_DataStorageAddInt(storage, NULL, "Height", cinfo->image_height);
+ GP_DataStorageAddInt(storage, NULL, "Channels", cinfo->num_components);
+ GP_DataStorageAddString(storage, NULL, "Color Space",
+ get_colorspace(cinfo->out_color_space));
+
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
switch (marker->marker) {
case JPEG_COM: {
diff --git a/libs/loaders/GP_PNM.c b/libs/loaders/GP_PNM.c
index 588d4300..a9003da1 100644
--- a/libs/loaders/GP_PNM.c
+++ b/libs/loaders/GP_PNM.c
@@ -700,6 +700,17 @@ err0:
return 1;
}
+static void fill_meta_data(struct pnm_header *header, GP_DataStorage *storage)
+{
+ if (!storage)
+ return;
+
+ GP_DataStorageAddInt(storage, NULL, "Width", header->w);
+ GP_DataStorageAddInt(storage, NULL, "Height", header->h);
+ GP_DataStorageAddInt(storage, NULL, "Depth", header->depth);
+ GP_DataStorageAddString(storage, NULL, "Format", pnm_magic_name(header->magic));
+}
+
int GP_ReadPBMEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
GP_ProgressCallback *callback)
{
@@ -707,14 +718,14 @@ int GP_ReadPBMEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
DECLARE_BUFFER(buf, io);
int err;
- (void) storage;
-
err = load_header(&buf, &header);
if (err) {
errno = err;
return 1;
}
+ fill_meta_data(&header, storage);
+
if (!img)
return 0;
@@ -864,14 +875,14 @@ int GP_ReadPGMEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
DECLARE_BUFFER(buf, io);
int err;
- (void) storage;
-
err = load_header(&buf, &header);
if (err) {
errno = err;
return 1;
}
+ fill_meta_data(&header, storage);
+
if (!img)
return 0;
@@ -990,14 +1001,14 @@ int GP_ReadPPMEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
DECLARE_BUFFER(buf, io);
int err;
- (void) storage;
-
err = load_header(&buf, &header);
if (err) {
errno = err;
return 1;
}
+ fill_meta_data(&header, storage);
+
if (!img)
return 0;
@@ -1116,14 +1127,14 @@ int GP_ReadPNMEx(GP_IO *io, GP_Context **img, GP_DataStorage *storage,
DECLARE_BUFFER(buf, io);
int err, ret = 1;
- (void) storage;
-
err = load_header(&buf, &header);
if (err) {
errno = err;
return 1;
}
+ fill_meta_data(&header, storage);
+
if (!img)
return 0;
-----------------------------------------------------------------------
Summary of changes:
build/syms/Filters_symbols.txt | 25 +---
build/syms/Loaders_symbols.txt | 11 +-
demos/bogoman/bogoman.c | 35 +++--
demos/bogoman/bogoman_loader.c | 51 +++++-
demos/bogoman/bogoman_map.c | 138 +++++++++++++--
demos/bogoman/bogoman_map.h | 57 +++++--
demos/bogoman/bogoman_render.c | 115 +++++++++++--
demos/bogoman/bogoman_render.h | 9 +-
demos/bogoman/levels/02-paticles.txt | 10 +
demos/bogoman/map.txt | 4 +-
demos/c_simple/Makefile | 3 +-
demos/c_simple/tmp_file.c | 110 ------------
demos/c_simple/zip_container.c | 6 +-
demos/grinder/histogram.c | 28 ++--
doc/pixels.txt | 8 +
include/core/GP_Pixel.h | 21 ++-
include/filters/GP_Filter.h | 2 -
include/filters/GP_FilterParam.h | 167 -----------------
include/filters/GP_Filters.h | 3 -
include/filters/GP_Stats.h | 41 +++--
include/loaders/GP_Container.h | 19 ++-
include/loaders/GP_Loaders.h | 2 -
include/loaders/GP_TmpFile.h | 58 ------
libs/filters/GP_FilterParam.c | 257 ---------------------------
libs/filters/{GP_Stats.c => GP_Histogram.c} | 90 +++++-----
libs/filters/GP_Histogram.gen.c.t | 73 ++++++--
libs/loaders/GP_BMP.c | 6 +
libs/loaders/GP_Container.c | 12 +-
libs/loaders/GP_Exif.c | 4 +-
libs/loaders/GP_JPG.c | 6 +
libs/loaders/GP_Loader.c | 23 ++-
libs/loaders/GP_PNM.c | 27 ++-
libs/loaders/GP_PSD.c | 6 +
libs/loaders/GP_PSP.c | 24 +++-
libs/loaders/GP_TmpFile.c | 183 -------------------
libs/loaders/GP_ZIP.c | 89 +++++-----
36 files changed, 669 insertions(+), 1054 deletions(-)
create mode 100644 demos/bogoman/levels/02-paticles.txt
delete mode 100644 demos/c_simple/tmp_file.c
delete mode 100644 include/filters/GP_FilterParam.h
delete mode 100644 include/loaders/GP_TmpFile.h
delete mode 100644 libs/filters/GP_FilterParam.c
rename libs/filters/{GP_Stats.c => GP_Histogram.c} (53%)
delete mode 100644 libs/loaders/GP_TmpFile.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
21 Dec '14
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via c410d038596cfd83b39c4729dcfaf0e99e3e48b0 (commit)
from 31c7add5cb754ad8250691d0875d4bd7b2cd6341 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/c410d038596cfd83b39c4729dcfaf0e99e3e…
commit c410d038596cfd83b39c4729dcfaf0e99e3e48b0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Dec 21 12:22:08 2014 +0100
core: Print C stack trace on warnings.
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/build/syms/Core_symbols.txt b/build/syms/Core_symbols.txt
index 4a452030..902dbdbd 100644
--- a/build/syms/Core_symbols.txt
+++ b/build/syms/Core_symbols.txt
@@ -78,3 +78,5 @@ SWIG_exception
GP_Gamma8_Linear10
GP_Linear10_Gamma8
+
+GP_DebugPrintCStack
diff --git a/libs/core/GP_Common.c b/libs/core/GP_Common.c
index 1d608ff1..d854cec0 100644
--- a/libs/core/GP_Common.c
+++ b/libs/core/GP_Common.c
@@ -41,7 +41,7 @@
#define GP_ABORT_INFO_TRACE_LEVELS 20
-static void print_c_stack(void)
+void GP_DebugPrintCStack(void)
{
#ifdef HAVE_BACKTRACE
#if GP_ABORT_INFO_TRACE_LEVELS > 0
@@ -86,5 +86,5 @@ void GP_PrintAbortInfo(const char *file, const char *func, unsigned int line,
fprintf(stderr, "n");
print_python_stack();
- print_c_stack();
+ GP_DebugPrintCStack();
}
diff --git a/libs/core/GP_Debug.c b/libs/core/GP_Debug.c
index c53ad513..011b6040 100644
--- a/libs/core/GP_Debug.c
+++ b/libs/core/GP_Debug.c
@@ -104,12 +104,15 @@ void GP_DebugPrint(int level, const char *file, const char *function, int line,
switch (level) {
case GP_DEBUG_FATAL:
+ GP_DebugPrintCStack();
fprintf(stderr, "*** FATAL: %s:%s():%u: ", file, function, line);
break;
case GP_DEBUG_BUG:
+ GP_DebugPrintCStack();
fprintf(stderr, "*** BUG: %s:%s():%u: ", file, function, line);
break;
case GP_DEBUG_WARN:
+ GP_DebugPrintCStack();
fprintf(stderr, "*** WARNING: %s:%s():%u: ", file, function, line);
break;
case GP_DEBUG_TODO:
-----------------------------------------------------------------------
Summary of changes:
build/syms/Core_symbols.txt | 2 ++
libs/core/GP_Common.c | 4 ++--
libs/core/GP_Debug.c | 3 +++
3 files changed, 7 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
18 Dec '14
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 31c7add5cb754ad8250691d0875d4bd7b2cd6341 (commit)
from c104daa309d30c1ffd78acb93d1f451f5224d59e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/31c7add5cb754ad8250691d0875d4bd7b2cd…
commit 31c7add5cb754ad8250691d0875d4bd7b2cd6341
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Dec 18 17:35:21 2014 +0100
loader: Two fixes.
* When GP_LoadImageEx() was introduced one of the return NULL was
changed to return 0 (should have been return 1).
* Do not try file signature based loader if the previous attempt
was aborted from callback
Signed-off-by: Cyril Hrubis <metan(a)ucw.cz>
diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c
index c7b13e23..8bc9caf1 100644
--- a/libs/loaders/GP_Loader.c
+++ b/libs/loaders/GP_Loader.c
@@ -379,14 +379,24 @@ int GP_LoadImageEx(const char *src_path,
return 0;
}
+ /*
+ * Operation was aborted, just here exit.
+ */
+ if (errno == ECANCELED)
+ return 1;
+
sig_load = loader_by_signature(src_path);
/*
* Avoid further work if extension matches the signature but image
* couldn't be loaded. Probably unimplemented format or damaged file.
*/
- if (ext_load == sig_load)
- return 0;
+ if (ext_load == sig_load) {
+ GP_WARN("Signature matches extension but file '%s' "
+ "can't be loaded. Unsupported/damaged file?",
+ src_path);
+ return 1;
+ }
if (ext_load && sig_load) {
GP_WARN("File '%s': Extension says %s but signature %s",
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_Loader.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0