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 4f9126b65e5597524ac218023ac7520e6219ad23 (commit) via 037b907e62d1a4427002d6a76f58eb5ee08a40b3 (commit) via f8d41db7b4077dd701a37cc0624011f5b62f9fbf (commit) via cbd1de31159606e98f46ac6d4ad281e15cc94344 (commit) via 8d627e19fbffb76c6e4a11c320018676da2eac4e (commit) via d75426b6d9542c45ea93f4ab5f918f71f7c286d0 (commit) via 0cfd38954aa140631a8faa6a72d6294a27c25f76 (commit) via d7ea6a77dc9ea5567ef84607cf98a36f6ed13c3b (commit) via abb8f83cb3e09d8206a071d4043be6c47dc077ea (commit) via 762943f4d1602fd118aa6efb380a956a03daf8d8 (commit) via 8e6577ea43f37eba91ebae68d8998d37a17edbe0 (commit) via 4e15e1706ca21c382ca73ea1de111e04bffc34e9 (commit) via aa053ead0e51edb99977b8a0aee8eb4488238473 (commit) via 043238394f939389538ed8666144c875428b65cc (commit) via d2aa0848db79445801a3ca718ced2204c7e4d783 (commit) via 53fcdc5357cb56708be84b483bf6facd0c380108 (commit) via 953585da5ceb2376fbb96db9965268a3566b26b4 (commit) via c696193212ee6fb4704cbb12c0d56d189647ccb8 (commit) via 6585778ebe915cccfe630d49782e6db6c0ac6c94 (commit) via c9ca2a9c99541ef2a206db9344c9feda39426db7 (commit) via 3275310a73bb7a599d6e1da9a4f6debf1e358635 (commit) via ba095a866ae6547879193c256d9c206585efbfe7 (commit) from 179ad0f8718479d653783f56c3128ef4cad8d880 (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/4f9126b65e5597524ac218023ac7520e6219a...
commit 4f9126b65e5597524ac218023ac7520e6219ad23 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 23:43:10 2012 +0200
doc: Add new example.
diff --git a/doc/examples.txt b/doc/examples.txt index a3eed9a..053b3c6 100644 --- a/doc/examples.txt +++ b/doc/examples.txt @@ -45,6 +45,14 @@ Example in C include::../demos/c_simple/filters_symmetry.c[] ------------------------------------------------------------------
+Example in Python +^^^^^^^^^^^^^^^^^ + +[source,python] +------------------------------------------------------------------ +include::../demos/py_simple/rotate90.py[] +------------------------------------------------------------------ + Simple backend example ----------------------
http://repo.or.cz/w/gfxprim.git/commit/037b907e62d1a4427002d6a76f58eb5ee08a4...
commit 037b907e62d1a4427002d6a76f58eb5ee08a40b3 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 23:40:45 2012 +0200
examples: Add pyton filter rotate example.
diff --git a/demos/py_simple/loaders_example.py b/demos/py_simple/loaders_example.py index 1bf9c2c..3cebc4d 100755 --- a/demos/py_simple/loaders_example.py +++ b/demos/py_simple/loaders_example.py @@ -3,7 +3,6 @@ import sys
import gfxprim.core as core import gfxprim.loaders as loaders -import gfxprim.filters as filters
def main(): if len(sys.argv) != 2: @@ -11,7 +10,7 @@ def main(): sys.exit(1)
# Load Image - img = loaders.LoadImage(sys.argv[2], None) + img = loaders.LoadImage(sys.argv[1], None) # Save result loaders.SavePNG("out.png", img, None)
diff --git a/demos/py_simple/rotate90.py b/demos/py_simple/rotate90.py new file mode 100755 index 0000000..d14022d --- /dev/null +++ b/demos/py_simple/rotate90.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +import sys + +import gfxprim.core as core +import gfxprim.loaders as loaders +import gfxprim.filters as filters + +def main(): + if len(sys.argv) != 3: + print("USAGE: %s imput_image output_image" % sys.argv[0]); + sys.exit(1) + + # Turns on debug messages + core.SetDebugLevel(10); + + # Load Image + src = loaders.LoadImage(sys.argv[1], None) + # Rotate by 90 degrees + res = filters.FilterRotate90Alloc(src, None) + # Save Image + loaders.SaveImage(res, sys.argv[2], None); + +if __name__ == '__main__': + main()
http://repo.or.cz/w/gfxprim.git/commit/f8d41db7b4077dd701a37cc0624011f5b62f9...
commit f8d41db7b4077dd701a37cc0624011f5b62f9fbf Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 23:29:59 2012 +0200
pywrap: filters: Mark allocating functions.
diff --git a/pylib/gfxprim/filters/filters.i b/pylib/gfxprim/filters/filters.i index 34baeb9..b617508 100644 --- a/pylib/gfxprim/filters/filters.i +++ b/pylib/gfxprim/filters/filters.i @@ -24,3 +24,11 @@ %include "GP_Linear.h" %include "GP_Resize.h" /* %include "GP_Dither.h" -- missing symbols */ + +/* Functions returning new allocated context */ +%newobject GP_FilterMirrorHAlloc; +%newobject GP_FilterMirrorVAlloc; +%newobject GP_FilterRotate90Alloc; +%newobject GP_FilterRotate180Alloc; +%newobject GP_FilterRotate270Alloc; +%newobject GP_FilterSymmetryAlloc;
http://repo.or.cz/w/gfxprim.git/commit/cbd1de31159606e98f46ac6d4ad281e15cc94...
commit cbd1de31159606e98f46ac6d4ad281e15cc94344 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 23:05:04 2012 +0200
filters: Finish rotate filters API change.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 01e8a06..7229781 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -227,13 +227,13 @@ static GP_RetCode rotate(GP_Context **c, const char *params)
switch (rot) { case 0: - res = GP_FilterRotate90(*c, NULL, progress_callback); + res = GP_FilterRotate90Alloc(*c, progress_callback); break; case 1: - res = GP_FilterRotate180(*c, NULL, progress_callback); + res = GP_FilterRotate180Alloc(*c, progress_callback); break; case 2: - res = GP_FilterRotate270(*c, NULL, progress_callback); + res = GP_FilterRotate270Alloc(*c, progress_callback); break; } @@ -262,10 +262,10 @@ static GP_RetCode mirror(GP_Context **c, const char *params) return GP_EINVAL;
if (vert) - GP_FilterMirrorV_Raw(*c, *c, progress_callback); + GP_FilterMirrorV(*c, *c, progress_callback); if (horiz) - GP_FilterMirrorH_Raw(*c, *c, progress_callback); + GP_FilterMirrorH(*c, *c, progress_callback);
return GP_ESUCCESS; } diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c index 18cfabc..ce97389 100644 --- a/demos/spiv/spiv.c +++ b/demos/spiv/spiv.c @@ -215,15 +215,15 @@ static void *image_loader(void *ptr) break; case 90: callback.priv = "Rotating image (90)"; - img = GP_FilterRotate90(ret, NULL, &callback); + img = GP_FilterRotate90Alloc(ret, &callback); break; case 180: callback.priv = "Rotating image (180)"; - img = GP_FilterRotate180(ret, NULL, &callback); + img = GP_FilterRotate180Alloc(ret, &callback); break; case 270: callback.priv = "Rotating image (270)"; - img = GP_FilterRotate270(ret, NULL, &callback); + img = GP_FilterRotate270Alloc(ret, &callback); break; }
diff --git a/include/filters/GP_Rotate.h b/include/filters/GP_Rotate.h index 26f878f..0957010 100644 --- a/include/filters/GP_Rotate.h +++ b/include/filters/GP_Rotate.h @@ -118,18 +118,25 @@ int GP_FilterRotate270_Raw(const GP_Context *src, GP_Context *dst, /* * Rotate the context by 90, 180, 270. * - * If dst is NULL, new bitmap is allocated. - * * Returns pointer to destination bitmap or NULL if allocation failed. */ -GP_Context *GP_FilterRotate90(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterRotate90(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterRotate90Alloc(const GP_Context *src, + GP_ProgressCallback *callback);
-GP_Context *GP_FilterRotate180(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterRotate180(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback);
-GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +GP_Context *GP_FilterRotate180Alloc(const GP_Context *src, + GP_ProgressCallback *callback); + +int GP_FilterRotate270(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +GP_Context *GP_FilterRotate270Alloc(const GP_Context *src, + GP_ProgressCallback *callback);
/* * Calls a symmetry filter on bitmap. @@ -165,4 +172,8 @@ GP_Context *GP_FilterSymmetryAlloc(const GP_Context *src, GP_FilterSymmetries symmetry, GP_ProgressCallback *callback);
+int GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, + GP_FilterSymmetries symmetry, + GP_ProgressCallback *callback); + #endif /* FILTERS_GP_ROTATE_H */ diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c index 5a7be3d..d758535 100644 --- a/libs/filters/GP_Rotate.c +++ b/libs/filters/GP_Rotate.c @@ -74,7 +74,7 @@ int GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, "The src and dst pixel types must match"); GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); + "Destination is not large enough");
if (GP_FilterMirrorH_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); @@ -108,7 +108,7 @@ int GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, GP_ASSERT(src->pixel_type == dst->pixel_type, "The src and dst pixel types must match"); GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); + "Destination is not large enough");
if (GP_FilterMirrorV_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); @@ -147,87 +147,105 @@ int GP_FilterRotate180_Raw(const GP_Context *src, GP_Context *dst, return 0; }
-GP_Context *GP_FilterRotate90(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate90(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_Context *res = dst; - - if (res == NULL) { - res = GP_ContextAlloc(src->h, src->w, src->pixel_type); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->h && src->h <= dst->w, - "Destination is not big enough"); - } + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + GP_ASSERT(src->w <= dst->h && src->h <= dst->w, + "Destination is not large enough");
- if (GP_FilterRotate90_Raw(src, res, callback)) { + if (GP_FilterRotate90_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); + return 1; + }
- if (dst == NULL) - GP_ContextFree(res); + return 0; +}
+GP_Context *GP_FilterRotate90Alloc(const GP_Context *src, + GP_ProgressCallback *callback) +{ + GP_Context *res; + + res = GP_ContextAlloc(src->h, src->w, src->pixel_type); + + if (res == NULL) + return NULL; + + if (GP_FilterRotate90_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + GP_ContextFree(res); return NULL; }
return res; }
-GP_Context *GP_FilterRotate180(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate180(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_Context *res = dst; - - if (res == NULL) { - res = GP_ContextCopy(src, 0); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); - } + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + GP_ASSERT(src->w <= dst->w && src->h <= dst->h, + "Destination is not large enough");
- if (GP_FilterRotate180_Raw(src, res, callback)) { + if (GP_FilterRotate180_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); + return 1; + }
- if (dst == NULL) - GP_ContextFree(res); + return 0; +}
+GP_Context *GP_FilterRotate180Alloc(const GP_Context *src, + GP_ProgressCallback *callback) +{ + GP_Context *res; + + res = GP_ContextCopy(src, 0); + + if (res == NULL) + return NULL; + + if (GP_FilterRotate180_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + GP_ContextFree(res); return NULL; }
return res; }
-GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterRotate270(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_Context *res = dst; - - if (res == NULL) { - res = GP_ContextAlloc(src->h, src->w, src->pixel_type); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->h && src->h <= dst->w, - "Destination is not big enough"); - } + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + GP_ASSERT(src->w <= dst->h && src->h <= dst->w, + "Destination is not large enough");
- if (GP_FilterRotate270_Raw(src, res, callback)) { + if (GP_FilterRotate270_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); + return 1; + }
- if (dst == NULL) - GP_ContextFree(res); + return 0; +}
+GP_Context *GP_FilterRotate270Alloc(const GP_Context *src, + GP_ProgressCallback *callback) +{ + GP_Context *res; + + res = GP_ContextAlloc(src->h, src->w, src->pixel_type); + + if (res == NULL) + return NULL; + + if (GP_FilterRotate270_Raw(src, res, callback)) { + GP_DEBUG(1, "Operation aborted"); + GP_ContextFree(res); return NULL; }
@@ -262,11 +280,11 @@ GP_Context *GP_FilterSymmetryAlloc(const GP_Context *src, { switch (symmetry) { case GP_ROTATE_90: - return GP_FilterRotate90(src, NULL, callback); + return GP_FilterRotate90Alloc(src, callback); case GP_ROTATE_180: - return GP_FilterRotate180(src, NULL, callback); + return GP_FilterRotate180Alloc(src, callback); case GP_ROTATE_270: - return GP_FilterRotate270(src, NULL, callback); + return GP_FilterRotate270Alloc(src, callback); case GP_MIRROR_H: return GP_FilterMirrorHAlloc(src, callback); case GP_MIRROR_V: @@ -276,3 +294,24 @@ GP_Context *GP_FilterSymmetryAlloc(const GP_Context *src, return NULL; } } + +int GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, + GP_FilterSymmetries symmetry, + GP_ProgressCallback *callback) +{ + switch (symmetry) { + case GP_ROTATE_90: + return GP_FilterRotate90(src, dst, callback); + case GP_ROTATE_180: + return GP_FilterRotate180(src, dst, callback); + case GP_ROTATE_270: + return GP_FilterRotate270(src, dst, callback); + case GP_MIRROR_H: + return GP_FilterMirrorH(src, dst, callback); + case GP_MIRROR_V: + return GP_FilterMirrorV(src, dst, callback); + default: + GP_DEBUG(1, "Invalid symmetry %i", (int) symmetry); + return 1; + } +}
http://repo.or.cz/w/gfxprim.git/commit/8d627e19fbffb76c6e4a11c320018676da2ea...
commit 8d627e19fbffb76c6e4a11c320018676da2eac4e Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:34:24 2012 +0200
doc: Add symmetry example to examples.
diff --git a/doc/examples.txt b/doc/examples.txt index 87b8f63..a3eed9a 100644 --- a/doc/examples.txt +++ b/doc/examples.txt @@ -31,6 +31,20 @@ Example in Python include::../demos/py_simple/loaders_example.py[] ------------------------------------------------------------------
+Filters +------- + +Symmetry filters (Rotation, Mirroring) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Example in C +^^^^^^^^^^^^ + +[source,c] +------------------------------------------------------------------ +include::../demos/c_simple/filters_symmetry.c[] +------------------------------------------------------------------ + Simple backend example ----------------------
http://repo.or.cz/w/gfxprim.git/commit/d75426b6d9542c45ea93f4ab5f918f71f7c28...
commit d75426b6d9542c45ea93f4ab5f918f71f7c286d0 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:31:42 2012 +0200
examples: Add filter symmetry C example.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile index 528152f..de507b3 100644 --- a/demos/c_simple/Makefile +++ b/demos/c_simple/Makefile @@ -5,7 +5,7 @@ CSOURCES=$(shell echo *.c) INCLUDE= LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
-APPS=backend_example loaders_example loaders filters_mirror +APPS=backend_example loaders_example loaders filters_symmetry
include $(TOPDIR)/pre.mk include $(TOPDIR)/app.mk diff --git a/demos/c_simple/filters_symmetry.c b/demos/c_simple/filters_symmetry.c new file mode 100644 index 0000000..3f130a4 --- /dev/null +++ b/demos/c_simple/filters_symmetry.c @@ -0,0 +1,116 @@ +/***************************************************************************** + * 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@ucw.cz * + * * + *****************************************************************************/ + + /* + + Symmetry filter example. + + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <getopt.h> + +#include <GP.h> + +static void usage_and_exit(int ret) +{ + int i; + printf("filter_symmetry [-d debug_level] -s {"); + + for (i = 0; GP_FilterSymmetryNames[i+1] != NULL; i++) + printf("%s, ", GP_FilterSymmetryNames[i]); + + printf("%s} image_in image_outn", GP_FilterSymmetryNames[i]); + + exit(ret); +} + +int main(int argc, char *argv[]) +{ + GP_Context *src, *res; + const char *symmetry = NULL; + int opt, sym, debug = 0; + + /* Parse program options */ + while ((opt = getopt(argc, argv, "d:hs:")) != -1) { + switch (opt) { + case 's': + symmetry = optarg; + break; + case 'h': + usage_and_exit(0); + break; + case 'd': + debug = atoi(optarg); + break; + default: + usage_and_exit(1); + } + } + + /* Turn on debug messages */ + GP_SetDebugLevel(debug); + + if (symmetry == NULL) { + printf("Symmetry not specifiedn"); + usage_and_exit(1); + } + + if (argc - optind != 2) { + printf("Input and output image not specifiedn"); + usage_and_exit(1); + } + + sym = GP_FilterSymmetryByName(symmetry); + + if (sym < 0) { + printf("Invalid symmetry name '%s'n", symmetry); + usage_and_exit(1); + } + + /* Load Image */ + src = GP_LoadImage(argv[optind], NULL); + + if (src == NULL) { + fprintf(stderr, "Failed to load image '%s': %sn", + argv[optind], strerror(errno)); + return 1; + } + + /* Apply a symmetry filter */ + res = GP_FilterSymmetryAlloc(src, sym, NULL); + + /* Save Image */ + if (GP_SaveImage(res, argv[optind+1], NULL)) { + fprintf(stderr, "Failed to save image '%s': %sn", + argv[optind+1], strerror(errno)); + return 1; + } + + /* Cleanup */ + GP_ContextFree(src); + GP_ContextFree(res); + + return 0; +}
http://repo.or.cz/w/gfxprim.git/commit/0cfd38954aa140631a8faa6a72d6294a27c25...
commit 0cfd38954aa140631a8faa6a72d6294a27c25f76 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:30:19 2012 +0200
filters: Starting to change filter API.
diff --git a/include/filters/GP_Rotate.h b/include/filters/GP_Rotate.h index 515d2b5..26f878f 100644 --- a/include/filters/GP_Rotate.h +++ b/include/filters/GP_Rotate.h @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
@@ -36,6 +36,8 @@ * Mirror horizontally. * * Works 'in place'. The contexts must have equal pixel_type and size. + * + * This is semi-internal function without any assertions on destination. */ int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback); @@ -43,17 +45,32 @@ int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, /* * Mirrors bitmap horizontally. * - * If dst is NULL, new bitmap is allocated. + * The dst must be at least as big as source. * - * Returns pointer to destination bitmap or NULL if allocation failed. + * The filter works 'in-place' which means that src and dst + * may be very same context. Note that when aborting in-place operation + * the image buffer gets into an inconsitent state. + * + * Retruns zero on success, non-zero if operation was aborted. + */ +int GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +/* + * Mirrors bitmap horizontally. + * + * Returns pointer to newly allocated context, or NULL if malloc() has failed + * or operation was aborted from withing a callback. */ -GP_Context *GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +GP_Context *GP_FilterMirrorHAlloc(const GP_Context *src, + GP_ProgressCallback *callback);
/* * Mirror vertically * * Works 'in place'. The contexts must have equal pixel_type and size. + * + * This is semi-internal function without any assertions on destination. */ int GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback); @@ -61,18 +78,33 @@ int GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst, /* * Mirrors bitmap vertically. * - * If dst is NULL, new bitmap is allocated. + * The dst must be at least as big as source. * - * Returns pointer to destination bitmap or NULL if allocation failed. + * The filter works 'in-place' which means that src and dst + * may be very same context. Note that when aborting in-place operation + * the image buffer gets into an inconsitent state. + * + * Retruns zero on success, non-zero if operation was aborted. */ -GP_Context *GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback); +int GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback); + +/* + * Mirrors bitmap vertically. + * + * Returns pointer to newly allocated context, or NULL if malloc() has failed + * or operation was aborted from withing a callback. + */ +GP_Context *GP_FilterMirrorVAlloc(const GP_Context *src, + GP_ProgressCallback *callback);
/* * Rotate context by 90, 180 and 270. * * Doesn't work 'in place'. The contexts must have equal pixel_type size must * match the rotated size (is equal for 180 and swapped for 90 and 270). + * + * These are semi-internal functions without any assertions on destination. */ int GP_FilterRotate90_Raw(const GP_Context *src, GP_Context *dst, GP_ProgressCallback *callback); @@ -107,7 +139,7 @@ GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, * Returns pointer to destination bitmap or NULL if allocation failed. */ typedef enum GP_FilterSymmetries { - GP_ROTATE_90, + GP_ROTATE_90 = 0, GP_ROTATE_CW = GP_ROTATE_90, GP_ROTATE_180, GP_ROTATE_270, @@ -116,8 +148,21 @@ typedef enum GP_FilterSymmetries { GP_MIRROR_V, } GP_FilterSymmetries;
-GP_Context *GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, - GP_FilterSymmetries symmetry, - GP_ProgressCallback *callback); +/* + * NULL-terminated array of symmetry names (C strings). + */ +extern const char **GP_FilterSymmetryNames; + +/* + * Symmetry by name (as defined in GP_FilerSymmetryNames). + * + * Returns either one of the GP_FilterSymmetries enums or -1 in case of + * failure. + */ +int GP_FilterSymmetryByName(const char *symmetry); + +GP_Context *GP_FilterSymmetryAlloc(const GP_Context *src, + GP_FilterSymmetries symmetry, + GP_ProgressCallback *callback);
#endif /* FILTERS_GP_ROTATE_H */ diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c index 1409e06..5a7be3d 100644 --- a/libs/filters/GP_Rotate.c +++ b/libs/filters/GP_Rotate.c @@ -67,62 +67,72 @@ int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst, return 0; }
-GP_Context *GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterMirrorH(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_Context *res = dst; + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + + GP_ASSERT(src->w <= dst->w && src->h <= dst->h, + "Destination is not big enough");
- if (res == NULL) { - res = GP_ContextCopy(src, 0); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); + if (GP_FilterMirrorH_Raw(src, dst, callback)) { + GP_DEBUG(1, "Operation aborted"); + return 1; }
- if (GP_FilterMirrorH_Raw(src, res, callback)) { - GP_DEBUG(1, "Operation aborted"); + return 0; +} + +GP_Context *GP_FilterMirrorHAlloc(const GP_Context *src, + GP_ProgressCallback *callback) +{ + GP_Context *res; + + res = GP_ContextCopy(src, 0); - if (dst == NULL) - GP_ContextFree(res); + if (res == NULL) + return NULL;
+ if (GP_FilterMirrorH_Raw(src, res, callback)) { + GP_ContextFree(res); return NULL; } - + return res; }
- -GP_Context *GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, - GP_ProgressCallback *callback) +int GP_FilterMirrorV(const GP_Context *src, GP_Context *dst, + GP_ProgressCallback *callback) { - GP_Context *res = dst; + GP_ASSERT(src->pixel_type == dst->pixel_type, + "The src and dst pixel types must match"); + GP_ASSERT(src->w <= dst->w && src->h <= dst->h, + "Destination is not big enough");
- if (res == NULL) { - res = GP_ContextCopy(src, 0); - - if (res == NULL) - return NULL; - } else { - GP_ASSERT(src->pixel_type == dst->pixel_type, - "The src and dst pixel types must match"); - GP_ASSERT(src->w <= dst->w && src->h <= dst->h, - "Destination is not big enough"); - } - if (GP_FilterMirrorV_Raw(src, dst, callback)) { GP_DEBUG(1, "Operation aborted"); + return 1; + } + + return 0; +} + +GP_Context *GP_FilterMirrorVAlloc(const GP_Context *src, + GP_ProgressCallback *callback) +{ + GP_Context *res; + + res = GP_ContextCopy(src, 0); - if (dst == NULL) - GP_ContextFree(res); + if (res == NULL) + return NULL;
+ if (GP_FilterMirrorV_Raw(src, res, callback)) { + GP_ContextFree(res); return NULL; } - + return res; }
@@ -224,24 +234,45 @@ GP_Context *GP_FilterRotate270(const GP_Context *src, GP_Context *dst, return res; }
-GP_Context *GP_FilterSymmetry(const GP_Context *src, GP_Context *dst, - GP_FilterSymmetries symmetry, - GP_ProgressCallback *callback) +static const char *symmetry_names[] = { + "90", + "180", + "270", + "H", + "V", + NULL, +}; + +const char **GP_FilterSymmetryNames = symmetry_names; + +int GP_FilterSymmetryByName(const char *symmetry) +{ + int i; + + for (i = 0; symmetry_names[i] != NULL; i++) + if (!strcasecmp(symmetry, symmetry_names[i])) + return i; + + return -1; +} + +GP_Context *GP_FilterSymmetryAlloc(const GP_Context *src, + GP_FilterSymmetries symmetry, + GP_ProgressCallback *callback) { switch (symmetry) { case GP_ROTATE_90: - return GP_FilterRotate90(src, dst, callback); + return GP_FilterRotate90(src, NULL, callback); case GP_ROTATE_180: - return GP_FilterRotate180(src, dst, callback); + return GP_FilterRotate180(src, NULL, callback); case GP_ROTATE_270: - return GP_FilterRotate270(src, dst, callback); + return GP_FilterRotate270(src, NULL, callback); case GP_MIRROR_H: - return GP_FilterMirrorH(src, dst, callback); + return GP_FilterMirrorHAlloc(src, callback); case GP_MIRROR_V: - return GP_FilterMirrorV(src, dst, callback); + return GP_FilterMirrorVAlloc(src, callback); + default: + GP_DEBUG(1, "Invalid symmetry %i", (int) symmetry); + return NULL; } - - GP_DEBUG(1, "Invalid symmetry %i", (int) symmetry); - - return NULL; }
http://repo.or.cz/w/gfxprim.git/commit/d7ea6a77dc9ea5567ef84607cf98a36f6ed13...
commit d7ea6a77dc9ea5567ef84607cf98a36f6ed13c3b Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:26:15 2012 +0200
loaders: Add debug message when saving JPG/PNG image.
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c index 51e20fc..54507b1 100644 --- a/libs/loaders/GP_JPG.c +++ b/libs/loaders/GP_JPG.c @@ -209,6 +209,8 @@ int GP_SaveJPG(const GP_Context *src, const char *dst_path, struct my_jpg_err my_err; int err;
+ GP_DEBUG(1, "Saving JPG Image '%s'", dst_path); + if (src->pixel_type != GP_PIXEL_RGB888 && src->pixel_type != GP_PIXEL_G8) { GP_DEBUG(1, "Can't save png with pixel type %s", diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c index 33f18fc..381039c 100644 --- a/libs/loaders/GP_PNG.c +++ b/libs/loaders/GP_PNG.c @@ -243,6 +243,8 @@ int GP_SavePNG(const GP_Context *src, const char *dst_path, png_infop png_info = NULL; int err;
+ GP_DEBUG(1, "Saving PNG Image '%s'", dst_path); + if (src->pixel_type != GP_PIXEL_RGB888) { GP_DEBUG(1, "Can't save png with pixel type %s", GP_PixelTypeName(src->pixel_type));
http://repo.or.cz/w/gfxprim.git/commit/abb8f83cb3e09d8206a071d4043be6c47dc07...
commit abb8f83cb3e09d8206a071d4043be6c47dc077ea Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:24:09 2012 +0200
doc: Update loaders docs.
* Fix GP_SaveXXX() functions
* Add GP_SaveImage()
diff --git a/doc/loaders.txt b/doc/loaders.txt index 472a735..72aae8c 100644 --- a/doc/loaders.txt +++ b/doc/loaders.txt @@ -29,6 +29,24 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback); Loads image from a file. The format is now matched by an image file extension. File sinature loading method is on the TODO.
+[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_Loaders.h> +/* or */ +#include <GP.h> + +int GP_SaveImage(GP_Context *src, const char *dst_path, + GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Saves a context into a file. The file format is matched accordingly to the +file extension, if extension is invalid or if support for request image format +wasn't compiled in, non-zero is returned and 'errno' is set to 'ENOSYS'. + +Returns zero on succes and non-zero on failure and 'errno' is set. The +possible errno values are 'ENOSYS' for unknown format and anything that could +be returned by 'fopen()', 'open()', 'fwrite()', 'write()', 'seek()', etc... + PNG ~~~ The 'PNG' loading support is optionaly implemented by libpng. @@ -85,7 +103,7 @@ signature. Basically this combines both of the calls above. /* or */ #include <GP.h>
-int GP_SavePNG(const char *dst_path, const GP_Context *src, +int GP_SavePNG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback); -------------------------------------------------------------------------------
@@ -152,7 +170,7 @@ signature. Basically this combines both of the calls above. /* or */ #include <GP.h>
-int GP_SaveJPG(const char *dst_path, const GP_Context *src, +int GP_SaveJPG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback); -------------------------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/762943f4d1602fd118aa6efb380a956a03daf...
commit 762943f4d1602fd118aa6efb380a956a03daf8d8 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:23:04 2012 +0200
loaders: Change parameters of GP_SaveXXX() functions.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile index c6a4e24..528152f 100644 --- a/demos/c_simple/Makefile +++ b/demos/c_simple/Makefile @@ -5,7 +5,7 @@ CSOURCES=$(shell echo *.c) INCLUDE= LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
-APPS=backend_example loaders_example loaders +APPS=backend_example loaders_example loaders filters_mirror
include $(TOPDIR)/pre.mk include $(TOPDIR)/app.mk diff --git a/demos/c_simple/loaders.c b/demos/c_simple/loaders.c index 8bd9b0e..1446d52 100644 --- a/demos/c_simple/loaders.c +++ b/demos/c_simple/loaders.c @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) priv.op = "Saving"; priv.name = "out.png";
- if (GP_SavePNG("out.png", img, &callback)) { + if (GP_SavePNG(img, "out.png", &callback)) { fprintf(stderr, "Failed to save image %s", strerror(errno)); return 1; } diff --git a/demos/c_simple/loaders_example.c b/demos/c_simple/loaders_example.c index b05c0b5..ab0b5b4 100644 --- a/demos/c_simple/loaders_example.c +++ b/demos/c_simple/loaders_example.c @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) return 1; }
- if (GP_SavePNG("out.png", img, NULL)) { + if (GP_SavePNG(img, "out.png", NULL)) { fprintf(stderr, "Failed to save image %s", strerror(errno)); return 1; } diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index be3bf09..01e8a06 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -477,7 +477,7 @@ static GP_RetCode save_jpg(GP_Context **c, const char *params) return GP_EINVAL; }
- GP_SaveJPG(file, *c, progress_callback); + GP_SaveJPG(*c, file, progress_callback);
return GP_ESUCCESS; } @@ -501,7 +501,7 @@ static GP_RetCode save_png(GP_Context **c, const char *params) return GP_EINVAL; }
- GP_SavePNG(file, *c, progress_callback); + GP_SavePNG(*c, file, progress_callback);
return GP_ESUCCESS; } @@ -836,9 +836,9 @@ static void save_by_fmt(struct GP_Context *bitmap, const char *name, const char if (!strcmp(fmt, "ppm")) ret = GP_SavePPM(name, bitmap, "b"); else if (!strcmp(fmt, "jpg")) - ret = GP_SaveJPG(name, bitmap, progress_callback); + ret = GP_SaveJPG(bitmap, name, progress_callback); else if (!strcmp(fmt, "png")) - ret = GP_SavePNG(name, bitmap, progress_callback); + ret = GP_SavePNG(bitmap, name, progress_callback); if (ret) { fprintf(stderr, "Failed to save bitmap: %sn", GP_RetCodeName(ret)); diff --git a/demos/grinder/histogram.c b/demos/grinder/histogram.c index 24fc9a7..ab6929a 100644 --- a/demos/grinder/histogram.c +++ b/demos/grinder/histogram.c @@ -74,7 +74,7 @@ void histogram_to_png(const GP_Context *src, const char *filename) } }
- GP_SavePNG(filename, res, NULL); + GP_SavePNG(res, filename, NULL);
GP_ContextFree(res); GP_FilterHistogramFree(params); diff --git a/demos/ttf2img/ttf2img.c b/demos/ttf2img/ttf2img.c index 0dea1fe..d027139 100644 --- a/demos/ttf2img/ttf2img.c +++ b/demos/ttf2img/ttf2img.c @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) GP_Text(context, &style, img_w/2, img_h/2, GP_ALIGN_CENTER|GP_VALIGN_CENTER, black_pixel, white_pixel, string);
- GP_SavePNG(img_path, context, NULL); + GP_SavePNG(context, img_path, NULL); GP_ContextFree(context);
diff --git a/include/loaders/GP_JPG.h b/include/loaders/GP_JPG.h index 32dd5ca..7cbbd36 100644 --- a/include/loaders/GP_JPG.h +++ b/include/loaders/GP_JPG.h @@ -51,7 +51,7 @@ GP_Context *GP_LoadJPG(const char *src_path, GP_ProgressCallback *callback); /* * Saves JPG to a file. */ -int GP_SaveJPG(const char *dst_path, const GP_Context *src, +int GP_SaveJPG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback);
#endif /* LOADERS_GP_JPG_H */ diff --git a/include/loaders/GP_PNG.h b/include/loaders/GP_PNG.h index 937baf5..b866b7d 100644 --- a/include/loaders/GP_PNG.h +++ b/include/loaders/GP_PNG.h @@ -68,7 +68,7 @@ GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback); * Saves PNG to a file. Zero is returned on succes. Upon failure non-zero is * returned and errno is filled accordingly. */ -int GP_SavePNG(const char *dst_path, const GP_Context *src, +int GP_SavePNG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback);
#endif /* LOADERS_GP_PNG_H */ diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c index 950ca11..51e20fc 100644 --- a/libs/loaders/GP_JPG.c +++ b/libs/loaders/GP_JPG.c @@ -201,7 +201,7 @@ GP_Context *GP_LoadJPG(const char *src_path, GP_ProgressCallback *callback) return GP_ReadJPG(f, callback); }
-int GP_SaveJPG(const char *dst_path, const GP_Context *src, +int GP_SaveJPG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback) { FILE *f; @@ -320,8 +320,8 @@ GP_Context *GP_LoadJPG(const char GP_UNUSED(*src_path), return NULL; }
-int GP_SaveJPG(const char GP_UNUSED(*dst_path), - const GP_Context GP_UNUSED(*src), +int GP_SaveJPG(const GP_Context GP_UNUSED(*src), + const char GP_UNUSED(*dst_path), GP_ProgressCallback GP_UNUSED(*callback)) { errno = ENOSYS; diff --git a/libs/loaders/GP_Loaders.c b/libs/loaders/GP_Loaders.c index f3754a1..a6349bc 100644 --- a/libs/loaders/GP_Loaders.c +++ b/libs/loaders/GP_Loaders.c @@ -169,13 +169,13 @@ int GP_SaveImage(const GP_Context *src, const char *dst_path, case 'N': if (dst_path[len - 3] == 'p' || dst_path[len - 3] == 'P') - return GP_SavePNG(dst_path, src, callback); + return GP_SavePNG(src, dst_path, callback); break; case 'p': case 'P': if (dst_path[len - 3] == 'j' || dst_path[len - 3] == 'J') - return GP_SaveJPG(dst_path, src, callback); + return GP_SaveJPG(src, dst_path, callback); break; case 'e': case 'E': @@ -183,7 +183,7 @@ int GP_SaveImage(const GP_Context *src, const char *dst_path, dst_path[len - 3] == 'P') && (dst_path[len - 4] == 'j' || dst_path[len - 4] == 'J')) - return GP_SaveJPG(dst_path, src, callback); + return GP_SaveJPG(src, dst_path, callback); break; } break; diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c index dc1b60b..33f18fc 100644 --- a/libs/loaders/GP_PNG.c +++ b/libs/loaders/GP_PNG.c @@ -235,7 +235,7 @@ GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback) return GP_ReadPNG(f, callback); }
-int GP_SavePNG(const char *dst_path, const GP_Context *src, +int GP_SavePNG(const GP_Context *src, const char *dst_path, GP_ProgressCallback *callback) { FILE *f; @@ -351,8 +351,8 @@ GP_Context *GP_LoadPNG(const char GP_UNUSED(*src_path), return NULL; }
-int GP_SavePNG(const char GP_UNUSED(*dst_path), - const GP_Context GP_UNUSED(*src), +int GP_SavePNG(const GP_Context GP_UNUSED(*src), + const char GP_UNUSED(*dst_path), GP_ProgressCallback GP_UNUSED(*callback)) { errno = ENOSYS;
http://repo.or.cz/w/gfxprim.git/commit/8e6577ea43f37eba91ebae68d8998d37a17ed...
commit 8e6577ea43f37eba91ebae68d8998d37a17edbe0 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:07:51 2012 +0200
loaders: GP_ImageLoad(): Set ENOSYS on unknowns image format.
diff --git a/libs/loaders/GP_Loaders.c b/libs/loaders/GP_Loaders.c index 1a61902..f3754a1 100644 --- a/libs/loaders/GP_Loaders.c +++ b/libs/loaders/GP_Loaders.c @@ -65,13 +65,13 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) case 'N': if (src_path[len - 3] == 'p' || src_path[len - 3] == 'P') - res = GP_LoadPNG(src_path, callback); + return GP_LoadPNG(src_path, callback); break; case 'p': case 'P': if (src_path[len - 3] == 'j' || src_path[len - 3] == 'J') - res = GP_LoadJPG(src_path, callback); + return GP_LoadJPG(src_path, callback); break; case 'e': case 'E': @@ -79,7 +79,7 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) src_path[len - 3] == 'P') && (src_path[len - 4] == 'j' || src_path[len - 4] == 'J')) - res = GP_LoadJPG(src_path, callback); + return GP_LoadJPG(src_path, callback); break; } break; @@ -89,21 +89,29 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) switch (src_path[len - 2]) { case 'b': case 'B': + //TODO: Fix this!!! if (src_path[len - 3] == 'p' || - src_path[len - 3] == 'P') + src_path[len - 3] == 'P') { GP_LoadPBM(src_path, &res); + return res; + } break; case 'g': case 'G': + //TODO: Fix this!!! if (src_path[len - 3] == 'p' || - src_path[len - 3] == 'P') + src_path[len - 3] == 'P') { GP_LoadPGM(src_path, &res); + return res; + } break; case 'p': case 'P': if (src_path[len - 3] == 'p' || - src_path[len - 3] == 'P') + src_path[len - 3] == 'P') { GP_LoadPPM(src_path, &res); + return res; + } break; } break; @@ -115,7 +123,7 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) case 'm': if (src_path[len - 3] == 'B' || src_path[len - 3] == 'b') - res = GP_LoadBMP(src_path, callback); + return GP_LoadBMP(src_path, callback); break; } break; @@ -127,7 +135,7 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) case 'i': if (src_path[len - 3] == 'G' || src_path[len - 3] == 'g') - res = GP_LoadGIF(src_path, callback); + return GP_LoadGIF(src_path, callback); break; } break; @@ -136,7 +144,8 @@ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback) skip_filename_check:
//TODO file signature based check - return res; + errno = ENOSYS; + return NULL; }
int GP_SaveImage(const GP_Context *src, const char *dst_path,
http://repo.or.cz/w/gfxprim.git/commit/4e15e1706ca21c382ca73ea1de111e04bffc3...
commit 4e15e1706ca21c382ca73ea1de111e04bffc34e9 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 20:04:04 2012 +0200
loaders: Add GP_ImageSave() function.
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h index 2b7d0d0..38633c7 100644 --- a/include/loaders/GP_Loaders.h +++ b/include/loaders/GP_Loaders.h @@ -51,4 +51,21 @@ */ GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback);
+/* + * Simple saving function, the image format is matched by file extension. + * + * Retruns zero on succes. + * + * On failure non-zero is returned. + * + * When file type wasn't recognized by extension or if support for requested + * image format wasn't compiled in non-zero is returned and errno is set to + * ENOSYS. + * + * The resulting errno may also be set to any possible error from fopen(3), open(3), + * write(3), fwrite(3), seek(3), etc.. + */ +int GP_SaveImage(const GP_Context *src, const char *dst_path, + GP_ProgressCallback *callback); + #endif /* LOADERS_GP_LOADERS_H */ diff --git a/libs/loaders/GP_Loaders.c b/libs/loaders/GP_Loaders.c index 6cb39e2..1a61902 100644 --- a/libs/loaders/GP_Loaders.c +++ b/libs/loaders/GP_Loaders.c @@ -16,13 +16,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2012 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- General functions for loading bitmaps. + General functions for loading and saving bitmaps.
*/
@@ -138,3 +138,48 @@ skip_filename_check: //TODO file signature based check return res; } + +int GP_SaveImage(const GP_Context *src, const char *dst_path, + GP_ProgressCallback *callback) +{ + int len; + + len = strlen(dst_path); + + if (len < 3) { + errno = ENOSYS; + return 1; + } + + switch (dst_path[len - 1]) { + /* PNG, JPG, JPEG */ + case 'g': + case 'G': + switch (dst_path[len - 2]) { + case 'n': + case 'N': + if (dst_path[len - 3] == 'p' || + dst_path[len - 3] == 'P') + return GP_SavePNG(dst_path, src, callback); + break; + case 'p': + case 'P': + if (dst_path[len - 3] == 'j' || + dst_path[len - 3] == 'J') + return GP_SaveJPG(dst_path, src, callback); + break; + case 'e': + case 'E': + if ((dst_path[len - 3] == 'p' || + dst_path[len - 3] == 'P') && + (dst_path[len - 4] == 'j' || + dst_path[len - 4] == 'J')) + return GP_SaveJPG(dst_path, src, callback); + break; + } + break; + } + + errno = ENOSYS; + return 1; +}
http://repo.or.cz/w/gfxprim.git/commit/aa053ead0e51edb99977b8a0aee8eb4488238...
commit aa053ead0e51edb99977b8a0aee8eb4488238473 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 19:38:00 2012 +0200
examples: Add runtest.sh script.
diff --git a/demos/c_simple/runtest.sh b/demos/c_simple/runtest.sh new file mode 100755 index 0000000..0794707 --- /dev/null +++ b/demos/c_simple/runtest.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# +# Run dynamically linked test. +# + +PROG="$1" +shift + +LD_LIBRARY_PATH=../../build/ ./$PROG "$@"
http://repo.or.cz/w/gfxprim.git/commit/043238394f939389538ed8666144c875428b6...
commit 043238394f939389538ed8666144c875428b65cc Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 18:37:58 2012 +0200
doc: Add new example, fix paths.
diff --git a/doc/Makefile b/doc/Makefile index 4bb74ee..d709a78 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,7 +4,7 @@ api.html: general.txt api.txt context.txt loaders.txt filters.txt basic_types.txt drawing_api.txt asciidoc -a toc api.txt
-examples.html: examples.txt ../demos/simple/*.c ../demos/py_simple/*.py +examples.html: examples.txt ../demos/c_simple/*.c ../demos/py_simple/*.py asciidoc -a toc examples.txt
api.pdf: api.txt diff --git a/doc/examples.txt b/doc/examples.txt index c4566f2..87b8f63 100644 --- a/doc/examples.txt +++ b/doc/examples.txt @@ -1,31 +1,50 @@ -Simple backend example +GFXprim Code Examples +===================== +Cyril Hrubis metan@ucw.cz + +Image loaders examples ----------------------
-Basic backend code example. Initalizes backends, draws a cross and dumps -events. +Loads an image and saves it into 'out.png' png image. + +Example in C +~~~~~~~~~~~~
[source,c] ------------------------------------------------------------------ -include::../demos/simple/backend_example.c[] +include::../demos/c_simple/loaders_example.c[] ------------------------------------------------------------------
-Simple loaders example ----------------------- - -Loads an image and saves it into 'out.png' png image. +Example in C utilizing progress callback +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[source,c] ------------------------------------------------------------------ -include::../demos/simple/loaders_example.c[] +include::../demos/c_simple/loaders.c[] ------------------------------------------------------------------
-And the same in python +Example in Python +~~~~~~~~~~~~~~~~~
[source,python] ------------------------------------------------------------------ include::../demos/py_simple/loaders_example.py[] ------------------------------------------------------------------
+Simple backend example +---------------------- + +Basic backend code example. Initalizes backends, draws a cross and dumps +events. + +Example in C +~~~~~~~~~~~~ + +[source,c] +------------------------------------------------------------------ +include::../demos/c_simple/backend_example.c[] +------------------------------------------------------------------ + GFXprim + PyGTK ---------------
http://repo.or.cz/w/gfxprim.git/commit/d2aa0848db79445801a3ca718ced2204c7e4d...
commit d2aa0848db79445801a3ca718ced2204c7e4d783 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 18:31:06 2012 +0200
examples: Add loaders example utilizing progress callback.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile index 7fd7505..c6a4e24 100644 --- a/demos/c_simple/Makefile +++ b/demos/c_simple/Makefile @@ -5,7 +5,7 @@ CSOURCES=$(shell echo *.c) INCLUDE= LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
-APPS=backend_example loaders_example +APPS=backend_example loaders_example loaders
include $(TOPDIR)/pre.mk include $(TOPDIR)/app.mk diff --git a/demos/c_simple/loaders.c b/demos/c_simple/loaders.c new file mode 100644 index 0000000..8bd9b0e --- /dev/null +++ b/demos/c_simple/loaders.c @@ -0,0 +1,91 @@ +/***************************************************************************** + * 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@ucw.cz * + * * + *****************************************************************************/ + + /* + + Simple loaders example utilizing progress callback. + + */ + +#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); + + /* + * It's important to return zero as non-zero return value + * aborts the operation. + */ + 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 0; + } + + 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 = "out.png"; + + if (GP_SavePNG("out.png", img, &callback)) { + fprintf(stderr, "Failed to save image %s", strerror(errno)); + return 1; + } + + printf("n"); + + return 0; +}
http://repo.or.cz/w/gfxprim.git/commit/53fcdc5357cb56708be84b483bf6facd0c380...
commit 53fcdc5357cb56708be84b483bf6facd0c380108 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 18:14:00 2012 +0200
examples: Move simple c examples into c_simple directory.
diff --git a/demos/Makefile b/demos/Makefile index 6cbebf6..ec4885b 100644 --- a/demos/Makefile +++ b/demos/Makefile @@ -1,3 +1,3 @@ TOPDIR=.. -SUBDIRS=grinder spiv particle ttf2img simple +SUBDIRS=grinder spiv particle ttf2img c_simple include $(TOPDIR)/post.mk diff --git a/demos/simple/Makefile b/demos/c_simple/Makefile similarity index 100% rename from demos/simple/Makefile rename to demos/c_simple/Makefile diff --git a/demos/simple/backend_example.c b/demos/c_simple/backend_example.c similarity index 100% rename from demos/simple/backend_example.c rename to demos/c_simple/backend_example.c diff --git a/demos/simple/loaders_example.c b/demos/c_simple/loaders_example.c similarity index 100% rename from demos/simple/loaders_example.c rename to demos/c_simple/loaders_example.c
http://repo.or.cz/w/gfxprim.git/commit/953585da5ceb2376fbb96db9965268a3566b2...
commit 953585da5ceb2376fbb96db9965268a3566b26b4 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 18:03:23 2012 +0200
Remove unused file.
diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 240f484..0000000 --- a/LICENSE +++ /dev/null @@ -1,24 +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@gmail.com * - * * - * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * - * * - *****************************************************************************/
http://repo.or.cz/w/gfxprim.git/commit/c696193212ee6fb4704cbb12c0d56d189647c...
commit c696193212ee6fb4704cbb12c0d56d189647ccb8 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 18:02:32 2012 +0200
Remove finished tasks from TODO.
diff --git a/TODO b/TODO index ac6d898..04e7bdc 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,9 @@ What's not implemented (and should be) --------------------------------------
-* bitmaps and blitting - - blit bitmaps (should respect rotation and pixel formats) - * IN PROGRESS - - loading bitmaps from image files (jpg, png, bmp, pnm ...) - * IN NEARLY FINISHED - -* backends - - finish framebuffer backend (SDL does not work on most of my framebuffers) - - other than SDL X backend (SDL does support only one window) - - some overall initialization routines - - backed event handling - * Meditate about bit endians and why these aren't separate pixel types (which would make our lives a bit easier)
- Advanced features -----------------
@@ -26,5 +13,3 @@ Advanced features * gfx primitives - drawing with alpha channel - anti aliasing - -* freetype support
http://repo.or.cz/w/gfxprim.git/commit/6585778ebe915cccfe630d49782e6db6c0ac6...
commit 6585778ebe915cccfe630d49782e6db6c0ac6c94 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 17:59:18 2012 +0200
input: Do not include internal headers in GP_Input.h
This fixes SDL-less and Xlib less build.
diff --git a/include/input/GP_Input.h b/include/input/GP_Input.h index 07724ae..80ebe2b 100644 --- a/include/input/GP_Input.h +++ b/include/input/GP_Input.h @@ -28,10 +28,4 @@ */ #include "input/GP_Event.h"
-/* - * Input drivers (semi internal). - */ -#include "input/GP_InputDriverSDL.h" -#include "input/GP_InputDriverLinux.h" - #endif /* INPUT_GP_INPUT_H */
http://repo.or.cz/w/gfxprim.git/commit/c9ca2a9c99541ef2a206db9344c9feda39426...
commit c9ca2a9c99541ef2a206db9344c9feda39426db7 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 17:56:04 2012 +0200
build: gfxprim-config: print error on invalid option.
diff --git a/configure b/configure index 3e05d42..bd08e4b 100755 --- a/configure +++ b/configure @@ -214,7 +214,8 @@ def write_gfxprim_config(cfg, libs): ldflags += '-lGP_backends ' ldflags += libs.get_linker_flags(i) f.write('t--libs-%s) echo -n "%s ";;n' % (i, ldflags)) - + + f.write('t*) echo "Invalid option '$1'"; echo $USAGE; exit 1;;n')
f.write('tesacntshiftndonenechon') f.close()
http://repo.or.cz/w/gfxprim.git/commit/3275310a73bb7a599d6e1da9a4f6debf1e358...
commit 3275310a73bb7a599d6e1da9a4f6debf1e358635 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 17:52:16 2012 +0200
buid: Use list rather than dict in list of modules.
diff --git a/configure b/configure index dee4a4f..3e05d42 100755 --- a/configure +++ b/configure @@ -233,26 +233,26 @@ if __name__ == '__main__': # # Library detection/enable disable # - # name, description, [detection], cflags, ldflags, dict of modules library is needed for + # name, description, [detection], cflags, ldflags, list of modules library is needed for # l = libraries([["libpng", "Portable Network Graphics Library", - [header_exists, "png.h"], "", "-lpng", {"loaders"}], + [header_exists, "png.h"], "", "-lpng", ["loaders"]], ["libsdl", "Simple Direct Media Layer", - [header_exists, "SDL/SDL.h"], "", "`sdl-config --libs`", {"backends"}], + [header_exists, "SDL/SDL.h"], "", "`sdl-config --libs`", ["backends"]], ["jpeg", "Library to load, handle and manipulate images in the JPEG format", - [header_exists, "jpeglib.h"], "", "-ljpeg", {"loaders"}], + [header_exists, "jpeglib.h"], "", "-ljpeg", ["loaders"]], ["giflib", "Library to handle, display and manipulate GIF images", - [header_exists, "gif_lib.h"], "", "-lgif", {"loaders"}], + [header_exists, "gif_lib.h"], "", "-lgif", ["loaders"]], ["libX11", "X11 library", - [header_exists, "X11/Xlib.h"], "", "-lX11", {"backends"}], + [header_exists, "X11/Xlib.h"], "", "-lX11", ["backends"]], ["freetype", "A high-quality and portable font engine", - [header_exists, "ft2build.h"], "", "`freetype-config --libs`", {"core"}]], cfg) + [header_exists, "ft2build.h"], "", "`freetype-config --libs`", ["core"]]], cfg)
parser = OptionParser();
http://repo.or.cz/w/gfxprim.git/commit/ba095a866ae6547879193c256d9c206585efb...
commit ba095a866ae6547879193c256d9c206585efbfe7 Author: Cyril Hrubis metan@ucw.cz Date: Fri May 11 17:48:14 2012 +0200
build: Make configure die verbosely on missing compilers.
diff --git a/configure b/configure index aa1d268..dee4a4f 100755 --- a/configure +++ b/configure @@ -142,13 +142,26 @@ class libraries: res += " " + i[4] return res
+def die_screaming(msg): + sys.stderr.write("n************************************n") + sys.stderr.write("ERROR: ") + sys.stderr.write(msg) + sys.stderr.write("n************************************n") + exit(1) + +# +# Check for basic compiling tools +# def basic_checks(cfg): sys.stderr.write("Basic checksn") sys.stderr.write("------------n") + if not c_compiler_exists(cfg): - exit(1) + die_screaming("No C compiler found") + if not python_module_installed(cfg, 'jinja2'): - exit(1) + die_screaming("No jinja2 python module found") + check_for_swig(cfg) sys.stderr.write("n")
@@ -194,7 +207,6 @@ def write_gfxprim_config(cfg, libs): f.write('t--cflags) echo -n "-I/usr/include/GP/ ";;n') f.write('t--libs) echo -n "-lGP %s ";;n' % libs.get_linker_flags('core'))
- # ldflags for specific modules for i in modules: ldflags = ''
-----------------------------------------------------------------------
Summary of changes: LICENSE | 24 -- TODO | 15 -- configure | 35 ++- demos/Makefile | 2 +- demos/{simple => c_simple}/Makefile | 2 +- demos/{simple => c_simple}/backend_example.c | 0 .../filters_symmetry.c} | 81 +++++- .../loaders_example.c => c_simple/loaders.c} | 42 +++- demos/{simple => c_simple}/loaders_example.c | 2 +- demos/{particle => c_simple}/runtest.sh | 0 demos/grinder/grinder.c | 18 +- demos/grinder/histogram.c | 2 +- demos/py_simple/loaders_example.py | 3 +- demos/py_simple/rotate90.py | 24 ++ demos/spiv/spiv.c | 6 +- demos/ttf2img/ttf2img.c | 2 +- doc/Makefile | 2 +- doc/examples.txt | 61 ++++- doc/loaders.txt | 22 ++- include/filters/GP_Rotate.h | 98 ++++++-- include/input/GP_Input.h | 6 - include/loaders/GP_JPG.h | 2 +- include/loaders/GP_Loaders.h | 17 ++ include/loaders/GP_PNG.h | 2 +- libs/filters/GP_Rotate.c | 266 ++++++++++++------- libs/loaders/GP_JPG.c | 8 +- libs/loaders/GP_Loaders.c | 76 +++++- libs/loaders/GP_PNG.c | 8 +- pylib/gfxprim/filters/filters.i | 8 + 29 files changed, 589 insertions(+), 245 deletions(-) delete mode 100644 LICENSE rename demos/{simple => c_simple}/Makefile (74%) rename demos/{simple => c_simple}/backend_example.c (100%) copy demos/{simple/loaders_example.c => c_simple/filters_symmetry.c} (55%) copy demos/{simple/loaders_example.c => c_simple/loaders.c} (73%) rename demos/{simple => c_simple}/loaders_example.c (98%) copy demos/{particle => c_simple}/runtest.sh (100%) create mode 100755 demos/py_simple/rotate90.py
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.