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, generate has been updated via 4e6371664c0ae7cffb760e86403bae8bd372c555 (commit) from af5fd7582e11df218ea97fa3d5299a86e0a07194 (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/4e6371664c0ae7cffb760e86403bae8bd372c...
commit 4e6371664c0ae7cffb760e86403bae8bd372c555 Author: Cyril Hrubis metan@ucw.cz Date: Wed Sep 21 14:29:27 2011 +0200
More PPM work (image saving).
diff --git a/include/loaders/GP_PPM.h b/include/loaders/GP_PPM.h index 78ba9f7..8b57e61 100644 --- a/include/loaders/GP_PPM.h +++ b/include/loaders/GP_PPM.h @@ -27,6 +27,9 @@
GP_RetCode GP_LoadPPM(const char *src_path, GP_Context **res);
-GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src); +/* + * The fmt may be either "a" for ASCII or "b" for BINARY. + */ +GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src, char *fmt);
#endif /* GP_PPM_H */ diff --git a/libs/loaders/GP_PNM.c b/libs/loaders/GP_PNM.c new file mode 100644 index 0000000..261b75f --- /dev/null +++ b/libs/loaders/GP_PNM.c @@ -0,0 +1,180 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <stdint.h> +#include <inttypes.h> + +#include <ctype.h> +#include <errno.h> +#include <string.h> + +#include <GP_Debug.h> + +#include "GP_PNM.h" + +/* + + PNM portable bitmap header + -------------------------- + + Format: + + a magick number value of 'P' and one of + '1' - PBM 2bpp gray ASCII + '2' - PGM gray ASCII + '3' - PPM rgb888 ASCII + '4' - PBM 2bpp gray BINARY + '5' - PGM gray BINARY + '6' - PPM rgb888 BINARY + whitespace (blanks, TABs, CRs, LFs). + ascii width + whitespace + ascii height + whitespace + maximal value (interval is 0 ... max) (not applicable for PBM) + width * height ascii or binary values + + lines starting with '#' are comments to the end of line + + */ + +static void try_read_comments(FILE *f) +{ + char c1, c2; + + while (isspace(c1 = fgetc(f))); + + ungetc(c1, f); + + while ((c1 = fgetc(f)) == '#') { + do { + c2 = fgetc(f); + } while (c2 != 'n' && c2 != EOF); + } + + ungetc(c1, f); +} + + +static char *pnm_names[] = { + "ASCII encoded PBM", + "ASCII encoded PGM", + "ASCII encoded PPM", + "BINARY encoded PBM", + "BINARY encoded PGM", + "BINARY encoded PPM", +}; + +FILE *GP_ReadPNM(const char *src_path, char *fmt, + uint32_t *w, uint32_t *h, uint32_t *depth) +{ + FILE *f = fopen(src_path, "r"); + int ch; + + if (f == NULL) { + GP_DEBUG(1, "Failed to open file '%s': %s", + src_path, strerror(errno)); + return NULL; + } + + ch = fgetc(f); + + if (ch != 'P') { + GP_DEBUG(1, "Invalid PNM header start '%c' (0x%2x) expecting 'P'", + isprint(ch) ? ch : ' ', ch); + goto err1; + } + + ch = fgetc(f); + + switch (ch) { + case '4': + case '1': + *depth = 1; + break; + case '2': + case '3': + case '5': + case '6': + break; + default: + GP_DEBUG(1, "Invalid PNM format 'P%c' (0x%2x)", + isprint(ch) ? ch : ' ', ch); + goto err1; + } + + *fmt = ch; + + try_read_comments(f); + + if (fscanf(f, "%"PRIu32"n", w) < 1) { + GP_DEBUG(1, "Failed to read PNM header width"); + goto err1; + } + + try_read_comments(f); + + if (fscanf(f, "%"PRIu32"n", h) < 1) { + GP_DEBUG(1, "Failed to read PNM header height"); + goto err1; + } + + GP_DEBUG(2, "Have %s size %"PRIu32"x%"PRIu32, + pnm_names[*fmt - '1'], *w, *h); + + if (*fmt == '1' || *fmt == '3') + return f; + + try_read_comments(f); + + if (fscanf(f, "%"PRIu32"n", depth) < 1) { + GP_DEBUG(1, "Failed to read PNM header depth"); + goto err1; + } + + return f; +err1: + fclose(f); + return NULL; +} + +#define GFXPRIM_SIGNATURE "# Generated by gfxprim http://gfxprim.ucw.czn" + +FILE *GP_WritePNM(const char *dst_path, char fmt, + uint32_t w, uint32_t h, uint32_t depth) +{ + FILE *f = fopen(dst_path, "w"); + int ret; + + ret = fprintf(f, "P%cn"GFXPRIM_SIGNATURE + "%"PRIu32" %"PRIu32"n%"PRIu32"n", + fmt, w, h, depth); + + if (ret < 0) { + GP_DEBUG(1, "Failed to write PNM header '%s' : %s", + dst_path, strerror(errno)); + fclose(f); + return NULL; + } + + return f; +} diff --git a/include/loaders/GP_PPM.h b/libs/loaders/GP_PNM.h similarity index 72% copy from include/loaders/GP_PPM.h copy to libs/loaders/GP_PNM.h index 78ba9f7..af59319 100644 --- a/include/loaders/GP_PPM.h +++ b/libs/loaders/GP_PNM.h @@ -16,17 +16,34 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2011 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2010 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
-#ifndef GP_PPM_H -#define GP_PPM_H +/*
-#include "core/GP_Context.h" + Common PNM functions.
-GP_RetCode GP_LoadPPM(const char *src_path, GP_Context **res); + */
-GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src); +#ifndef GP_PNM_H +#define GP_PNM_H
-#endif /* GP_PPM_H */ +#include <stdint.h> + +/* + * Loads image header, returns pointer to FILE* (with file possition pointing + * to the start of the data stream) on success, fills image metadata into + * arguments. + */ +FILE *GP_ReadPNM(const char *src_path, char *fmt, + uint32_t *w, uint32_t *h, uint32_t *depth); + +/* + * Writes image header. + */ +FILE *GP_WritePNM(const char *dst_path, char fmt, + uint32_t w, uint32_t h, uint32_t depth); + + +#endif /* GP_PNM_H */ diff --git a/libs/loaders/GP_PPM.c b/libs/loaders/GP_PPM.c index 1eec6e9..a14dbe3 100644 --- a/libs/loaders/GP_PPM.c +++ b/libs/loaders/GP_PPM.c @@ -27,15 +27,18 @@ */
#include <stdint.h> +#include <inttypes.h> +#include <errno.h> +#include <string.h>
#include <GP_Debug.h> #include <GP_Context.h> #include <GP_Pixel.h> #include <GP_GetPutPixel.h>
-#include "GP_PXMCommon.h" +#include "GP_PNM.h"
-int load_binary_ppm(FILE *f, uint32_t w, uint32_t h, uint32_t depth, +int load_binary_ppm(FILE *f, uint32_t w, uint32_t h, uint32_t depth __attribute__((unused)), GP_Context *res) { uint32_t x, y; @@ -66,7 +69,7 @@ GP_RetCode GP_LoadPPM(const char *src_path, GP_Context **res) char fmt; FILE *f;
- f = GP_OpenPNM(src_path, &fmt, &w, &h, &depth); + f = GP_ReadPNM(src_path, &fmt, &w, &h, &depth);
if (f == NULL) return GP_EBADFILE; @@ -76,6 +79,11 @@ GP_RetCode GP_LoadPPM(const char *src_path, GP_Context **res) goto err1; }
+ if (depth != 255) { + GP_DEBUG(1, "Unsupported depth %"PRIu32, depth); + goto err1; + } + *res = GP_ContextAlloc(w, h, GP_PIXEL_RGB888);
if (res == NULL) @@ -102,7 +110,58 @@ err1: return GP_EBADFILE; }
-GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src) +static int write_binary_ppm(FILE *f, GP_Context *src) +{ + uint32_t x, y; + + for (y = 0; y < src->h; y++) + for (x = 0; x < src->w; x++) { + GP_Pixel pix = GP_GetPixel_Raw_24BPP(src, x, y); + //TODO endianess? + + GP_SWAP(((uint8_t*)&pix)[0], ((uint8_t*)&pix)[2]); + + if (fwrite(&pix, 3, 1, f) < 1) + return 1; + } + + return 0; +} + +GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src, char *fmt) { - return GP_ENOIMPL; + char hfmt; + FILE *f; + + if (src->pixel_type != GP_PIXEL_RGB888) + return GP_ENOIMPL; + + switch (*fmt) { + /* ASCII */ + case 'a': + return GP_ENOIMPL; + break; + /* binary */ + case 'b': + hfmt = '6'; + break; + default: + return GP_ENOIMPL; + } + + f = GP_WritePNM(res_path, hfmt, src->w, src->h, 255); + + if (write_binary_ppm(f, src)) { + GP_DEBUG(1, "Failed to write buffer"); + fclose(f); + return GP_EBADFILE; + } + + if (fclose(f) < 0) { + GP_DEBUG(1, "Failed to close file '%s' : %s", + res_path, strerror(errno)); + return GP_EBADFILE; + } + + return GP_ESUCCESS; } diff --git a/libs/loaders/GP_PXMCommon.c b/libs/loaders/GP_PXMCommon.c index 9b250bd..0add2f0 100644 --- a/libs/loaders/GP_PXMCommon.c +++ b/libs/loaders/GP_PXMCommon.c @@ -386,127 +386,3 @@ GP_RetCode GP_PXMSave8bpp(FILE *f, GP_Context *context)
return GP_ESUCCESS; } - -static void try_read_comments(FILE *f) -{ - char c1, c2; - - while (isspace(c1 = fgetc(f))); - - ungetc(c1, f); - - while ((c1 = fgetc(f)) == '#') { - do { - c2 = fgetc(f); - } while (c2 != 'n' && c2 != EOF); - } - - ungetc(c1, f); -} - -/* - - PNM portable bitmap header loader. - - Format: - - a magick number value of 'P' and one of - '1' - PBM 2bpp gray ASCII - '2' - PGM gray ASCII - '3' - PPM rgb888 ASCII - '4' - PBM 2bpp gray BINARY - '5' - PGM gray BINARY - '6' - PPM rgb888 BINARY - whitespace (blanks, TABs, CRs, LFs). - ascii width - whitespace - ascii height - whitespace - maximal value (interval is 0 ... max) (not applicable for PBM) - width * height ascii or binary values - - lines starting with '#' are comments to the end of line - - */ - -static char *pnm_names[] = { - "ASCII encoded PBM", - "ASCII encoded PGM", - "ASCII encoded PPM", - "BINARY encoded PBM", - "BINARY encoded PGM", - "BINARY encoded PPM", -}; - -FILE *GP_OpenPNM(const char *src_path, char *fmt, uint32_t *w, uint32_t *h, - uint32_t *depth) -{ - FILE *f = fopen(src_path, "r"); - int ch; - - if (f == NULL) { - GP_DEBUG(1, "Failed to open file '%s': %s", - src_path, strerror(errno)); - return NULL; - } - - ch = fgetc(f); - - if (ch != 'P') { - GP_DEBUG(1, "Invalid PNM header start '%c' (0x%2x) expecting 'P'", - isprint(ch) ? ch : ' ', ch); - goto err1; - } - - ch = fgetc(f); - - switch (ch) { - case '4': - case '1': - *depth = 1; - break; - case '2': - case '3': - case '5': - case '6': - break; - default: - GP_DEBUG(1, "Invalid PNM format 'P%c' (0x%2x)", - isprint(ch) ? ch : ' ', ch); - goto err1; - } - - *fmt = ch; - - try_read_comments(f); - - if (fscanf(f, "%"PRIu32"n", w) < 1) { - GP_DEBUG(1, "Failed to read PNM header width"); - goto err1; - } - - try_read_comments(f); - - if (fscanf(f, "%"PRIu32"n", h) < 1) { - GP_DEBUG(1, "Failed to read PNM header height"); - goto err1; - } - - GP_DEBUG(2, "Have %s size %"PRIu32"x%"PRIu32, - pnm_names[*fmt - '1'], *w, *h); - - if (*fmt == '1' || *fmt == '3') - return f; - - try_read_comments(f); - - if (fscanf(f, "%"PRIu32"n", depth) < 1) { - GP_DEBUG(1, "Failed to read PNM header depth"); - goto err1; - } - - return f; -err1: - fclose(f); - return NULL; -} diff --git a/libs/loaders/GP_PXMCommon.h b/libs/loaders/GP_PXMCommon.h index 0c231e2..1a3fc04 100644 --- a/libs/loaders/GP_PXMCommon.h +++ b/libs/loaders/GP_PXMCommon.h @@ -57,7 +57,11 @@ GP_RetCode GP_PXMLoad8bpp(FILE *f, GP_Context *context); * Loads image header, returns pointer to FILE* on success, fills image * metadata into arguments. */ -FILE *GP_OpenPNM(const char *src_path, char *fmt, uint32_t *w, uint32_t *h, - uint32_t *depth); +FILE *GP_ReadHeaderPNM(const char *src_path, char *fmt, + uint32_t *w, uint32_t *h, uint32_t *depth); + +FILE *GP_WriteHeaderPNM(const char *dst_path, char *fmt, + uint32_t w, uint32_t h, uint32_t depth); +
#endif /* GP_PXM_COMMON_H */ diff --git a/tests/SDL/Makefile b/tests/SDL/Makefile index d99fdb9..185a3ce 100644 --- a/tests/SDL/Makefile +++ b/tests/SDL/Makefile @@ -6,7 +6,7 @@ INCLUDE=core gfx SDL backends LDLIBS+=-lGP -L$(TOPDIR)/build/ -lGP_SDL -lSDL
APPS=pixeltest fileview fonttest linetest randomshapetest shapetest sierpinsky- symbolstest textaligntest trianglefps input blittest subcontext + symbolstest textaligntest trianglefps input blittest subcontext ppm_test
include $(TOPDIR)/include.mk include $(TOPDIR)/app.mk diff --git a/include/loaders/GP_PPM.h b/tests/SDL/ppm_test.c similarity index 79% copy from include/loaders/GP_PPM.h copy to tests/SDL/ppm_test.c index 78ba9f7..fce7989 100644 --- a/include/loaders/GP_PPM.h +++ b/tests/SDL/ppm_test.c @@ -20,13 +20,26 @@ * * *****************************************************************************/
-#ifndef GP_PPM_H -#define GP_PPM_H +#include <stdio.h> +#include <stdlib.h>
-#include "core/GP_Context.h" +#include "GP.h"
-GP_RetCode GP_LoadPPM(const char *src_path, GP_Context **res); +int main(int argc, char *argv[]) +{ + GP_Context *bitmap; + GP_SetDebugLevel(10); + GP_RetCode ret;
-GP_RetCode GP_SavePPM(const char *res_path, GP_Context *src); + if ((ret = GP_LoadPPM("ball.ppm", &bitmap))) { + fprintf(stderr, "Failed to load bitmap: %sn", GP_RetCodeName(ret)); + return 1; + }
-#endif /* GP_PPM_H */ + if ((ret = GP_SavePPM("ball2.ppm", bitmap, "b"))) { + fprintf(stderr, "Failed to load bitmap: %sn", GP_RetCodeName(ret)); + return 1; + } + + return 0; +}
-----------------------------------------------------------------------
Summary of changes: include/loaders/GP_PPM.h | 5 +- libs/loaders/GP_PNM.c | 180 ++++++++++++++++++++ .../filters/GP_Filters.h => libs/loaders/GP_PNM.h | 28 +++- libs/loaders/GP_PPM.c | 69 +++++++- libs/loaders/GP_PXMCommon.c | 124 -------------- libs/loaders/GP_PXMCommon.h | 8 +- tests/SDL/Makefile | 2 +- libs/core/GP_Debug.c => tests/SDL/ppm_test.c | 26 ++- 8 files changed, 293 insertions(+), 149 deletions(-) create mode 100644 libs/loaders/GP_PNM.c copy include/filters/GP_Filters.h => libs/loaders/GP_PNM.h (75%) copy libs/core/GP_Debug.c => tests/SDL/ppm_test.c (79%)
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.