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 dd150fbb860e16f01cbdf28dc2c0f2d2d8425b20 (commit) via cf801775780f7eab314e2ba9a166edc9ccdd708d (commit) from 690b25c07649dab4d217e1d0ecbf9c56a20fc48b (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/dd150fbb860e16f01cbdf28dc2c0f2d2d8425...
commit dd150fbb860e16f01cbdf28dc2c0f2d2d8425b20 Author: Cyril Hrubis metan@ucw.cz Date: Mon Jan 27 22:27:52 2014 +0100
loaders: Initial PCX support + tests + doc.
TODO: Needs a buffered IO Stream
FIXME: More tests, (256 color palette) does v2.5 with filed palette work?
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/build/syms/Loaders_symbols.txt b/build/syms/Loaders_symbols.txt index 7b40c8c..a65f6c7 100644 --- a/build/syms/Loaders_symbols.txt +++ b/build/syms/Loaders_symbols.txt @@ -56,6 +56,10 @@ GP_ReadJP2 GP_LoadJP2 GP_MatchJP2
+GP_ReadPCX +GP_LoadPCX +GP_MatchPCX + GP_SaveTmpFile GP_LoadTmpFile
diff --git a/demos/spiv/spiv.1 b/demos/spiv/spiv.1 index 386706e..fb23f1f 100644 --- a/demos/spiv/spiv.1 +++ b/demos/spiv/spiv.1 @@ -11,8 +11,9 @@ is a fast, lightweight and minimalistic image viewer build on the top of the GFXprim library. .PP Spiv supports wide range of image formats, currently supported are -JPEG, PNG, GIF, BMP, TIFF, PSP, PPM, JP2 and CBZ (as well general -ZIP archives with images), and more will come in the near future. +JPEG, PNG, GIF, BMP, TIFF, PSP, PNM, PCX, JPEG2000 and CBZ (as well +general ZIP archives with images), and more will come in the +near future. .PP Spiv supports variety of video backends (via GFXprim backends) currently these are X11, Linux Framebuffer, SDL and AAlib. Spiv also @@ -300,7 +301,7 @@ spiv -e G1 -d images/ spiv -b 'X11:use_root' -t 10 images/
.PP -.B Same as abowe but works in KDE +.B Same as above but works in KDE
.nf spiv -b 'X11:create_root' -t 10 images/ diff --git a/demos/spiv/spiv_help.c b/demos/spiv/spiv_help.c index 3af2b03..186b1c5 100644 --- a/demos/spiv/spiv_help.c +++ b/demos/spiv/spiv_help.c @@ -98,7 +98,7 @@ static const struct examples examples[] = { {"spiv -b 'X11:use_root' -t 10 images/", "Runs slideshow using X root window as backend window"}, {"spiv -b 'X11:create_root' -t 10 images/", - "Same as abowe but works in KDEn"} + "Same as above but works in KDEn"} };
static const int examples_len = sizeof(examples) / sizeof(*examples); @@ -164,8 +164,9 @@ const char *man_head = "top of the GFXprim library.n" ".PPn" "Spiv supports wide range of image formats, currently supported aren" - "JPEG, PNG, GIF, BMP, TIFF, PSP, PPM, JP2 and CBZ (as well generaln" - "ZIP archives with images), and more will come in the near future.n" + "JPEG, PNG, GIF, BMP, TIFF, PSP, PNM, PCX, JPEG2000 and CBZ (as welln" + "general ZIP archives with images), and more will come in then" + "near future.n" ".PPn" "Spiv supports variety of video backends (via GFXprim backends)n" "currently these are X11, Linux Framebuffer, SDL and AAlib. Spiv alson" diff --git a/doc/about.txt b/doc/about.txt index 7029823..6065ed4 100644 --- a/doc/about.txt +++ b/doc/about.txt @@ -109,6 +109,11 @@ images into various standard formats (PNG, JPEG, GIF, TIFF, BMP, PNM, etc...). [green]#Experimental support for RGB images# | [black]*No*
+| PCX | + ZSoft PCX | + [green]#All v3.0# | + [black]*No* + | CBZ | Comic book archive | [green]#Experimental support via ZIP Container# | diff --git a/doc/loaders.txt b/doc/loaders.txt index 5ac5743..1734718 100644 --- a/doc/loaders.txt +++ b/doc/loaders.txt @@ -600,3 +600,45 @@ signatures. The 'PNM' matches all of the formats. i.e. 'PBM', 'PGM' and 'PPM'.
All functions return non-zero if found. + +PCX Loader +~~~~~~~~~~ + +The 'PCX' loader can load ZSoft PCX images. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PCX.h> +/* or */ +#include <GP.h> + +GP_Context *GP_ReadPCX(GP_IO *io, GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Reads a 'PCX' image from readable 'GP_IO'. The link:loaders_io.html[IO stream] +is expected to start exactly at the 'PCX' file signature. + +Returns newly allocated context (containing decompressed image) or in case of +failure 'NULL' and 'errno' is set. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PCX.h> +/* or */ +#include <GP.h> + +GP_Context *GP_LoadPCX(const char *src_path, GP_ProgressCallback *callback); +------------------------------------------------------------------------------- + +Loads a 'PCX' image from a file. + +[source,c] +------------------------------------------------------------------------------- +#include <loaders/GP_PCX.h> +/* or */ +#include <GP.h> + +int GP_MatchPCX(const void *buf); +------------------------------------------------------------------------------- + +Matches a 'PCX' file signature. Returns non-zero if found. diff --git a/doc/loaders_python.txt b/doc/loaders_python.txt index 136b533..ae2207e 100644 --- a/doc/loaders_python.txt +++ b/doc/loaders_python.txt @@ -21,6 +21,7 @@ import gfxprim.loaders as loaders img = loaders.LoadPNG(path, callback=None) img = loaders.LoadPNM(path, callback=None) img = loaders.LoadPPM(path, callback=None) + img = loaders.LoadPCX(path, callback=None) img = loaders.LoadPSP(path, callback=None) img = loaders.LoadTIFF(path, callback=None) ------------------------------------------------------------------------------- diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h index 0ed72af..7ed1727 100644 --- a/include/loaders/GP_Loaders.h +++ b/include/loaders/GP_Loaders.h @@ -42,6 +42,7 @@ #include "loaders/GP_JP2.h" #include "loaders/GP_GIF.h" #include "loaders/GP_TIFF.h" +#include "loaders/GP_PCX.h" #include "loaders/GP_PSP.h"
#include "loaders/GP_TmpFile.h" diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_PCX.h similarity index 67% copy from include/loaders/GP_Loaders.h copy to include/loaders/GP_PCX.h index 0ed72af..0d7d6e2 100644 --- a/include/loaders/GP_Loaders.h +++ b/include/loaders/GP_PCX.h @@ -16,41 +16,40 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos * - * jiri.bluebear.dluhos@gmail.com * - * * - * Copyright (C) 2009-2013 Cyril Hrubis metan@ucw.cz * + * Copyright (C) 2009-2014 Cyril Hrubis metan@ucw.cz * * * *****************************************************************************/
/*
- Core include file for loaders API. + PCX image support.
*/
-#ifndef LOADERS_GP_LOADERS_H -#define LOADERS_GP_LOADERS_H +#ifndef LOADERS_GP_PCX_H +#define LOADERS_GP_PCX_H
#include "core/GP_Context.h" #include "core/GP_ProgressCallback.h" +#include "loaders/GP_IO.h"
-#include "loaders/GP_PNM.h" -#include "loaders/GP_BMP.h" -#include "loaders/GP_PNG.h" -#include "loaders/GP_JPG.h" -#include "loaders/GP_JP2.h" -#include "loaders/GP_GIF.h" -#include "loaders/GP_TIFF.h" -#include "loaders/GP_PSP.h" - -#include "loaders/GP_TmpFile.h"
-#include "loaders/GP_MetaData.h" +/* + * Reads a PCX from an IO stream. + * + * Returns newly allocated context cotaining the loaded image or in case of + * failure NULL and errno is set. + */ +GP_Context *GP_ReadPCX(GP_IO *io, GP_ProgressCallback *callback);
-#include "loaders/GP_Loader.h" +/* + * Loads a PCX image from a file. + */ +GP_Context *GP_LoadPCX(const char *src_path, GP_ProgressCallback *callback);
-#include "loaders/GP_Container.h" -#include "loaders/GP_ZIP.h" +/* + * Match PCX signature. + */ +int GP_MatchPCX(const void *buf);
-#endif /* LOADERS_GP_LOADERS_H */ +#endif /* LOADERS_GP_PCX_H */ diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c index aa793ba..e1f78a5 100644 --- a/libs/loaders/GP_Loader.c +++ b/libs/loaders/GP_Loader.c @@ -49,13 +49,23 @@ static GP_Loader psp_loader = { .extensions = {"psp", "pspimage", NULL}, };
+static GP_Loader pcx_loader = { + .Read = GP_ReadPCX, + .Load = GP_LoadPCX, + .Save = NULL, + .Match = GP_MatchPCX, + .fmt_name = "ZSoft PCX", + .next = &psp_loader, + .extensions = {"pcx", NULL}, +}; + static GP_Loader pbm_loader = { .Read = GP_ReadPBM, .Load = GP_LoadPBM, .Save = GP_SavePBM, .Match = GP_MatchPBM, .fmt_name = "Netpbm portable Bitmap", - .next = &psp_loader, + .next = &pcx_loader, .extensions = {"pbm", NULL}, };
diff --git a/libs/loaders/GP_PCX.c b/libs/loaders/GP_PCX.c new file mode 100644 index 0000000..698f82e --- /dev/null +++ b/libs/loaders/GP_PCX.c @@ -0,0 +1,473 @@ +/***************************************************************************** + * 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-2014 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +/* + + PCX image support. + + */ + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdint.h> +#include <inttypes.h> + +#include "core/GP_Debug.h" +#include "core/GP_GetPutPixel.h" + +#include "GP_PCX.h" + +/* Creator ZSoft: 0x0a + * Version: 0x00, 0x02, 0x03, 0x04, 0x05 + * RLE: 0x01 + * BPP: 0x01, 0x02, 0x04, 0x08 + */ +int GP_MatchPCX(const void *buf) +{ + const uint8_t *b = buf; + + if (b[0] != 0x0a) + return 0; + + /* version */ + switch (b[1]) { + case 0: + case 2: + case 3: + case 4: + case 5: + break; + default: + return 0; + } + + if (b[2] != 0x01) + return 0; + + /* bpp 1, 2, 4 or 8 */ + switch (b[3]) { + case 1: + case 2: + case 4: + case 8: + return 1; + default: + return 0; + } +} + +struct pcx_header { + uint8_t ver; + uint8_t bpp; + uint16_t xs, ys, xe, ye; + uint16_t hres, vres; + uint8_t nplanes; + uint16_t pal_info; + uint16_t bytes_per_line; + /* 16 RGB tripplets palette */ + uint8_t palette[48]; +}; + +static int get_byte(GP_IO *io) +{ + uint8_t buf; + + if (GP_IORead(io, &buf, 1) != 1) + return -1; + + return buf; +} + +static int readline(GP_IO *io, uint8_t *buf, unsigned int size, unsigned int padd) +{ + int b, val = 0, cnt = 0; + unsigned int read = 0; + + for (;;) { + while (cnt > 0 && read < size) { + buf[read++] = val; + cnt--; + } + + if (read >= size) { + goto end; + } + + b = get_byte(io); + + if (b == -1) { + GP_WARN("End of file reached unexpectedly"); + return 0; + } + + if ((b & 0xc0) == 0xc0) { + cnt = b & 0x3f; + val = get_byte(io); + } else { + cnt = 1; + val = b; + } + } + +end: + /* + * Data may be padded, read the excess bytes + */ + while (padd--) { + if (cnt) { + cnt--; + } else { + b = get_byte(io); + if ((b & 0xc0) == 0xc0) { + cnt = b & 0x3f; + get_byte(io); + } + } + } + + if (cnt) + GP_WARN("Nonzero repeat count at the line end (%u)", cnt); + + return 0; +} + +#include "core/GP_BitSwap.h" + +static int read_g1(GP_IO *io, struct pcx_header *header, + GP_Context *res, GP_ProgressCallback *callback) +{ + uint32_t y; + int padd = (int)header->bytes_per_line - (int)res->bytes_per_row; + + if (padd < 0) { + GP_WARN("Invalid number of bytes per line"); + return EINVAL; + } + + for (y = 0; y < res->h; y++) { + uint8_t *addr = GP_PIXEL_ADDR(res, 0, y); + + readline(io, addr, res->bytes_per_row, padd); + + //TODO: FIX Endians + GP_BitSwapRow_B1(addr, res->bytes_per_row); + + if (GP_ProgressCallbackReport(callback, y, res->h, res->w)) { + GP_DEBUG(1, "Operation aborted"); + return ECANCELED; + } + } + + return 0; +} + +static int read_rgb888(GP_IO *io, struct pcx_header *header, + GP_Context *res, GP_ProgressCallback *callback) +{ + uint32_t x, y; + unsigned int bpr = header->bytes_per_line; + uint8_t b[3 * bpr]; + + for (y = 0; y < res->h; y++) { + readline(io, b, sizeof(b), 0); + + for (x = 0; x < res->w; x++) { + GP_Pixel pix = GP_Pixel_CREATE_RGB888(b[x], + b[x+bpr], + b[x+2*bpr]); + GP_PutPixel_Raw_24BPP(res, x, y, pix); + } + + if (GP_ProgressCallbackReport(callback, y, res->h, res->w)) { + GP_DEBUG(1, "Operation aborted"); + return ECANCELED; + } + } + + return 0; +} + +static int read_16_palette(GP_IO *io, struct pcx_header *header, + GP_Context *res, GP_ProgressCallback *callback) +{ + uint32_t x, y; + unsigned int i; + uint8_t b[header->bytes_per_line]; + GP_Pixel palette[16]; + uint8_t idx=0, mask, mod; + + for (i = 0; i < 16; i++) { + palette[i] = (GP_Pixel)header->palette[3*i] << 16; + palette[i] |= (GP_Pixel)header->palette[3*i+1] << 8; + palette[i] |= header->palette[3*i+2]; + } + + switch (header->bpp) { + case 2: + mask = 0x30; + mod = 4; + break; + case 4: + mask = 0xf0; + mod = 2; + break; + default: + GP_BUG("Invalid 16 color palette bpp %u", header->bpp); + return EINVAL; + } + + for (y = 0; y < res->h; y++) { + readline(io, b, sizeof(b), 0); + + i = 0; + + for (x = 0; x < res->w; x++) { + + if (!(x % mod)) + idx = b[i++]; + + GP_PutPixel_Raw_24BPP(res, x, y, palette[(idx & mask) >> (8 - header->bpp)]); + idx <<= header->bpp; + } + + if (GP_ProgressCallbackReport(callback, y, res->h, res->w)) { + GP_DEBUG(1, "Operation aborted"); + return ECANCELED; + } + } + + return 0; +} + +static int read_256_palette(GP_IO *io, struct pcx_header *header, + GP_Context *res, GP_ProgressCallback *callback) +{ + uint32_t x, y; + unsigned int i; + GP_Pixel palette[256]; + uint8_t b[header->bytes_per_line]; + + if (GP_IOSeek(io, -769, GP_IO_SEEK_END) == (off_t)-1) { + GP_DEBUG(1, "Failed to seek to palette: %s", strerror(errno)); + return EIO; + } + + if (get_byte(io) != 0x0c) { + GP_DEBUG(1, "Wrong palette marker"); + return EIO; + } + + for (i = 0; i < 256; i++) { + palette[i] = get_byte(io) << 16; + palette[i] |= get_byte(io) << 8; + palette[i] |= get_byte(io); + } + + if (GP_IOSeek(io, 128, GP_IO_SEEK_SET) == (off_t)-1) { + GP_DEBUG(1, "Failed to seek to image data: %s", + strerror(errno)); + return EIO; + } + + for (y = 0; y < res->h; y++) { + readline(io, b, sizeof(b), 0); + + for (x = 0; x < res->w; x++) + GP_PutPixel_Raw_24BPP(res, x, y, palette[b[x]]); + + if (GP_ProgressCallbackReport(callback, y, res->h, res->w)) { + GP_DEBUG(1, "Operation aborted"); + return ECANCELED; + } + } + + return 0; +} + +static GP_PixelType match_pixel_type(struct pcx_header *header) +{ + switch (header->nplanes) { + case 1: + switch (header->bpp) { + /* 1 bit grayscale */ + case 1: + return GP_PIXEL_G1; + /* 16 color palette */ + case 2: + case 4: + /* 256 color palette */ + case 8: + return GP_PIXEL_RGB888; + } + break; + /* raw RGB */ + case 3: + if (header->bpp == 8) + return GP_PIXEL_RGB888; + break; + } + + return GP_PIXEL_UNKNOWN; +} + +static int read_image(GP_IO *io, struct pcx_header *header, + GP_Context *res, GP_ProgressCallback *callback) +{ + switch (header->nplanes) { + case 1: + switch (header->bpp) { + case 1: + return read_g1(io, header, res, callback); + case 2: + case 4: + return read_16_palette(io, header, res, callback); + case 8: + return read_256_palette(io, header, res, callback); + } + break; + case 3: + if (header->bpp == 8) + return read_rgb888(io, header, res, callback); + break; + default: + break; + } + + GP_BUG("Have pixel type %s but cannot load image data", + GP_PixelTypeName(res->pixel_type)); + return ENOSYS; +} + +GP_Context *GP_ReadPCX(GP_IO *io, GP_ProgressCallback *callback) +{ + GP_Context *res = NULL; + GP_PixelType pixel_type; + struct pcx_header header; + unsigned int w, h; + int err = 0; + + uint16_t pcx_header[] = { + 0x0a, /* creator ZSoft */ + GP_IO_BYTE, /* version */ + 0x01, /* compression 1 == RLE */ + GP_IO_BYTE, /* bpp */ + GP_IO_L2, /* xs */ + GP_IO_L2, /* ys */ + GP_IO_L2, /* xe */ + GP_IO_L2, /* ye */ + GP_IO_L2, /* hres */ + GP_IO_L2, /* vres */ + GP_IO_ARRAY | 48, /* 16 bit RGB palette */ + GP_IO_I1, /* reserved */ + GP_IO_BYTE, /* number of planes */ + GP_IO_L2, /* bytes per line */ + GP_IO_L2, /* palette info */ + GP_IO_IGN | 58, /* filler to 128 bytes */ + GP_IO_END, + }; + + if (GP_IOReadF(io, pcx_header, &header.ver, &header.bpp, + &header.xs, &header.ys, &header.xe, &header.ye, + &header.hres, &header.vres, + header.palette, &header.nplanes, + &header.bytes_per_line, &header.pal_info) != 16) { + GP_DEBUG(1, "Failed to read header: %s", strerror(errno)); + return NULL; + } + + switch (header.ver) { + case 0x00: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + break; + GP_DEBUG(1, "Unknown version %x", header.ver); + errno = EINVAL; + return NULL; + } + + GP_DEBUG(1, "Have PCX image ver=%x bpp=%"PRIu8" %"PRIu16"x%"PRIu16 + "-%"PRIu16"x%"PRIu16" bytes_per_line=%"PRIu16 + " nplanes=%"PRIu16" hres=%"PRIu16" vres=%"PRIu16, + header.ver, header.bpp, header.xs, + header.ys, header.xe, header.ye, + header.bytes_per_line, header.nplanes, + header.hres, header.vres); + + pixel_type = match_pixel_type(&header); + + if (pixel_type == GP_PIXEL_UNKNOWN) { + GP_DEBUG(1, "Failed to match pixel type"); + err = ENOSYS; + goto err0; + } + + if (header.xs > header.xe || header.ys > header.ye) { + GP_WARN("Invalid size %"PRIu16"-%"PRIu16"x%"PRIu16"-%"PRIu16, + header.xe, header.xs, header.ye, header.xs); + err = EINVAL; + goto err0; + } + + w = header.xe - header.xs + 1; + h = header.ye - header.ys + 1; + + res = GP_ContextAlloc(w, h, pixel_type); + + if (!res) { + GP_DEBUG(1, "Malloc failed :("); + err = ENOMEM; + goto err0; + } + + if ((err = read_image(io, &header, res, callback))) + goto err1; + + GP_ProgressCallbackDone(callback); + return res; +err1: + GP_ContextFree(res); +err0: + errno = err; + return NULL; +} + +GP_Context *GP_LoadPCX(const char *src_path, GP_ProgressCallback *callback) +{ + GP_IO *io; + GP_Context *res; + int err; + + io = GP_IOFile(src_path, GP_IO_RDONLY); + if (!io) + return NULL; + + res = GP_ReadPCX(io, callback); + + err = errno; + GP_IOClose(io); + errno = err; + + return res; +} diff --git a/pylib/gfxprim/loaders/loaders.i b/pylib/gfxprim/loaders/loaders.i index bab032c..2090b2a 100644 --- a/pylib/gfxprim/loaders/loaders.i +++ b/pylib/gfxprim/loaders/loaders.i @@ -69,3 +69,7 @@ LOADER_FUNC(PSP); LOADER_FUNC(JP2);
%include "GP_JP2.h" + +LOADER_FUNC(PCX); + +%include "GP_PCX.h" diff --git a/tests/loaders/.gitignore b/tests/loaders/.gitignore index 047646e..f6863aa 100644 --- a/tests/loaders/.gitignore +++ b/tests/loaders/.gitignore @@ -5,6 +5,7 @@ PGM PNG PNM PPM +PCX SaveAbort.gen SaveLoad.gen ZIP diff --git a/tests/loaders/Makefile b/tests/loaders/Makefile index 31eaea4..890e576 100644 --- a/tests/loaders/Makefile +++ b/tests/loaders/Makefile @@ -1,10 +1,11 @@ TOPDIR=../.. include $(TOPDIR)/pre.mk
-CSOURCES=loaders_suite.c PNG.c PBM.c PGM.c PPM.c ZIP.c GIF.c IO.c PNM.c +CSOURCES=loaders_suite.c PNG.c PBM.c PGM.c PPM.c ZIP.c GIF.c IO.c PNM.c PCX.c GENSOURCES=SaveLoad.gen.c SaveAbort.gen.c
-APPS=loaders_suite PNG PBM PGM PPM PNM SaveLoad.gen SaveAbort.gen ZIP GIF IO +APPS=loaders_suite PNG PBM PGM PPM PNM SaveLoad.gen SaveAbort.gen ZIP GIF PCX+ IO
include ../tests.mk
diff --git a/tests/loaders/PCX.c b/tests/loaders/PCX.c new file mode 100644 index 0000000..d894c86 --- /dev/null +++ b/tests/loaders/PCX.c @@ -0,0 +1,174 @@ +/***************************************************************************** + * 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-2014 Cyril Hrubis metan@ucw.cz * + * * + *****************************************************************************/ + +#include <string.h> +#include <errno.h> +#include <sys/stat.h> + +#include <core/GP_Context.h> +#include <core/GP_GetPutPixel.h> +#include <loaders/GP_PCX.h> + +#include "tst_test.h" + +struct testcase { + const char *path; + GP_Size w, h; + GP_PixelType pixel_type; + GP_Pixel pixel; +}; + +static int test_load_PCX(struct testcase *test) +{ + GP_Context *img; + + errno = 0; + + img = GP_LoadPCX(test->path, NULL); + + if (img == NULL) { + switch (errno) { + case ENOSYS: + tst_msg("Not Implemented"); + return TST_SKIPPED; + default: + tst_msg("Got %s", strerror(errno)); + return TST_FAILED; + } + } + + if (img->w != test->w || img->h != test->h) { + tst_msg("Wrong size have %ux%u expected %ux%u", + img->w, img->h, test->w, test->h); + GP_ContextFree(img); + return TST_FAILED; + } + + if (img->pixel_type != test->pixel_type) { + tst_msg("Wrong pixel type have %s expected %s", + GP_PixelTypeName(img->pixel_type), + GP_PixelTypeName(test->pixel_type)); + GP_ContextFree(img); + return TST_FAILED; + } + + unsigned int x, y, fail = 0; + + for (x = 0; x < img->w; x++) { + for (y = 0; y < img->w; y++) { + GP_Pixel p = GP_GetPixel(img, x, y); + + if (p != test->pixel) { + if (!fail) + tst_msg("First failed at %u,%u %x %x", + x, y, p, test->pixel); + fail = 1; + } + } + } + + if (!fail) + tst_msg("Context pixels are correct"); + + GP_ContextFree(img); + + if (fail) + return TST_FAILED; + + return TST_SUCCESS; +} + +static struct testcase v3_0_1bpp_10x10_white = { + .path = "ver3_0_palette_1bpp_10x10_white.pcx", + .w = 10, + .h = 10, + .pixel_type = GP_PIXEL_G1, + .pixel = 0x000001, +}; + +static struct testcase v3_0_2bpp_10x10_white = { + .path = "ver3_0_palette_2bpp_10x10_white.pcx", + .w = 10, + .h = 10, + .pixel_type = GP_PIXEL_RGB888, + .pixel = 0xffffff, +}; + +static struct testcase v3_0_4bpp_10x10_white = { + .path = "ver3_0_palette_4bpp_10x10_white.pcx", + .w = 10, + .h = 10, + .pixel_type = GP_PIXEL_RGB888, + .pixel = 0xffffff, +}; + +static struct testcase v2_8_4bpp_10x10_white = { + .path = "ver2_8_palette_4bpp_10x10_white.pcx", + .w = 10, + .h = 10, + .pixel_type = GP_PIXEL_RGB888, + .pixel = 0xffffff, +}; + +static struct testcase v3_0_24bpp_10x10_white = { + .path = "ver3_0_palette_24bpp_10x10_white.pcx", + .w = 10, + .h = 10, + .pixel_type = GP_PIXEL_RGB888, + .pixel = 0xffffff, +}; + +const struct tst_suite tst_suite = { + .suite_name = "PCX", + .tests = { + {.name = "PCX Load ver3.0 1bpp 10x10 white", + .tst_fn = test_load_PCX, + .res_path = "data/pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx", + .data = &v3_0_1bpp_10x10_white, + .flags = TST_TMPDIR | TST_CHECK_MALLOC}, + + {.name = "PCX Load ver3.0 2bpp 10x10 white", + .tst_fn = test_load_PCX, + .res_path = "data/pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx", + .data = &v3_0_2bpp_10x10_white, + .flags = TST_TMPDIR | TST_CHECK_MALLOC}, + + {.name = "PCX Load ver3.0 4bpp 10x10 white", + .tst_fn = test_load_PCX, + .res_path = "data/pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx", + .data = &v3_0_4bpp_10x10_white, + .flags = TST_TMPDIR | TST_CHECK_MALLOC}, + + {.name = "PCX Load ver2.8 4bpp 10x10 white", + .tst_fn = test_load_PCX, + .res_path = "data/pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx", + .data = &v2_8_4bpp_10x10_white, + .flags = TST_TMPDIR | TST_CHECK_MALLOC}, + + {.name = "PCX Load ver3.0 24bpp 10x10 white", + .tst_fn = test_load_PCX, + .res_path = "data/pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx", + .data = &v3_0_24bpp_10x10_white, + .flags = TST_TMPDIR | TST_CHECK_MALLOC}, + {.name = NULL}, + } +}; diff --git a/tests/loaders/data/pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx b/tests/loaders/data/pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx new file mode 100644 index 0000000..01b93b8 Binary files /dev/null and b/tests/loaders/data/pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx differ diff --git a/tests/loaders/data/pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx b/tests/loaders/data/pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx new file mode 100644 index 0000000..9fe5a00 Binary files /dev/null and b/tests/loaders/data/pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx differ diff --git a/tests/loaders/data/pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx b/tests/loaders/data/pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx new file mode 100644 index 0000000..9bc48fb Binary files /dev/null and b/tests/loaders/data/pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx differ diff --git a/tests/loaders/data/pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx b/tests/loaders/data/pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx new file mode 100644 index 0000000..080a9af Binary files /dev/null and b/tests/loaders/data/pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx differ diff --git a/tests/loaders/data/pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx b/tests/loaders/data/pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx new file mode 100644 index 0000000..da88d77 Binary files /dev/null and b/tests/loaders/data/pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx differ diff --git a/tests/loaders/test_list.txt b/tests/loaders/test_list.txt index d4410cb..d36b2a3 100644 --- a/tests/loaders/test_list.txt +++ b/tests/loaders/test_list.txt @@ -1,12 +1,13 @@ # Loaders testsuite loaders_suite PNG +GIF PBM PGM PPM PNM +PCX ZIP -GIF IO SaveLoad.gen SaveAbort.gen
http://repo.or.cz/w/gfxprim.git/commit/cf801775780f7eab314e2ba9a166edc9ccdd7...
commit cf801775780f7eab314e2ba9a166edc9ccdd708d Author: Cyril Hrubis metan@ucw.cz Date: Mon Jan 27 22:26:21 2014 +0100
Loaders: GP_IOFill: Set errno on end of file.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/libs/loaders/GP_IO.c b/libs/loaders/GP_IO.c index e09df1b..9a5d949 100644 --- a/libs/loaders/GP_IO.c +++ b/libs/loaders/GP_IO.c @@ -295,7 +295,12 @@ int GP_IOFill(GP_IO *io, void *buf, size_t size) ret = GP_IORead(io, (char*)buf + read, size - read);
if (ret <= 0) { - GP_DEBUG(1, "Failed to fill buffer"); + /* end of file */ + if (ret == 0) + errno = EIO; + + GP_DEBUG(1, "Failed to fill buffer: %s", + strerror(errno)); return 1; }
-----------------------------------------------------------------------
Summary of changes: build/syms/Loaders_symbols.txt | 4 + demos/spiv/spiv.1 | 7 +- demos/spiv/spiv_help.c | 7 +- doc/about.txt | 5 + doc/loaders.txt | 42 ++ doc/loaders_python.txt | 1 + include/loaders/GP_Loaders.h | 1 + include/loaders/{GP_JP2.h => GP_PCX.h} | 21 +- libs/loaders/GP_IO.c | 7 +- libs/loaders/GP_Loader.c | 12 +- libs/loaders/GP_PCX.c | 473 ++++++++++++++++++++ pylib/gfxprim/loaders/loaders.i | 4 + tests/loaders/.gitignore | 1 + tests/loaders/Makefile | 5 +- tests/loaders/PCX.c | 174 +++++++ .../pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx | Bin 0 -> 148 bytes .../pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx | Bin 0 -> 148 bytes .../pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx | Bin 0 -> 148 bytes .../pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx | Bin 0 -> 148 bytes .../pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx | Bin 0 -> 148 bytes tests/loaders/test_list.txt | 3 +- 21 files changed, 746 insertions(+), 21 deletions(-) copy include/loaders/{GP_JP2.h => GP_PCX.h} (81%) create mode 100644 libs/loaders/GP_PCX.c create mode 100644 tests/loaders/PCX.c create mode 100644 tests/loaders/data/pcx/valid/ver2_8_palette_4bpp_10x10_white.pcx create mode 100644 tests/loaders/data/pcx/valid/ver3_0_palette_1bpp_10x10_white.pcx create mode 100644 tests/loaders/data/pcx/valid/ver3_0_palette_24bpp_10x10_white.pcx create mode 100644 tests/loaders/data/pcx/valid/ver3_0_palette_2bpp_10x10_white.pcx create mode 100644 tests/loaders/data/pcx/valid/ver3_0_palette_4bpp_10x10_white.pcx
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.