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/ed03e7bc0d0825a97e73887be30e768cc0f8a...
commit ed03e7bc0d0825a97e73887be30e768cc0f8aeec Author: Cyril Hrubis metan@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@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/a2efbefa0d3cf0e3174dee1d95739d9872978...
commit a2efbefa0d3cf0e3174dee1d95739d9872978ed9 Author: Cyril Hrubis metan@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/3e5a833f10aa54ddd8b7218e06ee6ec370e05...
commit 3e5a833f10aa54ddd8b7218e06ee6ec370e05ae1 Author: Cyril Hrubis metan@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/2f882b02d5ff65219b1702a4e880582afeb18...
commit 2f882b02d5ff65219b1702a4e880582afeb185c4 Author: Cyril Hrubis metan@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/5d07526c70845eae42935de4a03ec9d90bf8a...
commit 5d07526c70845eae42935de4a03ec9d90bf8a019 Author: Cyril Hrubis metan@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@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@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@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.