Gfxprim
Threads by month
- ----- 2026 -----
- February
- 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
June 2012
- 2 participants
- 35 discussions
[repo.or.cz] gfxprim.git branch master updated: 4c2a2fda5d4751fdc40f987c9aa8b80197b79f6b
by metan 03 Jun '12
by metan 03 Jun '12
03 Jun '12
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 4c2a2fda5d4751fdc40f987c9aa8b80197b79f6b (commit)
via 997b04b5ded1777428594d22cbd0ec9862bceca4 (commit)
via a0576560f951f9bb3b9d4257597c4e82910a1379 (commit)
from 427d2740236f2b4c0e9045282ca3d8d1cc37042a (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/4c2a2fda5d4751fdc40f987c9aa8b80197b7…
commit 4c2a2fda5d4751fdc40f987c9aa8b80197b79f6b
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jun 3 13:36:49 2012 +0200
doc: Update filters docs.
diff --git a/doc/filters.txt b/doc/filters.txt
index fad32b2..9329361 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -13,28 +13,29 @@ Common filter API
For convenience, the filters API is unified:
-* Each filter returns pointer to destination context or 'NULL' on failure
-* The first two arguments are source and destination
-* The last argument is progress callback
-
-Each filter function could be used in two modes.
+* There are two functions for each filter
+ - first one takes destination as an argument
+ - second one allocates the destination and returns pointer to it
+* First argument(s) are always source(s)
+* Then, in case of second variant, destination
+* Other parameters follow
+* And the last argument is progress callback
+
+When using allocating version of the filter, pointer to the newly allocated
+context is returned, or in case of failure 'NULL' is returned. If filter has
+been interrupted by a callback, all allocated memory is freed and 'NULL' is
+returned.
-By passing non-'NULL' argument as filter destination user requests result to
-be stored into the destination context. The context must have correct pixel
-type and the context size must be big enough to store the result.
+When using non-allocating variant of the filter, the destination context must
+have correct pixel type and the context size must be big enough to store the
+result. The return value from such filter is either zero, in case of success,
+or non-zero when filter was interrupted by a callback.
For filters that work 'in-place' (which is explicitly said for each filter)
the source and the destination could be the same context. Note that this is
-not expected to work if you do several overlapping subcontexts and pass these
+not expected to work if you do several overlapping sub-contexts and pass these
as arguments.
-When 'NULL' is passed as destination new context for storing the result is
-allocated and returned.
-
-The return value is either pointer to destination context or 'NULL' either
-when malloc(2) has failed or if the filter is not implemented for such
-pixel_type, parameters, etc...
-
[source,c]
-------------------------------------------------------------------------------
/*
@@ -103,12 +104,106 @@ GP_Context *GP_FilterInvert(const GP_Context *src, GP_Context *dst,
Inverts the image, for each channel the result value is computed as "chan_max
- val".
+Arithmetic filters
+~~~~~~~~~~~~~~~~~~
+
+Arithmetic filters do take two contexts as an input and combines them into one
+output context.
+
+The pixel type of both input contexts must match.
+
+If size of the input contexts differs, minimum is used.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <filters/GP_Arithmetic.h>
+/* or */
+#include <GP.h>
+
+int GP_FilterAddition(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterAdditionAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Produces saturated (clamped) addition of two contexts.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <filters/GP_Arithmetic.h>
+/* or */
+#include <GP.h>
+
+int GP_FilterMultiply(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMultiplyAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Produces saturated (clamped) multiplication of two contexts.
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <filters/GP_Arigthmetic.h>
+/* or */
+#include <GP.h>
+
+int GP_FilterDifference(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterDifferenceAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+
+-------------------------------------------------------------------------------
+
+Produces symmetric difference (i.e. abs(a - b)).
+
+[source,c]
+-------------------------------------------------------------------------------
+#include <filters/GP_Arigthmetic.h>
+/* or */
+#include <GP.h>
+
+int GP_FilterMax(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMaxAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+
+int GP_FilterMin(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMinAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+-------------------------------------------------------------------------------
+
+Maximum and minimum filter.
+
Rotation and Symmetry filters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
int GP_FilterMirrorH(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
@@ -126,7 +221,9 @@ as large as source.
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
int GP_FilterMirrorV(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
@@ -144,7 +241,9 @@ as large as source.
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
int GP_FilterRotate90(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
@@ -162,7 +261,9 @@ fit rotated context (i.e. W and H are swapped).
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
int GP_FilterRotate180(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
@@ -180,7 +281,9 @@ as large as source.
[source,c]
-------------------------------------------------------------------------------
-#include <GP_Filters.h>
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
int GP_FilterRotate270(const GP_Context *src, GP_Context *dst,
GP_ProgressCallback *callback);
@@ -194,10 +297,14 @@ Rotate context by 270 degrees.
Doesn't work 'in-place' (yet).
The destination has to have the same pixel type and destination size must be
-large enough to fit rotated context (eg. W and H are swapped).
+large enough to fit rotated context (i.e. W and H are swapped).
[source,c]
-------------------------------------------------------------------------------
+#include <filters/GP_Rotate.h>
+/* or */
+#include <GP.h>
+
typedef enum GP_FilterSymmetries {
GP_ROTATE_90,
GP_ROTATE_CW = GP_ROTATE_90,
@@ -263,7 +370,7 @@ Doesn't work 'in-place' (this is quite impossible as the size of the bitmap is
changed by the filter).
If the filter destination is non 'NULL' and the 'w' and 'h' is smaller than the
-destination size the source image is interpolated into subcontext of
+destination size the source image is interpolated into sub-context of
destination defined by 'w' and 'h'.
'TODO:' this filter is implemented for RGB888 only.
http://repo.or.cz/w/gfxprim.git/commit/997b04b5ded1777428594d22cbd0ec9862bc…
commit 997b04b5ded1777428594d22cbd0ec9862bceca4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jun 3 12:22:48 2012 +0200
filters: Change arithmetics filters API.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c
index 3da5037..abdf546 100644
--- a/demos/grinder/grinder.c
+++ b/demos/grinder/grinder.c
@@ -608,19 +608,19 @@ static GP_RetCode arithmetic(GP_Context **c, const char *params)
switch (op) {
case 0:
- res = GP_FilterDifference(*c, img, NULL, progress_callback);
+ res = GP_FilterDifferenceAlloc(*c, img, progress_callback);
break;
case 1:
- res = GP_FilterAddition(*c, img, NULL, progress_callback);
+ res = GP_FilterAdditionAlloc(*c, img, progress_callback);
break;
case 2:
- res = GP_FilterMultiply(*c, img, NULL, progress_callback);
+ res = GP_FilterMultiplyAlloc(*c, img, progress_callback);
break;
case 3:
- res = GP_FilterMin(*c, img, NULL, progress_callback);
+ res = GP_FilterMinAlloc(*c, img, progress_callback);
break;
case 4:
- res = GP_FilterMax(*c, img, NULL, progress_callback);
+ res = GP_FilterMaxAlloc(*c, img, progress_callback);
break;
}
diff --git a/include/filters/GP_Arithmetic.h b/include/filters/GP_Arithmetic.h
index 9f1cb20..47fca47 100644
--- a/include/filters/GP_Arithmetic.h
+++ b/include/filters/GP_Arithmetic.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-2012 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -34,21 +34,30 @@
/*
* Addition filter.
*
- * Produces clamped addtion.
+ * Produces saturated (clamped) addtion.
*/
-GP_Context *GP_FilterAddition(const GP_Context *src_a,
- const GP_Context *src_b,
- GP_Context *dst,
- GP_ProgressCallback *callback);
+int GP_FilterAddition(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterAdditionAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
+
/*
* Multiply filter.
*
- * Produces clamped multiplication.
+ * Produces saturated (clamped) multiplication.
*/
-GP_Context *GP_FilterMultiply(const GP_Context *src_a,
- const GP_Context *src_b,
- GP_Context *dst,
- GP_ProgressCallback *callback);
+int GP_FilterMultiply(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMultiplyAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
/*
* Difference filter.
@@ -56,25 +65,37 @@ GP_Context *GP_FilterMultiply(const GP_Context *src_a,
* Produces symetric difference.
* eg. dst = abs(src_a - src_b)
*/
-GP_Context *GP_FilterDifference(const GP_Context *src_a,
- const GP_Context *src_b,
- GP_Context *dst,
- GP_ProgressCallback *callback);
+int GP_FilterDifference(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterDifferenceAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
/*
* Maximum filter.
*/
-GP_Context *GP_FilterMax(const GP_Context *src_a,
- const GP_Context *src_b,
- GP_Context *dst,
- GP_ProgressCallback *callback);
+int GP_FilterMax(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMaxAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
/*
* Minimum filter.
*/
-GP_Context *GP_FilterMin(const GP_Context *src_a,
- const GP_Context *src_b,
- GP_Context *dst,
- GP_ProgressCallback *callback);
+int GP_FilterMin(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_Context *dst,
+ GP_ProgressCallback *callback);
+
+GP_Context *GP_FilterMinAlloc(const GP_Context *src_a,
+ const GP_Context *src_b,
+ GP_ProgressCallback *callback);
#endif /* FILTERS_GP_ARITHMETIC_H */
diff --git a/pylib/templates/filter.arithmetic.c.t b/pylib/templates/filter.arithmetic.c.t
index e083921..d74ddce 100644
--- a/pylib/templates/filter.arithmetic.c.t
+++ b/pylib/templates/filter.arithmetic.c.t
@@ -116,10 +116,30 @@ int GP_Filter{{ name }}_Raw(const GP_Context *src_a, const GP_Context *src_b,
return 1;
}
-GP_Context *GP_Filter{{ name }}(const GP_Context *src_a, const GP_Context *src_b,
- GP_Context *dst{{ maybe_opts_l(opts) }}, GP_ProgressCallback *callback)
+int GP_Filter{{ name }}(const GP_Context *src_a, const GP_Context *src_b,
+ GP_Context *dst{{ maybe_opts_l(opts) }},
+ GP_ProgressCallback *callback)
{
- GP_Context *res = dst;
+ GP_Size w = GP_MIN(src_a->w, src_b->w);
+ GP_Size h = GP_MIN(src_a->h, src_b->h);
+
+ GP_ASSERT(src_a->pixel_type == dst->pixel_type,
+ "The src and dst pixel types must match");
+ GP_ASSERT(w <= dst->w && h <= dst->h,
+ "Destination is not big enough");
+
+ if (GP_Filter{{ name }}_Raw(src_a, src_b, dst{{ maybe_opts_l(params) }}, callback)) {
+ GP_DEBUG(1, "Operation aborted");
+ return 1;
+ }
+
+ return 0;
+}
+
+GP_Context *GP_Filter{{ name }}Alloc(const GP_Context *src_a, const GP_Context *src_b,
+ {{ maybe_opts_r(opts) }}GP_ProgressCallback *callback)
+{
+ GP_Context *res;
GP_ASSERT(src_a->pixel_type == src_b->pixel_type,
"Pixel types for sources must match.");
@@ -127,24 +147,15 @@ GP_Context *GP_Filter{{ name }}(const GP_Context *src_a, const GP_Context *src_b
GP_Size w = GP_MIN(src_a->w, src_b->w);
GP_Size h = GP_MIN(src_a->h, src_b->h);
- if (res == NULL) {
-
- res = GP_ContextAlloc(w, h, src_a->pixel_type);
-
- if (res == NULL)
- return NULL;
- } else {
- GP_ASSERT(src_a->pixel_type == dst->pixel_type,
- "The src and dst pixel types must match");
- GP_ASSERT(w <= dst->w && h <= dst->h,
- "Destination is not big enough");
- }
+ res = GP_ContextAlloc(w, h, src_a->pixel_type);
+
+ if (res == NULL)
+ return NULL;
if (GP_Filter{{ name }}_Raw(src_a, src_b, res{{ maybe_opts_l(params) }}, callback)) {
GP_DEBUG(1, "Operation aborted");
- if (dst == NULL)
- GP_ContextFree(res);
+ GP_ContextFree(res);
return NULL;
}
http://repo.or.cz/w/gfxprim.git/commit/a0576560f951f9bb3b9d4257597c4e82910a…
commit a0576560f951f9bb3b9d4257597c4e82910a1379
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jun 3 12:22:12 2012 +0200
doc: Update backend docs.
diff --git a/doc/Makefile b/doc/Makefile
index d709a78..8d4ffbf 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,7 +1,7 @@
all: api.html examples.html
api.html: general.txt api.txt context.txt loaders.txt filters.txt - basic_types.txt drawing_api.txt
+ basic_types.txt drawing_api.txt backends.txt
asciidoc -a toc api.txt
examples.html: examples.txt ../demos/c_simple/*.c ../demos/py_simple/*.py
diff --git a/doc/backends.txt b/doc/backends.txt
index 2a614ff..9ce83d7 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -15,16 +15,16 @@ Initialization functions
[source,c]
-------------------------------------------------------------------------------
-GP_Backend *GP_BackendLinuxFBInit(const char *path);
+GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag);
-------------------------------------------------------------------------------
Initializes mmaped frame-buffer backend. The path is path to the frame-buffer
device i.e. '/dev/fbX'. This backend is not buffered, everything you draw
appears on the screen right away (an switch may be added for that purpose).
-Also note that this backend doesn't initialize any input driver. You need to
-initialize input driver in order to get keystrokes and/or pointer events.
-
+If flag is set console KBD driver is used to feed keystrokes into the event
+queue, otherwise no events are generated and you are expected to initialize
+input event driver in order to get keystrokes and/or pointer events.
[source,c]
-------------------------------------------------------------------------------
@@ -39,28 +39,47 @@ GP_Backend *GP_BackendSDLInit(GP_Size w, GP_Size h,
-------------------------------------------------------------------------------
Initialize SDL as an backend driver. The backend is thread safe as all the
-operations are guarded by locks. You can't initialize more than one backend at a
-time, that is inherited SDL limitation. If you call the initialization for a
-second time, you will get a pointer to already running backend. This driver
-feeds input events into global input event queue (see input docs for details).
-If w, h and/or bpp are zero SDL tries to do a guess, most of the time wrong for
-w and h though. The caption is window caption and may be ignored for some of
-the backends. And finally flags may change the SDL to go to full-screen mode or
-make the window resizable.
+operations are guarded by locks.
+
+You can't initialize more than one backend at a time, which is inherited SDL
+limitation. If you call the initialization for a second time, you will get a
+pointer to already running backend.
+
+This driver feeds input events into global input event queue (see input docs
+for details).
+
+If w, h and/or bpp are zero SDL tries to do a guess, most of the time wrong
+for w and h though.
+
+The caption is window caption.
+
+And finally flags may change the SDL to go to full-screen mode or make the
+window resizable.
[source,c]
-------------------------------------------------------------------------------
+enum GP_BackendX11Flags {
+ /*
+ * When set, w and h is ignored and root window is used
+ */
+ GP_X11_USE_ROOT_WIN = 0x01,
+};
+
GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
unsigned int w, unsigned int h,
- const char *caption);
+ const char *caption,
+ enum GP_BackendX11Flags flags);
-------------------------------------------------------------------------------
-Returns pointer to backend. When display is NULL default display is used
-(which is what you want most of the time). This backend feeds key events into
-global input queue (pointer events not implemented yet). Note this is
-experimental version of X11 backend and will be changed to support more
-windows at a time.
+Returns pointer to initialized X11 backend or in case of failure NULL.
+
+When display is NULL default display is used (which is what you want most of the
+time).
+This backend feeds key events into global input queue.
+
+Note this is experimental version of X11 backend and will be changed to support
+more windows at a time.
Overall init function
~~~~~~~~~~~~~~~~~~~~~
@@ -95,7 +114,29 @@ initialization yields pointer to this structure. Although is possible to call
these pointers directly it's not recommended and everybody should rather use
backend inline functions instead.
-The backend API consist of several functions:
+The backend API consist GP_Backend structure and of several functions:
+
+[source,c]
+-------------------------------------------------------------------------------
+typdef struct GP_Backend {
+ /*
+ * Backend name.
+ */
+ const char *name;
+
+ /*
+ * Pointer to context app should draw to.
+ */
+ GP_Context *context;
+
+ ...
+
+ /*
+ * Connection fd. Set to -1 if not available
+ */
+ int fd;
+};
+-------------------------------------------------------------------------------
[source,c]
-------------------------------------------------------------------------------
@@ -128,3 +169,23 @@ void GP_BackendPoll(GP_Backend *backend);
Polls for backend events. For backends that do not expose file descriptor
(namely SDL) this should be called repeatedly. For other backend it may be
called either repeatedly or when data are ready on file-descriptor.
+
+[source,c]
+-------------------------------------------------------------------------------
+int GP_BackendSetCaption(GP_Backend *backend, const char *caption)
+-------------------------------------------------------------------------------
+
+Sets backend caption. On success zero is returned. On failure (backend doesn't
+support caption, operation failed) non zero is returned.
+
+[source,c]
+-------------------------------------------------------------------------------
+int GP_BackendResize(GP_Backend *backend, uint32_t w, uint32_t h);
+-------------------------------------------------------------------------------
+
+Resize backend, if supported. On success zero is returned and backend is
+resized, otherwise (if resize failed, or is not supported) non-zero is
+returned. If backend size already matches w and h, nothing is done.
+
+Note that backend->context pointer may change upon calling this function and
+at least backend->context->pixels pointer will change.
-----------------------------------------------------------------------
Summary of changes:
demos/grinder/grinder.c | 10 +-
doc/Makefile | 2 +-
doc/backends.txt | 99 +++++++++++++++++----
doc/filters.txt | 155 ++++++++++++++++++++++++++++-----
include/filters/GP_Arithmetic.h | 67 +++++++++-----
pylib/templates/filter.arithmetic.c.t | 45 ++++++----
6 files changed, 289 insertions(+), 89 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
[repo.or.cz] gfxprim.git branch master updated: 427d2740236f2b4c0e9045282ca3d8d1cc37042a
by metan 03 Jun '12
by metan 03 Jun '12
03 Jun '12
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 427d2740236f2b4c0e9045282ca3d8d1cc37042a (commit)
via 7ced426dcbac270e05d48913f2611f34e48eeb40 (commit)
from aef381e3ac79970a4167fd9f0d5d681e4203ef5e (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/427d2740236f2b4c0e9045282ca3d8d1cc37…
commit 427d2740236f2b4c0e9045282ca3d8d1cc37042a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jun 3 11:22:32 2012 +0200
loaders: Make use of edhanced debug messages.
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 72e4c86..2c40f47 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -219,7 +219,7 @@ static void read_jpg_metadata(struct jpeg_decompress_struct *cinfo,
marker->data_length, 1);
break;
case JPEG_APP0:
- GP_DEBUG(0, "TODO: JFIF");
+ GP_TODO("JFIF");
break;
case JPEG_APP0 + 1:
GP_MetaDataFromExif(data, marker->data, marker->data_length);
diff --git a/libs/loaders/GP_MetaExif.c b/libs/loaders/GP_MetaExif.c
index 08fb7f9..f188e00 100644
--- a/libs/loaders/GP_MetaExif.c
+++ b/libs/loaders/GP_MetaExif.c
@@ -201,7 +201,7 @@ static const struct IFD_tag IFD_tags[] = {
/* TAGs from Exif SubIFD */
{IFD_EXPOSURE_PROGRAM, "Exposure Program", IFD_UNSIGNED_SHORT, 1},
- {IFD_ISO_SPEED_RATINGS, "ISO Speed Ratings", IFD_UNSIGNED_SHORT, 2},
+ {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},
@@ -360,21 +360,21 @@ static void load_tag(GP_MetaData *self, void *buf, size_t buf_len, int swap,
const struct IFD_tag *res = IFD_tag_get(tag);
if (res == NULL) {
- GP_DEBUG(1, "Skipping unknown IFD tag 0x%02x", tag);
+ GP_TODO("Skipping unknown IFD tag 0x%02x", tag);
return;
}
if (res->format != format) {
- GP_DEBUG(1, "Unexpected tag '%s' format '%s' (0x%02x) "
- "expected '%s'", res->name,
- IFD_format_name(format), format,
- IFD_format_name(res->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_DEBUG(1, "Unexpected tag '%s' num_components %u expected %u",
- res->name, num_comp, res->num_components);
+ GP_WARN("Unexpected tag '%s' num_components %u expected %u",
+ res->name, num_comp, res->num_components);
}
const char *addr;
@@ -420,8 +420,8 @@ static void load_tag(GP_MetaData *self, void *buf, size_t buf_len, int swap,
break;
unused:
default:
- GP_DEBUG(0, "Unused record '%s' format '%s' (0x%02x)", res->name,
- IFD_format_name(format), format);
+ GP_TODO("Unused record '%s' format '%s' (0x%02x)", res->name,
+ IFD_format_name(format), format);
}
}
@@ -483,16 +483,15 @@ int GP_MetaDataFromExif(GP_MetaData *self, void *buf, size_t buf_len)
buf_char(buf, 3, buf_len) != 'f' ||
buf_char(buf, 4, buf_len) != 0 ||
buf_char(buf, 5, buf_len) != 0) {
- GP_DEBUG(1, "Missing ASCII 'Exif
- "the start of the buffer");
+ GP_WARN("Missing ASCII 'Exif
+ "the start of the buffer");
return 1;
}
if (((c1 = buf_char(buf, 6, buf_len)) !=
(c2 = buf_char(buf, 7, buf_len)))
|| (c1 != 'I' && c1 != 'M')) {
- GP_DEBUG(1, "Expected II or MM got %x%x, corrupt header?",
- c1, c2);
+ GP_WARN("Expected II or MM got %x%x, corrupt header?", c1, c2);
return 1;
}
@@ -505,7 +504,7 @@ int GP_MetaDataFromExif(GP_MetaData *self, void *buf, size_t buf_len)
GET_16(tag, buf, 8, buf_len, swap);
if (tag != 0x002a) {
- GP_DEBUG(1, "Expected TIFF TAG '0x002a' got '0x%04x'", tag);
+ GP_WARN("Expected TIFF TAG '0x002a' got '0x%04x'", tag);
return 1;
}
http://repo.or.cz/w/gfxprim.git/commit/7ced426dcbac270e05d48913f2611f34e48e…
commit 7ced426dcbac270e05d48913f2611f34e48eeb40
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jun 3 11:14:04 2012 +0200
core: Edhance and rewrite debug messages.
diff --git a/include/core/GP_Debug.h b/include/core/GP_Debug.h
index 235f001..a09ba69 100644
--- a/include/core/GP_Debug.h
+++ b/include/core/GP_Debug.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-2012 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -33,6 +33,10 @@
Debug level > 1 is intended for more verbose reporting, like inner cycles
or loop debugging.
+ Debug levels with negative level are special. Debug level -1 means TODO,
+ level -2 says WARNING while -2 means BUG (i.e. library get into unconsistent
+ state).
+
*/
#ifndef GP_DEBUG_H
@@ -45,17 +49,23 @@
#define GP_DEFAULT_DEBUG_LEVEL 0
-#define GP_DEBUG(level, ...) do { - if (level <= GP_GetDebugLevel()) { - fprintf(stderr, "%u: %s:%s():%u: ", level, __FILE__, - __FUNCTION__, __LINE__); - fprintf(stderr, __VA_ARGS__); - fputc('n', stderr); - } -} while (0)
+#define GP_DEBUG(level, ...) + GP_DebugPrint(level, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define GP_TODO(...) + GP_DebugPrint(-1, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define GP_WARN(...) + GP_DebugPrint(-2, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define GP_BUG(...) + GP_DebugPrint(-3, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
void GP_SetDebugLevel(unsigned int level);
unsigned int GP_GetDebugLevel(void);
+void GP_DebugPrint(int level, const char *file, const char *function, int line,
+ const char *fmt, ...) __attribute__ ((format (printf, 5, 6)));
+
#endif /* GP_DEBUG_H */
diff --git a/libs/core/GP_Debug.c b/libs/core/GP_Debug.c
index d3b8cbe..ecef216 100644
--- a/libs/core/GP_Debug.c
+++ b/libs/core/GP_Debug.c
@@ -16,20 +16,57 @@
* 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-2012 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
+#include <stdarg.h>
+
#include "GP_Debug.h"
-static unsigned int GP_debug_level = GP_DEFAULT_DEBUG_LEVEL;
+static unsigned int debug_level = GP_DEFAULT_DEBUG_LEVEL;
void GP_SetDebugLevel(unsigned int level)
{
- GP_debug_level = level;
+ debug_level = level;
}
unsigned int GP_GetDebugLevel(void)
{
- return GP_debug_level;
+ return debug_level;
+}
+
+void GP_DebugPrint(int level, const char *file, const char *function, int line,
+ const char *fmt, ...)
+{
+ int i;
+
+ if (level > (int)debug_level)
+ return;
+
+ for (i = 1; i < level; i++)
+ fputc(' ', stderr);
+
+ switch (level) {
+ case -3:
+ fprintf(stderr, "*** BUG: %s:%s():%u: ", file, function, line);
+ break;
+ case -2:
+ fprintf(stderr, "*** WARNING: %s:%s():%u: ", file, function, line);
+ break;
+ case -1:
+ fprintf(stderr, "*** TODO: %s:%s():%u: ", file, function, line);
+ break;
+ default:
+ fprintf(stderr, "%u: %s:%s():%u: ",
+ level, file, function, line);
+ break;
+ }
+
+ va_list va;
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+
+ fputc('n', stderr);
}
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_Debug.h | 28 ++++++++++++++++++--------
libs/core/GP_Debug.c | 45 ++++++++++++++++++++++++++++++++++++++++---
libs/loaders/GP_JPG.c | 2 +-
libs/loaders/GP_MetaExif.c | 29 +++++++++++++--------------
4 files changed, 75 insertions(+), 29 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
[repo.or.cz] gfxprim.git branch master updated: aef381e3ac79970a4167fd9f0d5d681e4203ef5e
by metan 02 Jun '12
by metan 02 Jun '12
02 Jun '12
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 aef381e3ac79970a4167fd9f0d5d681e4203ef5e (commit)
via 32857ab67cf984aeeb14cec514406fdf6cc0eff3 (commit)
via a97d1e9056b14aecb130f45368093a06c4b82cf5 (commit)
from bcd98a45393d9f7273c4d8c589580ff457f3bc1a (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/aef381e3ac79970a4167fd9f0d5d681e4203…
commit aef381e3ac79970a4167fd9f0d5d681e4203ef5e
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jun 2 20:14:04 2012 +0200
loaders: Add generic function to load Meta Data.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index c03f374..22efd37 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -6,7 +6,7 @@ INCLUDE=
LDLIBS+=-lGP -lGP_backends -lSDL -L$(TOPDIR)/build/
APPS=backend_example loaders_example loaders filters_symmetry gfx_koch- virtual_backend_example meta_data meta_data_png
+ virtual_backend_example meta_data meta_data_dump
include $(TOPDIR)/pre.mk
include $(TOPDIR)/app.mk
diff --git a/demos/c_simple/meta_data_png.c b/demos/c_simple/meta_data_dump.c
similarity index 94%
rename from demos/c_simple/meta_data_png.c
rename to demos/c_simple/meta_data_dump.c
index 9f6543b..d9aacfb 100644
--- a/demos/c_simple/meta_data_png.c
+++ b/demos/c_simple/meta_data_dump.c
@@ -22,7 +22,7 @@
/*
- Read png meta-data and print them into stdout.
+ Read image meta-data and print them into stdout.
*/
@@ -37,7 +37,7 @@
int main(int argc, char *argv[])
{
- GP_MetaData *data = GP_MetaDataCreate(20);
+ GP_MetaData *data = GP_MetaDataCreate(80);
int i;
if (argc < 2) {
@@ -53,7 +53,7 @@ int main(int argc, char *argv[])
GP_MetaDataClear(data);
- if (GP_LoadPNGMetaData(argv[i], data)) {
+ if (GP_LoadMetaData(argv[i], data)) {
fprintf(stderr, "Failed to read '%s' meta-data: %sn",
argv[1], strerror(errno));
} else {
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h
index d374f99..c7aab95 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Loaders.h
@@ -54,6 +54,11 @@
GP_Context *GP_LoadImage(const char *src_path, GP_ProgressCallback *callback);
/*
+ * Loads image Meta Data (if possible).
+ */
+int GP_LoadMetaData(const char *src_path, GP_MetaData *data);
+
+/*
* Simple saving function, the image format is matched by file extension.
*
* Retruns zero on succes.
diff --git a/libs/loaders/GP_Loaders.c b/libs/loaders/GP_Loaders.c
index a6349bc..f298983 100644
--- a/libs/loaders/GP_Loaders.c
+++ b/libs/loaders/GP_Loaders.c
@@ -148,6 +148,50 @@ skip_filename_check:
return NULL;
}
+int GP_LoadMetaData(const char *src_path, GP_MetaData *data)
+{
+ int len;
+
+ len = strlen(src_path);
+
+ if (len < 3) {
+ errno = ENOSYS;
+ return 1;
+ }
+
+ switch (src_path[len - 1]) {
+ /* PNG, JPG, JPEG */
+ case 'g':
+ case 'G':
+ switch (src_path[len - 2]) {
+ case 'n':
+ case 'N':
+ if (src_path[len - 3] == 'p' ||
+ src_path[len - 3] == 'P')
+ return GP_LoadPNGMetaData(src_path, data);
+ break;
+ case 'p':
+ case 'P':
+ if (src_path[len - 3] == 'j' ||
+ src_path[len - 3] == 'J')
+ return GP_LoadJPGMetaData(src_path, data);
+ break;
+ case 'e':
+ case 'E':
+ if ((src_path[len - 3] == 'p' ||
+ src_path[len - 3] == 'P') &&
+ (src_path[len - 4] == 'j' ||
+ src_path[len - 4] == 'J'))
+ return GP_LoadJPGMetaData(src_path, data);
+ break;
+ }
+ break;
+ }
+
+ errno = ENOSYS;
+ return 1;
+}
+
int GP_SaveImage(const GP_Context *src, const char *dst_path,
GP_ProgressCallback *callback)
{
http://repo.or.cz/w/gfxprim.git/commit/32857ab67cf984aeeb14cec514406fdf6cc0…
commit 32857ab67cf984aeeb14cec514406fdf6cc0eff3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jun 2 20:05:40 2012 +0200
loaders: More work on Exif loader, mostly finisned.
diff --git a/libs/loaders/GP_MetaExif.c b/libs/loaders/GP_MetaExif.c
index e6a89bc..08fb7f9 100644
--- a/libs/loaders/GP_MetaExif.c
+++ b/libs/loaders/GP_MetaExif.c
@@ -71,38 +71,39 @@ static const char *IFD_format_names[] = {
};
enum IFD_tags {
- /* image description */
+ /* ASCII text no multibyte encoding */
IFD_IMAGE_DESCRIPTION = 0x010e,
- /* camera manufacturer */
+ /* Device (camer, scanner, ...) manufacturer */
IFD_MAKE = 0x010f,
- /* camera model */
+ /* Device model */
IFD_MODEL = 0x0110,
- /* 1 = upper left, 3 = lower right, 6 = upper right, *
- * 8 = lower left, 9 = undefined */
+ /* Image orientation *
+ * 1 upper left, 3 lower right, 6 upper right, *
+ * 8 lower left, other reserved */
IFD_ORIENTATION = 0x0112,
- /* x resolution */
+ /* X resolution 72 DPI is default */
IFD_X_RESOLUTION = 0x011a,
- /* y resolution */
+ /* Y resolution 72 DPI is default */
IFD_Y_RESOLUTION = 0x011b,
- /* 1 = no unit, 2 = inch, 3 = centimeter */
+ /* 1 = no unit, 2 = inch (default), 3 = centimeter */
IFD_RESOLUTION_UNIT = 0x0128,
- /* software */
+ /* Software string. */
IFD_SOFTWARE = 0x0131,
- /* date time */
+ /* YYYY:MM:DD HH:MM:SS in 24 hours format */
IFD_DATE_TIME = 0x0132,
- /* white point */
+ /* White Point */
IFD_WHITE_POINT = 0x013e,
- /* primary chromaticies */
+ /* Primary Chromaticies */
IFD_PRIMARY_CHROMATICIES = 0x013f,
- /* YCbCr coefficients */
+ /* YCbCr Coefficients */
IFD_Y_CB_CR_COEFFICIENTS = 0x0211,
- /* YCbCr positioning */
+ /* YCbCr Positioning */
IFD_Y_CB_CR_POSITIONING = 0x0213,
- /* reference black white */
+ /* Reference Black White */
IFD_REFERENCE_BLACK_WHITE = 0x0214,
- /* copyright */
+ /* Copyright */
IFD_COPYRIGHT = 0x8298,
- /* exif offset */
+ /* Exif SubIFD Offset */
IFD_EXIF_OFFSET = 0x8769,
/* TAGs from Exif SubIFD */
@@ -150,6 +151,18 @@ enum IFD_tags {
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,
+ /* */
+
};
struct IFD_tag {
@@ -164,8 +177,8 @@ struct IFD_tag {
static const struct IFD_tag IFD_tags[] = {
/* TAGs from IFD0 */
{IFD_IMAGE_DESCRIPTION, "Image Description", IFD_ASCII_STRING, 0},
- {IFD_MAKE, "Camera Manufacturer", IFD_ASCII_STRING, 0},
- {IFD_MODEL, "Camera Model", 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},
@@ -206,6 +219,12 @@ 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_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},
};
static const char *IFD_format_name(uint16_t format)
@@ -357,10 +376,12 @@ static void load_tag(GP_MetaData *self, void *buf, size_t buf_len, int swap,
GP_DEBUG(1, "Unexpected tag '%s' num_components %u expected %u",
res->name, num_comp, res->num_components);
}
+
+ const char *addr;
switch (format) {
case IFD_ASCII_STRING: {
- const char *addr = get_string(buf, buf_len, num_comp, &val);
+ addr = get_string(buf, buf_len, num_comp, &val);
if (addr == NULL)
return;
@@ -382,9 +403,24 @@ static void load_tag(GP_MetaData *self, void *buf, size_t buf_len, int swap,
else
goto unused;
break;
+ case IFD_UNDEFINED:
+ switch (res->tag) {
+ case IFD_EXIF_VERSION:
+ case IFD_FLASH_PIX_VERSION:
+ addr = get_string(buf, buf_len, num_comp, &val);
+
+ if (addr == NULL)
+ return;
+
+ GP_MetaDataCreateString(self, res->name, addr, num_comp, 1);
+ break;
+ default:
+ goto unused;
+ }
+ break;
unused:
default:
- GP_DEBUG(1, "Unused record '%s' format '%s' (0x%02x)", res->name,
+ GP_DEBUG(0, "Unused record '%s' format '%s' (0x%02x)", res->name,
IFD_format_name(format), format);
}
}
http://repo.or.cz/w/gfxprim.git/commit/a97d1e9056b14aecb130f45368093a06c4b8…
commit a97d1e9056b14aecb130f45368093a06c4b82cf5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jun 2 19:33:40 2012 +0200
loaders: MetaData: edhance printing rational numbers.
diff --git a/libs/loaders/GP_MetaData.c b/libs/loaders/GP_MetaData.c
index 1a7ad93..a81480f 100644
--- a/libs/loaders/GP_MetaData.c
+++ b/libs/loaders/GP_MetaData.c
@@ -103,7 +103,8 @@ void GP_MetaDataPrint(GP_MetaData *self)
printf("%in", rec->val.i);
break;
case GP_META_RATIONAL:
- printf("%i/%in", rec->val.r.num, rec->val.r.den);
+ printf("%i/%i (%.4f)n", rec->val.r.num, rec->val.r.den,
+ (float)rec->val.r.num / rec->val.r.den);
break;
case GP_META_STRING:
printf("'%s'n", rec->val.str);
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 2 +-
.../c_simple/{meta_data_png.c => meta_data_dump.c} | 6 +-
include/loaders/GP_Loaders.h | 5 +
libs/loaders/GP_Loaders.c | 44 +++++++++++
libs/loaders/GP_MetaData.c | 3 +-
libs/loaders/GP_MetaExif.c | 78 ++++++++++++++-----
6 files changed, 112 insertions(+), 26 deletions(-)
rename demos/c_simple/{meta_data_png.c => meta_data_dump.c} (94%)
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
[repo.or.cz] gfxprim.git branch master updated: bcd98a45393d9f7273c4d8c589580ff457f3bc1a
by metan 02 Jun '12
by metan 02 Jun '12
02 Jun '12
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 bcd98a45393d9f7273c4d8c589580ff457f3bc1a (commit)
from 8da4803c71d9fba0fb5a70c8cc5feccbaf4fdac0 (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/bcd98a45393d9f7273c4d8c589580ff457f3…
commit bcd98a45393d9f7273c4d8c589580ff457f3bc1a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jun 2 00:29:05 2012 +0200
loaders: A few Meta Data fixes.
diff --git a/libs/loaders/GP_MetaData.c b/libs/loaders/GP_MetaData.c
index 1403e01..1a7ad93 100644
--- a/libs/loaders/GP_MetaData.c
+++ b/libs/loaders/GP_MetaData.c
@@ -159,6 +159,7 @@ static GP_MetaRecord *record_create(GP_MetaData *self, const char *id,
strcpy(rec->id, id);
rec->hash = hash;
+ rec->next = NULL;
if (self->root == NULL) {
self->root = rec;
@@ -166,7 +167,6 @@ static GP_MetaRecord *record_create(GP_MetaData *self, const char *id,
} else {
self->last->next = rec;
self->last = rec;
- rec->next = NULL;
}
self->rec_count++;
@@ -335,9 +335,9 @@ GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
char *s;
if (len == 0)
- size = strlen(str) + 1;
- else
- size = len + 1;
+ len = strlen(str);
+
+ size = len + 1;
/* Play safe with aligment */
if (size % 8)
@@ -345,8 +345,8 @@ GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
//TODO: allocation error
s = do_alloc(self, size);
- strncpy(s, str, size - 1);
- s[size - 1] = '0';
+ memcpy(s, str, len);
+ s[len] = '0';
str = s;
}
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_MetaData.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 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
[repo.or.cz] gfxprim.git branch master updated: 8da4803c71d9fba0fb5a70c8cc5feccbaf4fdac0
by metan 02 Jun '12
by metan 02 Jun '12
02 Jun '12
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 8da4803c71d9fba0fb5a70c8cc5feccbaf4fdac0 (commit)
via d0497f46eebcf460bd1377686f1f6218804743b4 (commit)
from 9dc7c882ccd99e87e0146b367037d89ceb98aef1 (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/8da4803c71d9fba0fb5a70c8cc5feccbaf4f…
commit 8da4803c71d9fba0fb5a70c8cc5feccbaf4fdac0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jun 2 00:08:53 2012 +0200
loaders: Added Exif to MetaData parser.
diff --git a/demos/c_simple/meta_data.c b/demos/c_simple/meta_data.c
index b5f2905..746f6b7 100644
--- a/demos/c_simple/meta_data.c
+++ b/demos/c_simple/meta_data.c
@@ -60,8 +60,8 @@ int main(void)
* The last parameter says, if the string should be duplicated
* in the metadata storage.
*/
- GP_MetaDataCreateString(data, "author", "Foo Bar <foo(a)bar.net>", 1);
- GP_MetaDataCreateString(data, "comment", "Created in hurry.", 1);
+ GP_MetaDataCreateString(data, "author", "Foo Bar <foo(a)bar.net>", 0, 1);
+ GP_MetaDataCreateString(data, "comment", "Created in hurry.", 0, 1);
GP_MetaDataCreateDouble(data, "pi", 3.141592);
const char *ret;
diff --git a/include/loaders/GP_MetaData.h b/include/loaders/GP_MetaData.h
index 4da30f1..2c529d2 100644
--- a/include/loaders/GP_MetaData.h
+++ b/include/loaders/GP_MetaData.h
@@ -23,18 +23,25 @@
#ifndef LOADERS_METADATA_H
#define LOADERS_METADATA_H
-#define GP_META_RECORD_ID_MAX 16
+#define GP_META_RECORD_ID_MAX 32
enum GP_MetaType {
GP_META_INT,
GP_META_STRING,
GP_META_DOUBLE,
+ GP_META_RATIONAL,
+};
+
+struct GP_MetaRational {
+ int num;
+ int den;
};
union GP_MetaValue {
int i;
double d;
const char *str;
+ struct GP_MetaRational r;
};
typedef struct GP_MetaRecord {
@@ -98,6 +105,9 @@ GP_MetaRecord *GP_MetaDataCreateRecord(GP_MetaData *self, const char *id);
*/
GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val);
+GP_MetaRecord *GP_MetaDataCreateRat(GP_MetaData *self, const char *id,
+ int num, int den);
+
/*
* Creates an double record and returns pointer to it.
*/
@@ -107,10 +117,19 @@ GP_MetaRecord *GP_MetaDataCreateDouble(GP_MetaData *self, const char *id,
/*
* Creates an string record and returns pointer to it.
*
+ * If len == 0, string is copied to the terminating '0', otherwise len
+ * characters is copied. This has no effect if dup == 0.
+ *
* If dup is set to 1, the string is duplicated inside of the MetaData
* structure, otherwise only the pointer is saved.
*/
GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
- const char *str, int dup);
+ const char *str, int len, int dup);
+
+/*
+ * Parses Exif data from passed buffer. The start of the buffer must point to
+ * the ASCII 'Exif' string.
+ */
+int GP_MetaDataFromExif(GP_MetaData *self, void *buf, size_t buf_len);
#endif /* LOADERS_GP_METADATA_H */
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index f600b57..72e4c86 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -214,24 +214,15 @@ static void read_jpg_metadata(struct jpeg_decompress_struct *cinfo,
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
switch (marker->marker) {
- case JPEG_COM: {
- char buf[JPEG_COM_MAX+1];
-
- memcpy(buf, marker->data, marker->data_length);
- buf[marker->data_length] = 0;
-
- /* Strip newline at the end of the commment */
- if (buf[marker->data_length-1] == 'n')
- buf[marker->data_length-1] = 0;
-
- GP_MetaDataCreateString(data, "comment", buf, 1);
- }
+ case JPEG_COM:
+ GP_MetaDataCreateString(data, "comment", (void*)marker->data,
+ marker->data_length, 1);
break;
case JPEG_APP0:
GP_DEBUG(0, "TODO: JFIF");
break;
case JPEG_APP0 + 1:
- GP_DEBUG(0, "TODO: EXIF");
+ GP_MetaDataFromExif(data, marker->data, marker->data_length);
break;
}
}
diff --git a/libs/loaders/GP_MetaData.c b/libs/loaders/GP_MetaData.c
index e62af18..1403e01 100644
--- a/libs/loaders/GP_MetaData.c
+++ b/libs/loaders/GP_MetaData.c
@@ -29,6 +29,7 @@
struct GP_MetaData {
struct GP_MetaRecord *root;
+ struct GP_MetaRecord *last;
unsigned int rec_count;
size_t size;
size_t free;
@@ -63,6 +64,7 @@ GP_MetaData *GP_MetaDataCreate(unsigned int expected_records)
}
data->root = NULL;
+ data->last = NULL;
data->rec_count = 0;
data->size = size;
data->free = size;
@@ -76,6 +78,7 @@ void GP_MetaDataClear(GP_MetaData *self)
self, self->rec_count);
self->root = NULL;
+ self->last = NULL;
self->rec_count = 0;
self->free = self->size;
}
@@ -93,12 +96,15 @@ void GP_MetaDataPrint(GP_MetaData *self)
printf("MetaData %u record(s)n", self->rec_count);
for (rec = self->root; rec != NULL; rec = rec->next) {
- printf("%-16s: ", rec->id);
+ printf("%-32s: ", rec->id);
switch (rec->type) {
case GP_META_INT:
printf("%in", rec->val.i);
break;
+ case GP_META_RATIONAL:
+ printf("%i/%in", rec->val.r.num, rec->val.r.den);
+ break;
case GP_META_STRING:
printf("'%s'n", rec->val.str);
break;
@@ -153,9 +159,16 @@ static GP_MetaRecord *record_create(GP_MetaData *self, const char *id,
strcpy(rec->id, id);
rec->hash = hash;
- rec->next = self->root;
- self->root = rec;
-
+
+ if (self->root == NULL) {
+ self->root = rec;
+ self->last = rec;
+ } else {
+ self->last->next = rec;
+ self->last = rec;
+ rec->next = NULL;
+ }
+
self->rec_count++;
return rec;
@@ -263,6 +276,30 @@ GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val)
return rec;
}
+GP_MetaRecord *GP_MetaDataCreateRat(GP_MetaData *self, const char *id,
+ int num, int den)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Creating GP_META_RATIONAL id '%s' = %i/%i", id, num, den);
+
+ if (den == 0) {
+ GP_DEBUG(1, "Would not create '%s' with denominator == 0", id);
+ return NULL;
+ }
+
+ rec = GP_MetaDataCreateRecord(self, id);
+
+ if (rec == NULL)
+ return NULL;
+
+ rec->type = GP_META_RATIONAL;
+ rec->val.r.num = num;
+ rec->val.r.den = den;
+
+ return rec;
+}
+
GP_MetaRecord *GP_MetaDataCreateDouble(GP_MetaData *self, const char *id,
double val)
{
@@ -282,7 +319,7 @@ GP_MetaRecord *GP_MetaDataCreateDouble(GP_MetaData *self, const char *id,
}
GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
- const char *str, int dup)
+ const char *str, int len, int dup)
{
GP_MetaRecord *rec;
@@ -294,8 +331,13 @@ GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
return NULL;
if (dup) {
- size_t size = strlen(str) + 1;
+ size_t size;
char *s;
+
+ if (len == 0)
+ size = strlen(str) + 1;
+ else
+ size = len + 1;
/* Play safe with aligment */
if (size % 8)
@@ -303,7 +345,8 @@ GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
//TODO: allocation error
s = do_alloc(self, size);
- strcpy(s, str);
+ strncpy(s, str, size - 1);
+ s[size - 1] = '0';
str = s;
}
diff --git a/libs/loaders/GP_MetaExif.c b/libs/loaders/GP_MetaExif.c
new file mode 100644
index 0000000..e6a89bc
--- /dev/null
+++ b/libs/loaders/GP_MetaExif.c
@@ -0,0 +1,487 @@
+/*****************************************************************************
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "core/GP_Debug.h"
+
+#include "GP_MetaData.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 description */
+ IFD_IMAGE_DESCRIPTION = 0x010e,
+ /* camera manufacturer */
+ IFD_MAKE = 0x010f,
+ /* camera model */
+ IFD_MODEL = 0x0110,
+ /* 1 = upper left, 3 = lower right, 6 = upper right, *
+ * 8 = lower left, 9 = undefined */
+ IFD_ORIENTATION = 0x0112,
+ /* x resolution */
+ IFD_X_RESOLUTION = 0x011a,
+ /* y resolution */
+ IFD_Y_RESOLUTION = 0x011b,
+ /* 1 = no unit, 2 = inch, 3 = centimeter */
+ IFD_RESOLUTION_UNIT = 0x0128,
+ /* software */
+ IFD_SOFTWARE = 0x0131,
+ /* date time */
+ 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 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,
+};
+
+struct IFD_tag {
+ uint16_t tag;
+ const char *name;
+ uint16_t format;
+ /* 0 == not defined */
+ uint32_t num_components;
+};
+
+/* These are sorted by tag */
+static const struct IFD_tag IFD_tags[] = {
+ /* TAGs from IFD0 */
+ {IFD_IMAGE_DESCRIPTION, "Image Description", IFD_ASCII_STRING, 0},
+ {IFD_MAKE, "Camera Manufacturer", IFD_ASCII_STRING, 0},
+ {IFD_MODEL, "Camera 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_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, 2},
+ {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},
+};
+
+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 buf_char(void *buf, size_t pos, size_t buf_len)
+{
+ if (pos >= buf_len) {
+ GP_DEBUG(1, "Byte position %zu out of buffer len %zu", pos, buf_len);
+ return -1;
+ }
+
+ return ((char*)buf)[pos];
+}
+
+#define GET_16(res, buf, pos, buf_len, swap) do { + if (pos + 1 >= buf_len) { + GP_DEBUG(1, "2-byte position %zu out of buffer len %zu", + (size_t)pos, buf_len); + return -1; + } + + if (swap) + res = ((uint8_t*)buf)[pos]<<8 | ((uint8_t*)buf)[pos+1]; + else + res = ((uint8_t*)buf)[pos] | ((uint8_t*)buf)[pos+1]<<8; +} while (0)
+
+#define GET_32(res, buf, pos, buf_len, swap) do { + if (pos + 3 >= buf_len) { + GP_DEBUG(1, "4-byte position %zu out of buffer len %zu", + (size_t)pos, buf_len); + return -1; + } + + if (swap) + res = (((uint8_t*)buf)[pos])<<24 | (((uint8_t*)buf)[pos+1])<<16 | + (((uint8_t*)buf)[pos+2])<<8 | ((uint8_t*)buf)[pos+3]; + else + res = ((uint8_t*)buf)[pos] | (((uint8_t*)buf)[pos+1])<<8 | + (((uint8_t*)buf)[pos+2])<<16 | (((uint8_t*)buf)[pos+3])<<24; +} while (0)
+
+#define GET_16_INC(res, buf, pos, buf_len, swap) do { + GET_16(res, buf, pos, buf_len, swap); + pos += 2; +} while (0)
+
+#define GET_32_INC(res, buf, pos, buf_len, swap) do { + GET_32(res, buf, pos, buf_len, swap); + pos += 4; +} while (0)
+
+static const char *get_string(void *buf, size_t buf_len,
+ uint32_t num_comp, uint32_t *val)
+{
+ if (num_comp <= 4)
+ return (const char*)val;
+
+ if (*val + num_comp >= buf_len) {
+ GP_DEBUG(1, "String out of buffer offset 0x%08x length %u",
+ *val, num_comp);
+ return NULL;
+ }
+
+ return ((const char*)buf) + *val;
+}
+
+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 void load_tag(GP_MetaData *self, void *buf, size_t buf_len, int swap,
+ 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_DEBUG(1, "Skipping unknown IFD tag 0x%02x", tag);
+ return;
+ }
+
+ if (res->format != format) {
+ GP_DEBUG(1, "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_DEBUG(1, "Unexpected tag '%s' num_components %u expected %u",
+ res->name, num_comp, res->num_components);
+ }
+
+ switch (format) {
+ case IFD_ASCII_STRING: {
+ const char *addr = get_string(buf, buf_len, num_comp, &val);
+
+ if (addr == NULL)
+ return;
+
+ GP_MetaDataCreateString(self, res->name, addr, num_comp, 1);
+ } break;
+ case IFD_UNSIGNED_SHORT:
+ if (num_comp == 1)
+ GP_MetaDataCreateInt(self, res->name, val);
+ else
+ goto unused;
+ break;
+ case IFD_UNSIGNED_RATIONAL:
+ case IFD_SIGNED_RATIONAL:
+ if (num_comp == 1)
+ GP_MetaDataCreateRat(self, res->name,
+ rat_num(buf, val, buf_len, swap),
+ rat_den(buf, val, buf_len, swap));
+ else
+ goto unused;
+ break;
+ unused:
+ default:
+ GP_DEBUG(1, "Unused record '%s' format '%s' (0x%02x)", res->name,
+ IFD_format_name(format), format);
+ }
+}
+
+/*
+ * Loads IFD block.
+ */
+static int load_IFD(GP_MetaData *self, void *buf, size_t buf_len,
+ uint32_t IFD_offset, int swap)
+{
+ uint16_t IFD_entries_count;
+
+ GET_16_INC(IFD_entries_count, buf, IFD_offset, buf_len, swap);
+
+ GP_DEBUG(2, "-- IFD Offset 0x%08x Entries 0x%04x --",
+ IFD_offset, IFD_entries_count);
+
+ int i;
+
+ for (i = 0; i < IFD_entries_count; i++) {
+ uint16_t tag, format;
+ uint32_t num_components, val;
+
+ GET_16_INC(tag, buf, IFD_offset, buf_len, swap);
+ GET_16_INC(format, buf, IFD_offset, buf_len, swap);
+ GET_32_INC(num_components, buf, IFD_offset, buf_len, swap);
+ GET_32_INC(val, buf, IFD_offset, buf_len, swap);
+
+ GP_DEBUG(3, "IFD Entry tag 0x%04x format (0x%04x) components 0x%08x val 0x%08x",
+ tag, format, num_components, val);
+
+ GP_DEBUG(3, "IFD Entry tag '%s' format '%s'",
+ IFD_tag_name(tag), IFD_format_name(format));
+
+ if (tag == IFD_EXIF_OFFSET)
+ load_IFD(self, buf, buf_len, val, swap);
+ else
+ load_tag(self, buf, buf_len, swap, tag, format, num_components, 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;
+}
+
+/* Offset from the start of the Exit to TIFF header */
+#define TIFF_OFFSET 6
+
+int GP_MetaDataFromExif(GP_MetaData *self, void *buf, size_t buf_len)
+{
+ static int swap = 0;
+ int c1, c2;
+
+ if (buf_char(buf, 0, buf_len) != 'E' ||
+ buf_char(buf, 1, buf_len) != 'x' ||
+ buf_char(buf, 2, buf_len) != 'i' ||
+ buf_char(buf, 3, buf_len) != 'f' ||
+ buf_char(buf, 4, buf_len) != 0 ||
+ buf_char(buf, 5, buf_len) != 0) {
+ GP_DEBUG(1, "Missing ASCII 'Exif
+ "the start of the buffer");
+ return 1;
+ }
+
+ if (((c1 = buf_char(buf, 6, buf_len)) !=
+ (c2 = buf_char(buf, 7, buf_len)))
+ || (c1 != 'I' && c1 != 'M')) {
+ GP_DEBUG(1, "Expected II or MM got %x%x, corrupt header?",
+ c1, c2);
+ return 1;
+ }
+
+ swap = (c1 == 'M');
+
+ GP_DEBUG(2, "TIFF aligment is '%c%c' swap = %i", c1, c1, swap);
+
+ uint16_t tag;
+
+ GET_16(tag, buf, 8, buf_len, swap);
+
+ if (tag != 0x002a) {
+ GP_DEBUG(1, "Expected TIFF TAG '0x002a' got '0x%04x'", tag);
+ return 1;
+ }
+
+ uint32_t IFD_offset;
+
+ GET_32(IFD_offset, buf, 10, buf_len, swap);
+
+ GP_DEBUG(2, "IFD offset is 0x%08x", IFD_offset);
+
+ /* The offset starts from the II or MM */
+ load_IFD(self, (char*)buf + TIFF_OFFSET, buf_len - TIFF_OFFSET, IFD_offset, swap);
+
+
+ return 0;
+}
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 5f324aa..2d099fd 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -267,7 +267,7 @@ static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *dat
else
unit_name = "unknown";
- GP_MetaDataCreateString(data, "res_unit", unit_name, 0);
+ GP_MetaDataCreateString(data, "res_unit", unit_name, 0, 0);
}
png_timep mod_time;
@@ -302,7 +302,7 @@ static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *dat
char buf[GP_META_RECORD_ID_MAX];
snprintf(buf, GP_META_RECORD_ID_MAX, "text:%s", text_ptr[i].key);
- GP_MetaDataCreateString(data, buf, text_ptr[i].text, 1);
+ GP_MetaDataCreateString(data, buf, text_ptr[i].text, 0, 1);
}
}
}
http://repo.or.cz/w/gfxprim.git/commit/d0497f46eebcf460bd1377686f1f62188047…
commit d0497f46eebcf460bd1377686f1f6218804743b4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jun 1 16:58:34 2012 +0200
spiv: Rewrite the backend polling loop.
* Which is still hacky, but at least works now
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 9862049..6e03531 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -388,18 +388,88 @@ static void init_backend(const char *backend_opts)
}
}
+static int alarm_fired = 0;
+
+static void alarm_handler(int signo)
+{
+ alarm_fired = 1;
+}
+
+static int wait_for_event(int sleep_msec)
+{
+ static int sleep_msec_count = 0;
+ static int alarm_set = 0;
+
+ if (sleep_msec < 0) {
+ GP_BackendPoll(backend);
+ return 0;
+ }
+
+ /* We can't sleep on backend fd, because the backend doesn't export it. */
+ if (backend->fd < 0) {
+ GP_BackendPoll(backend);
+ usleep(10000);
+
+ sleep_msec_count += 10;
+
+ if (sleep_msec_count >= sleep_msec) {
+ sleep_msec_count = 0;
+ return 1;
+ }
+
+ return 0;
+ }
+
+ /* Initalize select */
+ fd_set rfds;
+ FD_ZERO(&rfds);
+
+ FD_SET(backend->fd, &rfds);
+
+ if (!alarm_set) {
+ signal(SIGALRM, alarm_handler);
+ alarm(sleep_msec / 1000);
+ alarm_fired = 0;
+ alarm_set = 1;
+ }
+
+ struct timeval tv = {.tv_sec = sleep_msec / 1000,
+ .tv_usec = (sleep_msec % 1000) * 1000};
+
+ int ret = select(backend->fd + 1, &rfds, NULL, NULL, &tv);
+
+ switch (ret) {
+ case -1:
+ if (errno == EINTR)
+ return 1;
+
+ GP_BackendExit(backend);
+ exit(1);
+ break;
+ case 0:
+ if (alarm_fired) {
+ alarm_set = 0;
+ return 1;
+ }
+
+ return 0;
+ break;
+ default:
+ GP_BackendPoll(backend);
+ return 0;
+ }
+}
+
int main(int argc, char *argv[])
{
- GP_InputDriverLinux *drv = NULL;
GP_Context *context = NULL;
- const char *input_dev = NULL;
const char *backend_opts = "X11";
int sleep_sec = -1;
struct loader_params params = {NULL, 0, 0, 0, .img = NULL};
int opt, debug_level = 0;
GP_PixelType emul_type = GP_PIXEL_UNKNOWN;
- while ((opt = getopt(argc, argv, "b:cd:e:fIi:Ps:r:")) != -1) {
+ while ((opt = getopt(argc, argv, "b:cd:e:fIPs:r:")) != -1) {
switch (opt) {
case 'I':
params.show_info = 1;
@@ -407,9 +477,6 @@ int main(int argc, char *argv[])
case 'P':
params.show_progress = 1;
break;
- case 'i':
- input_dev = optarg;
- break;
case 'f':
dithering = 1;
break;
@@ -447,16 +514,6 @@ int main(int argc, char *argv[])
GP_SetDebugLevel(debug_level);
- if (input_dev != NULL) {
- drv = GP_InputDriverLinuxOpen(input_dev);
-
- if (drv == NULL) {
- fprintf(stderr, "Failed to initalize input device '%s'n",
- input_dev);
- return 1;
- }
- }
-
signal(SIGINT, sighandler);
signal(SIGSEGV, sighandler);
signal(SIGBUS, sighandler);
@@ -482,56 +539,17 @@ int main(int argc, char *argv[])
params.show_progress_once = 1;
show_image(¶ms, argv[argf]);
-
- for (;;) {
- int ret;
-
- if (drv != NULL) {
- /* Initalize select */
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(drv->fd, &rfds);
- struct timeval tv = {.tv_sec = sleep_sec, .tv_usec = 0};
- struct timeval *tvp = sleep_sec != -1 ? &tv : NULL;
-
- ret = select(drv->fd + 1, &rfds, NULL, NULL, tvp);
- tv.tv_sec = sleep_sec;
-
- switch (ret) {
- case -1:
- GP_BackendExit(backend);
- return 0;
- break;
- case 0:
- argn++;
- if (argn >= argc)
- argn = argf;
-
- show_image(¶ms, argv[argn]);
- break;
- default:
- while (GP_InputDriverLinuxRead(drv));
- }
-
- FD_SET(drv->fd, &rfds);
- } else {
- if (sleep_sec != -1) {
- sleep(sleep_sec);
-
- argn++;
- if (argn >= argc)
- argn = argf;
-
- show_image(¶ms, argv[argn]);
- }
+ for (;;) {
+ /* wait for event or a timeout */
+ if (wait_for_event(sleep_sec * 1000)) {
+ argn++;
+ if (argn >= argc)
+ argn = argf;
+
+ show_image(¶ms, argv[argn]);
}
- if (backend->Poll)
- GP_BackendPoll(backend);
-
- usleep(1000);
-
/* Read and parse events */
GP_Event ev;
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/meta_data.c | 4 +-
demos/spiv/spiv.c | 144 +++++++------
include/loaders/GP_MetaData.h | 23 ++-
libs/loaders/GP_JPG.c | 17 +-
libs/loaders/GP_MetaData.c | 57 +++++-
libs/loaders/GP_MetaExif.c | 487 +++++++++++++++++++++++++++++++++++++++++
libs/loaders/GP_PNG.c | 4 +-
7 files changed, 647 insertions(+), 89 deletions(-)
create mode 100644 libs/loaders/GP_MetaExif.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