Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
[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
[repo.or.cz] gfxprim.git branch master updated: 9dc7c882ccd99e87e0146b367037d89ceb98aef1
by metan 28 May '12
by metan 28 May '12
28 May '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 9dc7c882ccd99e87e0146b367037d89ceb98aef1 (commit)
from 4939286022a028a66c62ee082748384a908fed37 (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/9dc7c882ccd99e87e0146b367037d89ceb98…
commit 9dc7c882ccd99e87e0146b367037d89ceb98aef1
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 19:11:21 2012 +0200
filters: Clamp Floyd-Steinberg result pixels.
Visible owerflows were found on RGB565
diff --git a/libs/filters/GP_FloydSteinberg.gen.c.t b/libs/filters/GP_FloydSteinberg.gen.c.t
index 9886945..df22cfb 100644
--- a/libs/filters/GP_FloydSteinberg.gen.c.t
+++ b/libs/filters/GP_FloydSteinberg.gen.c.t
@@ -1,4 +1,4 @@
-%% extends "base.c.t"
+%% extends "common.c.t"
{% block descr %}Floyd Steinberg dithering RGB888 -> any pixel{% endblock %}
@@ -62,7 +62,6 @@ int GP_FilterFloydSteinberg_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src, G
val_{{ c[0] }} += errors_{{ c[0] }}[y%2][x];
float err_{{ c[0] }} = val_{{ c[0] }};
-
%% if pt.is_gray()
GP_Pixel res_{{ c[0] }} = {{ 2 ** c[2] - 1}} * val_{{ c[0] }} / (3 * 255);
err_{{ c[0] }} -= res_{{ c[0] }} * (3 * 255) / {{ 2 ** c[2] - 1}};
@@ -72,6 +71,8 @@ int GP_FilterFloydSteinberg_RGB888_to_{{ pt.name }}_Raw(const GP_Context *src, G
%% endif
{{ distribute_error("errors_%s"|format(c[0]), 'x', 'y', '(GP_Coord)src->w', 'err_%s'|format(c[0])) }}
+
+ {{ clamp_val("res_%s"|format(c[0]), c[2]) }}
%% endfor
%% if pt.is_gray()
diff --git a/pylib/templates/common.c.t b/pylib/templates/common.c.t
index d3fcbd8..785174d 100644
--- a/pylib/templates/common.c.t
+++ b/pylib/templates/common.c.t
@@ -14,3 +14,10 @@
* Converts channels to params
*/
{% macro expand_chanslist(chlist) %} {{ chlist[0][0] }}{% for i in chlist %}, {{ i[0] }}{% endfor %}{% endmacro %}
+
+/*
+ * Clamps n-bits value
+ */
+%%macro clamp_val(val, bits)
+if ({{ val }} > {{ 2 ** bits - 1 }}) {{ val }} = {{ 2 ** bits - 1}};
+%% endmacro
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_FloydSteinberg.gen.c.t | 5 +++--
pylib/templates/common.c.t | 7 +++++++
2 files changed, 10 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 4939286022a028a66c62ee082748384a908fed37
by metan 28 May '12
by metan 28 May '12
28 May '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 4939286022a028a66c62ee082748384a908fed37 (commit)
from 0d68cb863abf1ed7aef032d87f21a0e7193f2986 (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/4939286022a028a66c62ee082748384a908f…
commit 4939286022a028a66c62ee082748384a908fed37
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 15:43:10 2012 +0200
loaders: Start with meta-data support for JPEG.
diff --git a/include/loaders/GP_JPG.h b/include/loaders/GP_JPG.h
index 7cbbd36..73113c4 100644
--- a/include/loaders/GP_JPG.h
+++ b/include/loaders/GP_JPG.h
@@ -32,6 +32,8 @@
#include "core/GP_Context.h"
#include "core/GP_ProgressCallback.h"
+#include "GP_MetaData.h"
+
/*
* Opens up file and checks signature.
*/
@@ -49,6 +51,12 @@ GP_Context *GP_ReadJPG(FILE *f, GP_ProgressCallback *callback);
GP_Context *GP_LoadJPG(const char *src_path, GP_ProgressCallback *callback);
/*
+ * Loads JPEG meta-data, called markers in JPEG terminology.
+ */
+int GP_ReadJPGMetaData(FILE *f, GP_MetaData *data);
+int GP_LoadJPGMetaData(const char *src_path, GP_MetaData *data);
+
+/*
* Saves JPG to a file.
*/
int GP_SaveJPG(const GP_Context *src, const char *dst_path,
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 6011b8f..f600b57 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -205,6 +205,103 @@ GP_Context *GP_LoadJPG(const char *src_path, GP_ProgressCallback *callback)
return res;
}
+#define JPEG_COM_MAX 128
+
+static void read_jpg_metadata(struct jpeg_decompress_struct *cinfo,
+ GP_MetaData *data)
+{
+ jpeg_saved_marker_ptr marker;
+
+ 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);
+ }
+ break;
+ case JPEG_APP0:
+ GP_DEBUG(0, "TODO: JFIF");
+ break;
+ case JPEG_APP0 + 1:
+ GP_DEBUG(0, "TODO: EXIF");
+ break;
+ }
+ }
+}
+
+static void save_jpg_markers(struct jpeg_decompress_struct *cinfo)
+{
+ /* Comment marker */
+ jpeg_save_markers(cinfo, JPEG_COM, JPEG_COM_MAX);
+
+ /* APP0 marker = JFIF data */
+ jpeg_save_markers(cinfo, JPEG_APP0 + 1, 0xffff);
+
+ /* APP1 marker = Exif data */
+ jpeg_save_markers(cinfo, JPEG_APP0 + 1, 0xffff);
+}
+
+int GP_ReadJPGMetaData(FILE *f, GP_MetaData *data)
+{
+ struct jpeg_decompress_struct cinfo;
+ struct my_jpg_err my_err;
+ int err;
+
+ cinfo.err = jpeg_std_error(&my_err.error_mgr);
+ my_err.error_mgr.error_exit = my_error_exit;
+
+ if (setjmp(my_err.setjmp_buf)) {
+ err = EIO;
+ goto err1;
+ }
+
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, f);
+
+ save_jpg_markers(&cinfo);
+
+ jpeg_read_header(&cinfo, TRUE);
+
+ GP_DEBUG(1, "Have %s JPEG size %ux%u %i channels",
+ get_colorspace(cinfo.jpeg_color_space),
+ cinfo.image_width, cinfo.image_height,
+ cinfo.num_components);
+
+ read_jpg_metadata(&cinfo, data);
+
+// jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ return 0;
+err1:
+ jpeg_destroy_decompress(&cinfo);
+ errno = err;
+ return 1;
+}
+
+int GP_LoadJPGMetaData(const char *src_path, GP_MetaData *data)
+{
+ FILE *f;
+ int ret;
+
+ if (GP_OpenJPG(src_path, &f))
+ return 1;
+
+ ret = GP_ReadJPGMetaData(f, data);
+
+ fclose(f);
+
+ return ret;
+}
+
int GP_SaveJPG(const GP_Context *src, const char *dst_path,
GP_ProgressCallback *callback)
{
@@ -326,6 +423,19 @@ GP_Context *GP_LoadJPG(const char GP_UNUSED(*src_path),
return NULL;
}
+int GP_ReadJPGMetaData(FILE GP_UNUSED(*f), GP_MetaData GP_UNUSED(*data))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+int GP_LoadJPGMetaData(const char GP_UNUSED(*src_path),
+ GP_MetaData GP_UNUSED(*data))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
int GP_SaveJPG(const GP_Context GP_UNUSED(*src),
const char GP_UNUSED(*dst_path),
GP_ProgressCallback GP_UNUSED(*callback))
-----------------------------------------------------------------------
Summary of changes:
include/loaders/GP_JPG.h | 8 +++
libs/loaders/GP_JPG.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 0d68cb863abf1ed7aef032d87f21a0e7193f2986
by metan 28 May '12
by metan 28 May '12
28 May '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 0d68cb863abf1ed7aef032d87f21a0e7193f2986 (commit)
via ce2eb53e48956d4f98fe814c10459c4340c077a9 (commit)
via 056c9ac7bfef008374277b3aba84568742109d51 (commit)
via 6874eb6694b57df3bc5c7d1a06688be72524e448 (commit)
from cca1a95d0c61b096110045f796c86ab02703362f (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/0d68cb863abf1ed7aef032d87f21a0e7193f…
commit 0d68cb863abf1ed7aef032d87f21a0e7193f2986
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 14:14:32 2012 +0200
loaders: Make use of double metadata type.
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 7602fe7..5f324aa 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -284,8 +284,8 @@ static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *dat
double width, height;
if (png_get_sCAL(png, png_info, &unit, &width, &height)) {
- GP_MetaDataCreateInt(data, "width", width * 1000);
- GP_MetaDataCreateInt(data, "height", height * 1000);
+ GP_MetaDataCreateDouble(data, "width", width);
+ GP_MetaDataCreateDouble(data, "height", height);
GP_MetaDataCreateInt(data, "unit", unit);
}
http://repo.or.cz/w/gfxprim.git/commit/ce2eb53e48956d4f98fe814c10459c4340c0…
commit ce2eb53e48956d4f98fe814c10459c4340c077a9
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 14:09:07 2012 +0200
demos: Edhance png meta-data dumper example.
diff --git a/demos/c_simple/meta_data_png.c b/demos/c_simple/meta_data_png.c
index 3303bed..9f6543b 100644
--- a/demos/c_simple/meta_data_png.c
+++ b/demos/c_simple/meta_data_png.c
@@ -32,24 +32,36 @@
#include <GP.h>
+#define SEP +"-----------------------------------------------------------------------------"
+
int main(int argc, char *argv[])
{
- GP_MetaData *data = GP_MetaDataCreate(10);
+ GP_MetaData *data = GP_MetaDataCreate(20);
+ int i;
- if (argc != 2) {
- fprintf(stderr, "Takes an image as an parametern");
+ if (argc < 2) {
+ fprintf(stderr, "Takes an image(s) as parameter(s)n");
return 1;
}
//GP_SetDebugLevel(10);
- if (GP_LoadPNGMetaData(argv[1], data)) {
- fprintf(stderr, "Failed to read '%s' meta-data: %sn",
- argv[1], strerror(errno));
- return 1;
+ for (i = 1; i < argc; i++) {
+ puts(SEP);
+ printf("Opening '%s'n", argv[i]);
+
+ GP_MetaDataClear(data);
+
+ if (GP_LoadPNGMetaData(argv[i], data)) {
+ fprintf(stderr, "Failed to read '%s' meta-data: %sn",
+ argv[1], strerror(errno));
+ } else {
+ GP_MetaDataPrint(data);
+ }
}
-
- GP_MetaDataPrint(data);
+
+ puts(SEP);
return 0;
}
http://repo.or.cz/w/gfxprim.git/commit/056c9ac7bfef008374277b3aba8456874210…
commit 056c9ac7bfef008374277b3aba84568742109d51
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 14:08:47 2012 +0200
demos: Add forgotten meta_data example.
diff --git a/demos/c_simple/meta_data.c b/demos/c_simple/meta_data.c
new file mode 100644
index 0000000..b5f2905
--- /dev/null
+++ b/demos/c_simple/meta_data.c
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Meta-data storage operations example.
+
+ Meta-data storage is used to store image meta-data (if present) such as
+ physical size, creation date, etc...
+
+ Meta-data storage is basically an typed dictionary.
+
+ This example shows low-level interface to GP_MetaData structure.
+
+ */
+
+#include <stdio.h>
+
+#include <GP.h>
+
+int main(void)
+{
+ GP_MetaData *data = GP_MetaDataCreate(10);
+
+ //GP_SetDebugLevel(10);
+
+ if (data == NULL)
+ return 1;
+
+ /*
+ * Create integer
+ *
+ * May fail, if there is allready record with id 'dpi' or
+ * if there is no space left.
+ */
+ GP_MetaDataCreateInt(data, "dpi", 300);
+
+ /*
+ * Create an string.
+ *
+ * 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_MetaDataCreateDouble(data, "pi", 3.141592);
+
+ const char *ret;
+
+ ret = GP_MetaDataGetString(data, "comment");
+
+ if (ret != NULL)
+ printf("Found string 'comment' = '%s'n", ret);
+ else
+ printf("ERROR: cannot cound string 'comment'n");
+
+ printf("n");
+
+ /*
+ * Print all meta-data
+ */
+ GP_MetaDataPrint(data);
+
+ return 0;
+}
http://repo.or.cz/w/gfxprim.git/commit/6874eb6694b57df3bc5c7d1a06688be72524…
commit 6874eb6694b57df3bc5c7d1a06688be72524e448
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 14:08:04 2012 +0200
loaders: Add meta-data clear method and double type.
diff --git a/include/loaders/GP_MetaData.h b/include/loaders/GP_MetaData.h
index 2820ee0..4da30f1 100644
--- a/include/loaders/GP_MetaData.h
+++ b/include/loaders/GP_MetaData.h
@@ -28,10 +28,12 @@
enum GP_MetaType {
GP_META_INT,
GP_META_STRING,
+ GP_META_DOUBLE,
};
union GP_MetaValue {
int i;
+ double d;
const char *str;
};
@@ -53,6 +55,11 @@ typedef struct GP_MetaData GP_MetaData;
GP_MetaData *GP_MetaDataCreate(unsigned int expected_records);
/*
+ * Clears meta-data storage.
+ */
+void GP_MetaDataClear(GP_MetaData *self);
+
+/*
* Destroys metadata (frees all alocated memory).
*/
void GP_MetaDataDestroy(GP_MetaData *self);
@@ -92,6 +99,12 @@ GP_MetaRecord *GP_MetaDataCreateRecord(GP_MetaData *self, const char *id);
GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val);
/*
+ * Creates an double record and returns pointer to it.
+ */
+GP_MetaRecord *GP_MetaDataCreateDouble(GP_MetaData *self, const char *id,
+ double val);
+
+/*
* Creates an string record and returns pointer to it.
*
* If dup is set to 1, the string is duplicated inside of the MetaData
diff --git a/libs/loaders/GP_MetaData.c b/libs/loaders/GP_MetaData.c
index b0fcdf8..e62af18 100644
--- a/libs/loaders/GP_MetaData.c
+++ b/libs/loaders/GP_MetaData.c
@@ -70,6 +70,16 @@ GP_MetaData *GP_MetaDataCreate(unsigned int expected_records)
return data;
}
+void GP_MetaDataClear(GP_MetaData *self)
+{
+ GP_DEBUG(1, "Clearing MetaData %p with %u records",
+ self, self->rec_count);
+
+ self->root = NULL;
+ self->rec_count = 0;
+ self->free = self->size;
+}
+
void GP_MetaDataDestroy(GP_MetaData *self)
{
GP_DEBUG(1, "Destroying MetaData %p", self);
@@ -92,6 +102,9 @@ void GP_MetaDataPrint(GP_MetaData *self)
case GP_META_STRING:
printf("'%s'n", rec->val.str);
break;
+ case GP_META_DOUBLE:
+ printf("%lfn", rec->val.d);
+ break;
}
}
}
@@ -185,6 +198,31 @@ int GP_MetaDataGetInt(GP_MetaData *self, const char *id, int *res)
return 0;
}
+int GP_MetaDataGetDouble(GP_MetaData *self, const char *id, double *res)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Looking for GP_META_DOUBLE id '%s'", id);
+
+ rec = record_lookup(self, id, do_hash(id));
+
+ if (rec == NULL) {
+ GP_DEBUG(3, "Record id '%s' not found", id);
+ return 1;
+ }
+
+ if (rec->type != GP_META_DOUBLE) {
+ GP_DEBUG(3, "Record id '%s' has wrong type", id);
+ return 1;
+ }
+
+ *res = rec->val.d;
+
+ GP_DEBUG(3, "Found GP_META_DOUBLE id '%s' = %lf", id, *res);
+
+ return 0;
+}
+
const char *GP_MetaDataGetString(GP_MetaData *self, const char *id)
{
GP_MetaRecord *rec;
@@ -225,6 +263,24 @@ GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val)
return rec;
}
+GP_MetaRecord *GP_MetaDataCreateDouble(GP_MetaData *self, const char *id,
+ double val)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Creating GP_META_DOUBLE id '%s' = %lf", id, val);
+
+ rec = GP_MetaDataCreateRecord(self, id);
+
+ if (rec == NULL)
+ return NULL;
+
+ rec->type = GP_META_DOUBLE;
+ rec->val.d = val;
+
+ return rec;
+}
+
GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
const char *str, int dup)
{
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/{meta_data_png.c => meta_data.c} | 55 +++++++++++++++++-----
demos/c_simple/meta_data_png.c | 30 +++++++++----
include/loaders/GP_MetaData.h | 13 +++++
libs/loaders/GP_MetaData.c | 56 +++++++++++++++++++++++
libs/loaders/GP_PNG.c | 4 +-
5 files changed, 134 insertions(+), 24 deletions(-)
copy demos/c_simple/{meta_data_png.c => meta_data.c} (63%)
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: cca1a95d0c61b096110045f796c86ab02703362f
by metan 28 May '12
by metan 28 May '12
28 May '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 cca1a95d0c61b096110045f796c86ab02703362f (commit)
from ed03e7bc0d0825a97e73887be30e768cc0f8aeec (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/cca1a95d0c61b096110045f796c86ab02703…
commit cca1a95d0c61b096110045f796c86ab02703362f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 00:35:19 2012 +0200
loaders: PNG More work on metadata.
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 2cef50d..7602fe7 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -270,6 +270,17 @@ static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *dat
GP_MetaDataCreateString(data, "res_unit", unit_name, 0);
}
+ png_timep mod_time;
+
+ if (png_get_tIME(png, png_info, &mod_time)) {
+ GP_MetaDataCreateInt(data, "mod_sec", mod_time->second);
+ GP_MetaDataCreateInt(data, "mod_min", mod_time->minute);
+ GP_MetaDataCreateInt(data, "mod_hour", mod_time->hour);
+ GP_MetaDataCreateInt(data, "mod_day", mod_time->day);
+ GP_MetaDataCreateInt(data, "mod_mon", mod_time->month);
+ GP_MetaDataCreateInt(data, "mod_year", mod_time->year);
+ }
+
double width, height;
if (png_get_sCAL(png, png_info, &unit, &width, &height)) {
@@ -277,6 +288,23 @@ static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *dat
GP_MetaDataCreateInt(data, "height", height * 1000);
GP_MetaDataCreateInt(data, "unit", unit);
}
+
+ png_textp text_ptr;
+ int text_cnt;
+
+ if (png_get_text(png, png_info, &text_ptr, &text_cnt)) {
+ int i;
+
+ for (i = 0; i < text_cnt; i++) {
+
+ if (text_ptr[i].compression != PNG_TEXT_COMPRESSION_NONE)
+ continue;
+
+ 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);
+ }
+ }
}
int GP_ReadPNGMetaData(FILE *f, GP_MetaData *data)
-----------------------------------------------------------------------
Summary of changes:
libs/loaders/GP_PNG.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: ed03e7bc0d0825a97e73887be30e768cc0f8aeec
by metan 28 May '12
by metan 28 May '12
28 May '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 ed03e7bc0d0825a97e73887be30e768cc0f8aeec (commit)
via a2efbefa0d3cf0e3174dee1d95739d9872978ed9 (commit)
via 3e5a833f10aa54ddd8b7218e06ee6ec370e05ae1 (commit)
via 2f882b02d5ff65219b1702a4e880582afeb185c4 (commit)
via 5d07526c70845eae42935de4a03ec9d90bf8a019 (commit)
from 8aab7a816e45ba2fcfd256ab48bb36aa350c98f9 (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/ed03e7bc0d0825a97e73887be30e768cc0f8…
commit ed03e7bc0d0825a97e73887be30e768cc0f8aeec
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon May 28 00:01:18 2012 +0200
examples: Add meta data example.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index 7204831..c03f374 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
+ virtual_backend_example meta_data meta_data_png
include $(TOPDIR)/pre.mk
include $(TOPDIR)/app.mk
diff --git a/demos/c_simple/meta_data_png.c b/demos/c_simple/meta_data_png.c
new file mode 100644
index 0000000..3303bed
--- /dev/null
+++ b/demos/c_simple/meta_data_png.c
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * 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> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Read png meta-data and print them into stdout.
+
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <GP.h>
+
+int main(int argc, char *argv[])
+{
+ GP_MetaData *data = GP_MetaDataCreate(10);
+
+ if (argc != 2) {
+ fprintf(stderr, "Takes an image as an parametern");
+ return 1;
+ }
+
+ //GP_SetDebugLevel(10);
+
+ if (GP_LoadPNGMetaData(argv[1], data)) {
+ fprintf(stderr, "Failed to read '%s' meta-data: %sn",
+ argv[1], strerror(errno));
+ return 1;
+ }
+
+ GP_MetaDataPrint(data);
+
+ return 0;
+}
http://repo.or.cz/w/gfxprim.git/commit/a2efbefa0d3cf0e3174dee1d95739d987297…
commit a2efbefa0d3cf0e3174dee1d95739d9872978ed9
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun May 27 23:29:04 2012 +0200
loaders: PNG: add experimental support for metadata.
diff --git a/include/loaders/GP_PNG.h b/include/loaders/GP_PNG.h
index b866b7d..3a8f2f8 100644
--- a/include/loaders/GP_PNG.h
+++ b/include/loaders/GP_PNG.h
@@ -32,6 +32,8 @@
#include "core/GP_ProgressCallback.h"
#include "core/GP_Context.h"
+#include "GP_MetaData.h"
+
/*
* The possible errno values:
*
@@ -65,6 +67,12 @@ GP_Context *GP_ReadPNG(FILE *f, GP_ProgressCallback *callback);
GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback);
/*
+ * Loads png meta-data.
+ */
+int GP_ReadPNGMetaData(FILE *f, GP_MetaData *data);
+int GP_LoadPNGMetaData(const char *src_path, GP_MetaData *data);
+
+/*
* Saves PNG to a file. Zero is returned on succes. Upon failure non-zero is
* returned and errno is filled accordingly.
*/
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 51ea49c..2cef50d 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -246,6 +246,97 @@ GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback)
return res;
}
+static void load_meta_data(png_structp png, png_infop png_info, GP_MetaData *data)
+{
+ double gamma;
+
+ if (png_get_gAMA(png, png_info, &gamma))
+ GP_MetaDataCreateInt(data, "gamma", gamma * 100000);
+
+ png_uint_32 res_x, res_y;
+ int unit;
+
+ if (png_get_pHYs(png, png_info, &res_x, &res_y, &unit)) {
+ GP_MetaDataCreateInt(data, "res_x", res_x);
+ GP_MetaDataCreateInt(data, "res_y", res_y);
+
+ const char *unit_name;
+
+ if (unit == PNG_RESOLUTION_METER)
+ unit_name = "meter";
+ else
+ unit_name = "unknown";
+
+ GP_MetaDataCreateString(data, "res_unit", unit_name, 0);
+ }
+
+ double width, height;
+
+ if (png_get_sCAL(png, png_info, &unit, &width, &height)) {
+ GP_MetaDataCreateInt(data, "width", width * 1000);
+ GP_MetaDataCreateInt(data, "height", height * 1000);
+ GP_MetaDataCreateInt(data, "unit", unit);
+ }
+}
+
+int GP_ReadPNGMetaData(FILE *f, GP_MetaData *data)
+{
+ png_structp png;
+ png_infop png_info = NULL;
+ int err;
+
+ png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+ if (png == NULL) {
+ GP_DEBUG(1, "Failed to allocate PNG read buffer");
+ err = ENOMEM;
+ goto err1;
+ }
+
+ png_info = png_create_info_struct(png);
+
+ if (png_info == NULL) {
+ GP_DEBUG(1, "Failed to allocate PNG info buffer");
+ err = ENOMEM;
+ goto err2;
+ }
+
+ if (setjmp(png_jmpbuf(png))) {
+ GP_DEBUG(1, "Failed to read PNG file :(");
+ //TODO: should we get better error description from libpng?
+ err = EIO;
+ goto err2;
+ }
+
+ png_init_io(png, f);
+ png_set_sig_bytes(png, 8);
+ png_read_info(png, png_info);
+
+ load_meta_data(png, png_info, data);
+
+ return 0;
+err2:
+ png_destroy_read_struct(&png, png_info ? &png_info : NULL, NULL);
+err1:
+ errno = err;
+ return 1;
+}
+
+int GP_LoadPNGMetaData(const char *src_path, GP_MetaData *data)
+{
+ FILE *f;
+ int ret;
+
+ if (GP_OpenPNG(src_path, &f))
+ return 1;
+
+ ret = GP_ReadPNGMetaData(f, data);
+
+ fclose(f);
+
+ return ret;
+}
+
/*
* Maps gfxprim Pixel Type to the PNG format
*/
@@ -448,6 +539,18 @@ GP_Context *GP_LoadPNG(const char GP_UNUSED(*src_path),
return NULL;
}
+int GP_ReadPNGMetaData(FILE GP_UNUSED(*f), GP_MetaData GP_UNUSED(*data))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+int GP_LoadPNGMetaData(const char GP_UNUSED(*src_path), GP_MetaData GP_UNUSED(*data))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
int GP_SavePNG(const GP_Context GP_UNUSED(*src),
const char GP_UNUSED(*dst_path),
GP_ProgressCallback GP_UNUSED(*callback))
http://repo.or.cz/w/gfxprim.git/commit/3e5a833f10aa54ddd8b7218e06ee6ec370e0…
commit 3e5a833f10aa54ddd8b7218e06ee6ec370e05ae1
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun May 27 22:49:38 2012 +0200
loaders: JPG: move the fclose(f) where it belongs.
diff --git a/libs/loaders/GP_JPG.c b/libs/loaders/GP_JPG.c
index 54507b1..6011b8f 100644
--- a/libs/loaders/GP_JPG.c
+++ b/libs/loaders/GP_JPG.c
@@ -177,7 +177,6 @@ GP_Context *GP_ReadJPG(FILE *f, GP_ProgressCallback *callback)
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
- fclose(f);
GP_ProgressCallbackDone(callback);
@@ -186,7 +185,6 @@ err2:
GP_ContextFree(ret);
err1:
jpeg_destroy_decompress(&cinfo);
- fclose(f);
errno = err;
return NULL;
}
@@ -194,11 +192,17 @@ err1:
GP_Context *GP_LoadJPG(const char *src_path, GP_ProgressCallback *callback)
{
FILE *f;
+ GP_Context *res;
if (GP_OpenJPG(src_path, &f))
return NULL;
+
+
+ res = GP_ReadJPG(f, callback);
+
+ fclose(f);
- return GP_ReadJPG(f, callback);
+ return res;
}
int GP_SaveJPG(const GP_Context *src, const char *dst_path,
http://repo.or.cz/w/gfxprim.git/commit/2f882b02d5ff65219b1702a4e880582afeb1…
commit 2f882b02d5ff65219b1702a4e880582afeb185c4
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun May 27 22:43:51 2012 +0200
loaders: Add forgotten libpng cleanup for image loader.
diff --git a/libs/loaders/GP_PNG.c b/libs/loaders/GP_PNG.c
index 742cf46..51ea49c 100644
--- a/libs/loaders/GP_PNG.c
+++ b/libs/loaders/GP_PNG.c
@@ -96,7 +96,7 @@ static const char *interlace_type_name(int interlace)
GP_Context *GP_ReadPNG(FILE *f, GP_ProgressCallback *callback)
{
png_structp png;
- png_infop png_info = NULL;
+ png_infop png_info = NULL;
png_uint_32 w, h;
int depth, color_type, interlace_type;
GP_PixelType pixel_type = GP_PIXEL_UNKNOWN;
@@ -211,21 +211,22 @@ GP_Context *GP_ReadPNG(FILE *f, GP_ProgressCallback *callback)
if (GP_ProgressCallbackReport(callback, y, h, w)) {
GP_DEBUG(1, "Operation aborted");
- err= ECANCELED;
+ err = ECANCELED;
goto err3;
}
}
+
+ png_destroy_read_struct(&png, &png_info, NULL);
GP_ProgressCallbackDone(callback);
-
+
return res;
err3:
GP_ContextFree(res);
err2:
png_destroy_read_struct(&png, png_info ? &png_info : NULL, NULL);
err1:
- fclose(f);
errno = err;
return NULL;
}
@@ -233,11 +234,16 @@ err1:
GP_Context *GP_LoadPNG(const char *src_path, GP_ProgressCallback *callback)
{
FILE *f;
+ GP_Context *res;
if (GP_OpenPNG(src_path, &f))
return NULL;
- return GP_ReadPNG(f, callback);
+ res = GP_ReadPNG(f, callback);
+
+ fclose(f);
+
+ return res;
}
/*
http://repo.or.cz/w/gfxprim.git/commit/5d07526c70845eae42935de4a03ec9d90bf8…
commit 5d07526c70845eae42935de4a03ec9d90bf8a019
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun May 27 22:11:45 2012 +0200
loaders: Create generic metadata storage.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index eeadcf8..7204831 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
+ virtual_backend_example meta_data
include $(TOPDIR)/pre.mk
include $(TOPDIR)/app.mk
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h
index 38633c7..d374f99 100644
--- a/include/loaders/GP_Loaders.h
+++ b/include/loaders/GP_Loaders.h
@@ -44,6 +44,8 @@
#include "GP_JPG.h"
#include "GP_GIF.h"
+#include "GP_MetaData.h"
+
/*
* Tries to load image accordingly to the file extension.
*
diff --git a/include/loaders/GP_MetaData.h b/include/loaders/GP_MetaData.h
new file mode 100644
index 0000000..2820ee0
--- /dev/null
+++ b/include/loaders/GP_MetaData.h
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef LOADERS_METADATA_H
+#define LOADERS_METADATA_H
+
+#define GP_META_RECORD_ID_MAX 16
+
+enum GP_MetaType {
+ GP_META_INT,
+ GP_META_STRING,
+};
+
+union GP_MetaValue {
+ int i;
+ const char *str;
+};
+
+typedef struct GP_MetaRecord {
+ char id[GP_META_RECORD_ID_MAX];
+ unsigned int hash;
+ enum GP_MetaType type;
+ struct GP_MetaRecord *next;
+ union GP_MetaValue val;
+} GP_MetaRecord;
+
+typedef struct GP_MetaData GP_MetaData;
+
+/*
+ * Creates a metadata storage for at least expected_records values.
+ *
+ * Returns NULL if allocation has failed.
+ */
+GP_MetaData *GP_MetaDataCreate(unsigned int expected_records);
+
+/*
+ * Destroys metadata (frees all alocated memory).
+ */
+void GP_MetaDataDestroy(GP_MetaData *self);
+
+/*
+ * Prints metadata into the stdout.
+ */
+void GP_MetaDataPrint(GP_MetaData *self);
+
+/*
+ * Looks for metadata record with id.
+ */
+GP_MetaRecord *GP_MetaDataGetRecord(GP_MetaData *self, const char *id);
+
+/*
+ * Looks for integer metadata with id. Returns 0 on success and res is set to
+ * found metadata value.
+ */
+int GP_MetaDataGetInt(GP_MetaData *self, const char *id, int *res);
+
+/*
+ * Looks for string metadata by id. Returns pointe to found string, or NULL if
+ * there was no such value.
+ */
+const char *GP_MetaDataGetString(GP_MetaData *self, const char *id);
+
+/*
+ * Creates an record and returns pointer to it.
+ *
+ * May return NULL if allocation has failed.
+ */
+GP_MetaRecord *GP_MetaDataCreateRecord(GP_MetaData *self, const char *id);
+
+/*
+ * Creates an integer record and returns pointer to it.
+ */
+GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val);
+
+/*
+ * Creates an string record and returns pointer to it.
+ *
+ * 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);
+
+#endif /* LOADERS_GP_METADATA_H */
diff --git a/libs/loaders/GP_MetaData.c b/libs/loaders/GP_MetaData.c
new file mode 100644
index 0000000..b0fcdf8
--- /dev/null
+++ b/libs/loaders/GP_MetaData.c
@@ -0,0 +1,258 @@
+/*****************************************************************************
+ * 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"
+
+struct GP_MetaData {
+ struct GP_MetaRecord *root;
+ unsigned int rec_count;
+ size_t size;
+ size_t free;
+ char buf[];
+};
+
+static unsigned int do_hash(const char *id)
+{
+ unsigned int hash = 0;
+
+ while (*id != '0') {
+ hash += *id * 1217;
+ hash %= 46309;
+ id += 1;
+ }
+
+ return hash;
+}
+
+GP_MetaData *GP_MetaDataCreate(unsigned int expected_records)
+{
+ GP_MetaData *data;
+ size_t size = expected_records * sizeof(struct GP_MetaRecord);
+
+ GP_DEBUG(1, "Creating MetaData for %u records", expected_records);
+
+ data = malloc(sizeof(struct GP_MetaData) + size);
+
+ if (data == NULL) {
+ GP_DEBUG(1, "Malloc failed :(");
+ return NULL;
+ }
+
+ data->root = NULL;
+ data->rec_count = 0;
+ data->size = size;
+ data->free = size;
+
+ return data;
+}
+
+void GP_MetaDataDestroy(GP_MetaData *self)
+{
+ GP_DEBUG(1, "Destroying MetaData %p", self);
+ free(self);
+}
+
+void GP_MetaDataPrint(GP_MetaData *self)
+{
+ GP_MetaRecord *rec;
+
+ printf("MetaData %u record(s)n", self->rec_count);
+
+ for (rec = self->root; rec != NULL; rec = rec->next) {
+ printf("%-16s: ", rec->id);
+
+ switch (rec->type) {
+ case GP_META_INT:
+ printf("%in", rec->val.i);
+ break;
+ case GP_META_STRING:
+ printf("'%s'n", rec->val.str);
+ break;
+ }
+ }
+}
+
+static GP_MetaRecord *record_lookup(GP_MetaData *self, const char *id,
+ unsigned int hash)
+{
+ GP_MetaRecord *rec;
+
+ for (rec = self->root; rec != NULL; rec = rec->next)
+ if (rec->hash == hash && !strcmp(rec->id, id))
+ return rec;
+
+ return NULL;
+}
+
+static void *do_alloc(struct GP_MetaData *self, size_t size)
+{
+ if (self->free < size) {
+ GP_DEBUG(0, "TODO: storage full");
+ return NULL;
+ }
+
+ void *ret = ((char*)self) + sizeof(struct GP_MetaData) + (self->size - self->free);
+
+ self->free -= size;
+
+ return ret;
+}
+
+static GP_MetaRecord *record_create(GP_MetaData *self, const char *id,
+ unsigned int hash)
+{
+ GP_MetaRecord *rec;
+
+ if (strlen(id) + 1 > GP_META_RECORD_ID_MAX) {
+ GP_DEBUG(0, "Can't create id '%s' longer than %i chars",
+ id, GP_META_RECORD_ID_MAX - 1);
+ return NULL;
+ }
+
+ rec = do_alloc(self, sizeof(struct GP_MetaRecord));
+
+ if (rec == NULL)
+ return NULL;
+
+ strcpy(rec->id, id);
+ rec->hash = hash;
+ rec->next = self->root;
+ self->root = rec;
+
+ self->rec_count++;
+
+ return rec;
+}
+
+GP_MetaRecord *GP_MetaDataCreateRecord(GP_MetaData *self, const char *id)
+{
+ unsigned int hash = do_hash(id);
+
+ if (record_lookup(self, id, hash)) {
+ GP_DEBUG(1, "Trying to create duplicate record id '%s'", id);
+ return NULL;
+ }
+
+ return record_create(self, id, hash);
+}
+
+int GP_MetaDataGetInt(GP_MetaData *self, const char *id, int *res)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Looking for GP_META_INT id '%s'", id);
+
+ rec = record_lookup(self, id, do_hash(id));
+
+ if (rec == NULL) {
+ GP_DEBUG(3, "Record id '%s' not found", id);
+ return 1;
+ }
+
+ if (rec->type != GP_META_INT) {
+ GP_DEBUG(3, "Record id '%s' has wrong type", id);
+ return 1;
+ }
+
+ *res = rec->val.i;
+
+ GP_DEBUG(3, "Found GP_META_INT id '%s' = %i", id, *res);
+
+ return 0;
+}
+
+const char *GP_MetaDataGetString(GP_MetaData *self, const char *id)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Looking for GP_META_STRING id '%s'", id);
+
+ rec = record_lookup(self, id, do_hash(id));
+
+ if (rec == NULL) {
+ GP_DEBUG(3, "Record id '%s' not found", id);
+ return NULL;
+ }
+
+ if (rec->type != GP_META_STRING) {
+ GP_DEBUG(3, "Record id '%s' has wrong type", id);
+ return NULL;
+ }
+
+ GP_DEBUG(3, "Found GP_META_STRING id '%s' = '%s'", id, rec->val.str);
+
+ return rec->val.str;
+}
+
+GP_MetaRecord *GP_MetaDataCreateInt(GP_MetaData *self, const char *id, int val)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Creating GP_META_INT id '%s' = %i", id, val);
+
+ rec = GP_MetaDataCreateRecord(self, id);
+
+ if (rec == NULL)
+ return NULL;
+
+ rec->type = GP_META_INT;
+ rec->val.i = val;
+
+ return rec;
+}
+
+GP_MetaRecord *GP_MetaDataCreateString(GP_MetaData *self, const char *id,
+ const char *str, int dup)
+{
+ GP_MetaRecord *rec;
+
+ GP_DEBUG(2, "Creating GP_META_STRING id '%s' = '%s'", id, str);
+
+ rec = GP_MetaDataCreateRecord(self, id);
+
+ if (rec == NULL)
+ return NULL;
+
+ if (dup) {
+ size_t size = strlen(str) + 1;
+ char *s;
+
+ /* Play safe with aligment */
+ if (size % 8)
+ size += 8 - size % 8;
+
+ //TODO: allocation error
+ s = do_alloc(self, size);
+ strcpy(s, str);
+ str = s;
+ }
+
+ rec->type = GP_META_STRING;
+ rec->val.str = str;
+
+ return rec;
+}
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 2 +-
.../{loaders_example.c => meta_data_png.c} | 20 +-
include/loaders/GP_Loaders.h | 2 +
include/loaders/GP_MetaData.h | 103 ++++++++
include/loaders/GP_PNG.h | 8 +
libs/loaders/GP_JPG.c | 10 +-
libs/loaders/GP_MetaData.c | 258 ++++++++++++++++++++
libs/loaders/GP_PNG.c | 119 +++++++++-
8 files changed, 500 insertions(+), 22 deletions(-)
copy demos/c_simple/{loaders_example.c => meta_data_png.c} (84%)
create mode 100644 include/loaders/GP_MetaData.h
create mode 100644 libs/loaders/GP_MetaData.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
[repo.or.cz] gfxprim.git branch master updated: 8aab7a816e45ba2fcfd256ab48bb36aa350c98f9
by metan 27 May '12
by metan 27 May '12
27 May '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 8aab7a816e45ba2fcfd256ab48bb36aa350c98f9 (commit)
from 965a9237db419f83183eb4a59fc9bc741782093e (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/8aab7a816e45ba2fcfd256ab48bb36aa350c…
commit 8aab7a816e45ba2fcfd256ab48bb36aa350c98f9
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun May 27 15:34:52 2012 +0200
spiv: Resize backend to fit image on pressing 1.
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 91b9f35..9862049 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -171,9 +171,10 @@ int load_image(struct loader_params *params)
* This function tries to resize spiv window
* and if succedes blits the image directly to the screen.
*/
-static int resize_backend_and_blit(GP_Context *img,
- struct loader_params *params)
+static int resize_backend_and_blit(struct loader_params *params)
{
+ GP_Context *img = params->img;
+
if (GP_BackendResize(backend, img->w, img->h))
return 1;
@@ -236,6 +237,7 @@ static void *image_loader(void *ptr)
if (rat < 1) {
cpu_timer_start(&timer, "Blur");
callback.priv = "Blurring Image";
+ //TODO: We can't blur saved image!
if (GP_FilterGaussianBlur(img, img, 0.4/rat, 0.4/rat,
&callback) == NULL)
return NULL;
@@ -587,6 +589,9 @@ int main(int argc, char *argv[])
params.show_progress_once = 1;
show_image(¶ms, argv[argn]);
break;
+ case GP_KEY_1:
+ resize_backend_and_blit(¶ms);
+ break;
}
break;
case GP_EV_SYS:
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/spiv.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0