From 6f88921e6f7db7876313850c44ed973250cca61a Mon Sep 17 00:00:00 2001 From: metan Date: Wed, 23 Feb 2011 03:54:32 +0100 Subject: [PATCH] Working on PGM loader. --- loaders/GP_PBM.c | 113 ++-------------------- loaders/{GP_PBM.c => GP_PGM.c} | 178 ++++++++++++----------------------- loaders/GP_PGM.h | 35 +++++++ loaders/{GP_PBM.c => GP_PXMCommon.c} | 94 +++--------------- loaders/GP_PXMCommon.h | 41 ++++++++ 5 files changed, 160 insertions(+), 301 deletions(-) copy loaders/{GP_PBM.c => GP_PGM.c} (51%) create mode 100644 loaders/GP_PGM.h copy loaders/{GP_PBM.c => GP_PXMCommon.c} (69%) create mode 100644 loaders/GP_PXMCommon.h diff --git a/loaders/GP_PBM.c b/loaders/GP_PBM.c index 072763a9..623b8730 100644 --- a/loaders/GP_PBM.c +++ b/loaders/GP_PBM.c @@ -44,21 +44,19 @@ #include #include #include + +#include "GP_PXMCommon.h" #include "GP_PBM.h" GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) { FILE *f = fopen(src, "r"); - char h1, h2; - uint32_t w, h, x, y; + uint32_t w, h; if (f == NULL) return GP_EBADFILE; - if (fscanf(f, "%c%c", &h1, &h2) < 2) - goto err1; - - if (h1 != 'P' || h2 != '1') + if (fgetc(f) != 'P' || fgetc(f) != '1') goto err1; if (fscanf(f, "%"PRIu32"%"PRIu32, &w, &h) < 2) @@ -71,52 +69,9 @@ GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) return GP_ENOMEM; } - uint8_t *pixel = (*res)->pixels; - - for (y = 0; y < h; y++) { - for (x = 0; x < w;) { - int run = 1; - - while (run) { - switch (fgetc(f)) { - case EOF: - goto err2; - case '#': { - int cmt = 1; - while (cmt) { - switch (fgetc(f)) { - case '\n': - cmt = 0; - break; - case EOF: - goto err2; - } - } - break; - } - case '0': - *pixel &= ~(0x80>>(x%8)); - run = 0; - break; - case '1': - *pixel |= 0x80>>(x%8); - run = 0; - break; - default: - break; - } - } - - x++; - - if (x%8 == 0) - pixel++; - } - - if (w%8) - pixel++; - } - + if (GP_PXMLoad1bpp(f, *res)) + goto err2; + fclose(f); return GP_ESUCCESS; err2: @@ -126,53 +81,9 @@ err1: return GP_EBADFILE; } -#define BITMASK(byte, bit) (!!((byte)&(0x80>>(bit)))) - -static GP_RetCode write_line(FILE *f, const uint8_t *data, GP_Context *src) -{ - uint32_t x, max = src->bytes_per_row; - int ret; - - if (src->w % 8) - max--; - - for (x = 0; x < max; x++) { - - if (x != 0) - if (fprintf(f, " ") < 0) - return GP_EBADFILE; - - ret = fprintf(f, "%u %u %u %u %u %u %u %u", - BITMASK(data[x], 0), - BITMASK(data[x], 1), - BITMASK(data[x], 2), - BITMASK(data[x], 3), - BITMASK(data[x], 4), - BITMASK(data[x], 5), - BITMASK(data[x], 6), - BITMASK(data[x], 7)); - if (ret < 0) - return GP_EBADFILE; - } - - for (x = 0; x < (src->w % 8); x++) { - ret = fprintf(f, " %u", BITMASK(data[max], x)); - - if (ret < 0) - return GP_EBADFILE; - } - - if (fprintf(f, "\n") < 0) - return GP_EBADFILE; - - return GP_ESUCCESS; -} - GP_RetCode GP_SavePBM(const char *res, GP_Context *src) { FILE *f; - uint32_t y; - GP_RetCode ret; if (src->pixel_type != GP_PIXEL_G1) return GP_ENOIMPL; @@ -186,14 +97,8 @@ GP_RetCode GP_SavePBM(const char *res, GP_Context *src) (unsigned int) src->w, (unsigned int) src->h) < 2) goto err; - for (y = 0; y < src->h; y++) { - ret = write_line(f, (uint8_t*)src->pixels + src->bytes_per_row * y, src); - - if (ret) { - fclose(f); - return ret; - } - } + if (GP_PXMSave1bpp(f, src)) + goto err; if (fclose(f)) return GP_EBADFILE; diff --git a/loaders/GP_PBM.c b/loaders/GP_PGM.c similarity index 51% copy from loaders/GP_PBM.c copy to loaders/GP_PGM.c index 072763a9..6c0bc1ca 100644 --- a/loaders/GP_PBM.c +++ b/loaders/GP_PGM.c @@ -25,17 +25,18 @@ /* - PBM portable bitmap loader/saver. + PGM portable graymap loader/saver. Format: - a magick number value of 'P' and '1' + a magick number value of 'P' and '2' whitespace (blanks, TABs, CRs, LFs). ascii width whitespace ascii height whitespace - width * height symbols '1' or '0' ('1' == black, '0' == white) + maximal gray value (interval is 0 ... max) + width * height ascii gray values lines starting with '#' are comments to the end of line @@ -44,77 +45,50 @@ #include #include #include -#include "GP_PBM.h" -GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) +#include "GP_PXMCommon.h" +#include "GP_PGM.h" + +GP_RetCode GP_LoadPGM(const char *src, GP_Context **res) { FILE *f = fopen(src, "r"); - char h1, h2; - uint32_t w, h, x, y; + uint32_t w, h, gray; + GP_PixelType type; if (f == NULL) return GP_EBADFILE; - if (fscanf(f, "%c%c", &h1, &h2) < 2) + if (fgetc(f) != 'P' || fgetc(f) != '2') goto err1; - if (h1 != 'P' || h2 != '1') + if (fscanf(f, "%"PRIu32"%"PRIu32"%"PRIu32, &w, &h, &gray) < 3) goto err1; - if (fscanf(f, "%"PRIu32"%"PRIu32, &w, &h) < 2) + switch (gray) { + case 1: + type = GP_PIXEL_G1; + break; + case 3: + type = GP_PIXEL_G2; + break; + case 15: + type = GP_PIXEL_G4; + break; + case 255: + type = GP_PIXEL_G8; + break; + default: goto err1; - - *res = GP_ContextAlloc(w, h, GP_PIXEL_G1); - - if (*res == NULL) { - fclose(f); - return GP_ENOMEM; } - uint8_t *pixel = (*res)->pixels; - - for (y = 0; y < h; y++) { - for (x = 0; x < w;) { - int run = 1; - - while (run) { - switch (fgetc(f)) { - case EOF: - goto err2; - case '#': { - int cmt = 1; - while (cmt) { - switch (fgetc(f)) { - case '\n': - cmt = 0; - break; - case EOF: - goto err2; - } - } - break; - } - case '0': - *pixel &= ~(0x80>>(x%8)); - run = 0; - break; - case '1': - *pixel |= 0x80>>(x%8); - run = 0; - break; - default: - break; - } - } - - x++; - - if (x%8 == 0) - pixel++; - } - - if (w%8) - pixel++; + *res = GP_ContextAlloc(w, h, type); + + switch (gray) { + case 1: + if (GP_PXMLoad1bpp(f, *res)) + goto err2; + break; + //TODO } fclose(f); @@ -126,74 +100,44 @@ err1: return GP_EBADFILE; } -#define BITMASK(byte, bit) (!!((byte)&(0x80>>(bit)))) - -static GP_RetCode write_line(FILE *f, const uint8_t *data, GP_Context *src) -{ - uint32_t x, max = src->bytes_per_row; - int ret; - - if (src->w % 8) - max--; - - for (x = 0; x < max; x++) { - - if (x != 0) - if (fprintf(f, " ") < 0) - return GP_EBADFILE; - - ret = fprintf(f, "%u %u %u %u %u %u %u %u", - BITMASK(data[x], 0), - BITMASK(data[x], 1), - BITMASK(data[x], 2), - BITMASK(data[x], 3), - BITMASK(data[x], 4), - BITMASK(data[x], 5), - BITMASK(data[x], 6), - BITMASK(data[x], 7)); - if (ret < 0) - return GP_EBADFILE; - } - - for (x = 0; x < (src->w % 8); x++) { - ret = fprintf(f, " %u", BITMASK(data[max], x)); - - if (ret < 0) - return GP_EBADFILE; - } - - if (fprintf(f, "\n") < 0) - return GP_EBADFILE; - - return GP_ESUCCESS; -} - -GP_RetCode GP_SavePBM(const char *res, GP_Context *src) +GP_RetCode GP_SavePGM(const char *res, GP_Context *src) { FILE *f; - uint32_t y; - GP_RetCode ret; - - if (src->pixel_type != GP_PIXEL_G1) + uint32_t gray; + + switch (src->pixel_type) { + case GP_PIXEL_G1: + gray = 1; + break; + case GP_PIXEL_G2: + gray = 3; + break; + case GP_PIXEL_G4: + gray = 15; + break; + case GP_PIXEL_G8: + gray = 255; + break; + default: return GP_ENOIMPL; + } f = fopen(res, "w"); if (f == NULL) return GP_EBADFILE; - if (fprintf(f, "P1\n%u %u\n# Generated by gfxprim\n", - (unsigned int) src->w, (unsigned int) src->h) < 2) + if (fprintf(f, "P2\n%u %u\n%u\n# Generated by gfxprim\n", + (unsigned int) src->w, (unsigned int) src->h, gray) < 3) goto err; - for (y = 0; y < src->h; y++) { - ret = write_line(f, (uint8_t*)src->pixels + src->bytes_per_row * y, src); - - if (ret) { - fclose(f); - return ret; - } - } + switch (gray) { + case 1: + if (GP_PXMSave1bpp(f, src)) + goto err; + break; + //TODO + } if (fclose(f)) return GP_EBADFILE; diff --git a/loaders/GP_PGM.h b/loaders/GP_PGM.h new file mode 100644 index 00000000..998a6f2c --- /dev/null +++ b/loaders/GP_PGM.h @@ -0,0 +1,35 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * + * * + * * + * Copyright (C) 2009-2010 Cyril Hrubis * + * * + *****************************************************************************/ + +#ifndef GP_PGM_H +#define GP_PGM_H + +#include "GP_Context.h" + +GP_RetCode GP_LoadPGM(const char *src, GP_Context **res); + +GP_RetCode GP_SavePGM(const char *res, GP_Context *src); + +#endif /* GP_PGM_H */ diff --git a/loaders/GP_PBM.c b/loaders/GP_PXMCommon.c similarity index 69% copy from loaders/GP_PBM.c copy to loaders/GP_PXMCommon.c index 072763a9..1c16b879 100644 --- a/loaders/GP_PBM.c +++ b/loaders/GP_PXMCommon.c @@ -23,64 +23,25 @@ * * *****************************************************************************/ -/* - - PBM portable bitmap loader/saver. - - Format: - - a magick number value of 'P' and '1' - whitespace (blanks, TABs, CRs, LFs). - ascii width - whitespace - ascii height - whitespace - width * height symbols '1' or '0' ('1' == black, '0' == white) - - lines starting with '#' are comments to the end of line - - */ - #include #include #include -#include "GP_PBM.h" - -GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) -{ - FILE *f = fopen(src, "r"); - char h1, h2; - uint32_t w, h, x, y; - - if (f == NULL) - return GP_EBADFILE; - - if (fscanf(f, "%c%c", &h1, &h2) < 2) - goto err1; - - if (h1 != 'P' || h2 != '1') - goto err1; - - if (fscanf(f, "%"PRIu32"%"PRIu32, &w, &h) < 2) - goto err1; - - *res = GP_ContextAlloc(w, h, GP_PIXEL_G1); - if (*res == NULL) { - fclose(f); - return GP_ENOMEM; - } +#include "GP_PXMCommon.h" - uint8_t *pixel = (*res)->pixels; +GP_RetCode GP_PXMLoad1bpp(FILE *f, GP_Context *context) +{ + uint8_t *pixel = context->pixels; + uint32_t x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w;) { + for (y = 0; y < context->h; y++) { + for (x = 0; x < context->w;) { int run = 1; while (run) { switch (fgetc(f)) { case EOF: - goto err2; + return GP_EBADFILE; case '#': { int cmt = 1; while (cmt) { @@ -89,7 +50,7 @@ GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) cmt = 0; break; case EOF: - goto err2; + return GP_EBADFILE; } } break; @@ -113,17 +74,11 @@ GP_RetCode GP_LoadPBM(const char *src, GP_Context **res) pixel++; } - if (w%8) + if (context->w%8) pixel++; } - fclose(f); return GP_ESUCCESS; -err2: - free(*res); -err1: - fclose(f); - return GP_EBADFILE; } #define BITMASK(byte, bit) (!!((byte)&(0x80>>(bit)))) @@ -168,38 +123,17 @@ static GP_RetCode write_line(FILE *f, const uint8_t *data, GP_Context *src) return GP_ESUCCESS; } -GP_RetCode GP_SavePBM(const char *res, GP_Context *src) +GP_RetCode GP_PXMSave1bpp(FILE *f, GP_Context *context) { - FILE *f; uint32_t y; GP_RetCode ret; - if (src->pixel_type != GP_PIXEL_G1) - return GP_ENOIMPL; - - f = fopen(res, "w"); - - if (f == NULL) - return GP_EBADFILE; - - if (fprintf(f, "P1\n%u %u\n# Generated by gfxprim\n", - (unsigned int) src->w, (unsigned int) src->h) < 2) - goto err; + for (y = 0; y < context->h; y++) { + ret = write_line(f, context->pixels + context->bytes_per_row * y, context); - for (y = 0; y < src->h; y++) { - ret = write_line(f, (uint8_t*)src->pixels + src->bytes_per_row * y, src); - - if (ret) { - fclose(f); + if (ret) return ret; - } } - if (fclose(f)) - return GP_EBADFILE; - return GP_ESUCCESS; -err: - fclose(f); - return GP_EBADFILE; } diff --git a/loaders/GP_PXMCommon.h b/loaders/GP_PXMCommon.h new file mode 100644 index 00000000..105510e4 --- /dev/null +++ b/loaders/GP_PXMCommon.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * + * * + * * + * Copyright (C) 2009-2010 Cyril Hrubis * + * * + *****************************************************************************/ + +/* + + Common bytes to ascci and ascii to bytes functions. + + */ + +#ifndef GP_PXM_COMMON_H +#define GP_PXM_COMMON_H + +#include +#include "GP.h" + +GP_RetCode GP_PXMSave1bpp(FILE *f, GP_Context *context); +GP_RetCode GP_PXMLoad1bpp(FILE *f, GP_Context *context); + +#endif /* GP_PXM_COMMON_H */ -- 2.11.4.GIT