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 af257881668f5639c0e0167e6674e34f979b9a18 (commit) via c39571abe960d7892e9eb06735bfbb49d74352ef (commit) via 27ff06feef1cd3abdbca1ee6267f9e2febe43d6e (commit) via 70edd6e78312f8357776c81f6b5124a96233b5b2 (commit) from 4a428416a87a6b7b1290c8e89d3fc8cfc83fe188 (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/af257881668f5639c0e0167e6674e34f979b9...
commit af257881668f5639c0e0167e6674e34f979b9a18 Author: Cyril Hrubis metan@ucw.cz Date: Sun Feb 16 00:01:07 2014 +0100
loaders: Add PSD thumbnail loader
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/include/loaders/GP_IO.h b/include/loaders/GP_IO.h index fa1046f8..c10befe3 100644 --- a/include/loaders/GP_IO.h +++ b/include/loaders/GP_IO.h @@ -155,6 +155,16 @@ enum GP_IOReadFTypes { GP_IO_I2 = GP_IO_IGN | 2, GP_IO_I3 = GP_IO_IGN | 3, GP_IO_I4 = GP_IO_IGN | 4, + /* + * Photoshop Pascal string + * + * first byte stores size and string is padded to even number bytes. + * + * The lower half stores passed buffer size. + * + * TODO: Unfinished + */ + GP_IO_PPSTR = 0x0800, /* End of the types array */ GP_IO_END = 0xff00, }; @@ -163,6 +173,11 @@ enum GP_IOReadFTypes {
int GP_IOReadF(GP_IO *self, uint16_t *types, ...);
+/* + * GP_IOReadF wrappers for convinient reading of single value + */ +int GP_IOReadB4(GP_IO *io, uint32_t *val); + enum GP_IOFileMode { GP_IO_RDONLY = 0x00, GP_IO_WRONLY = 0x01, diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_Loaders.h index 7ed1727c..a80eb6e2 100644 --- a/include/loaders/GP_Loaders.h +++ b/include/loaders/GP_Loaders.h @@ -19,7 +19,7 @@ * 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 * * * *****************************************************************************/
@@ -44,6 +44,7 @@ #include "loaders/GP_TIFF.h" #include "loaders/GP_PCX.h" #include "loaders/GP_PSP.h" +#include "loaders/GP_PSD.h"
#include "loaders/GP_TmpFile.h"
diff --git a/include/loaders/GP_Loaders.h b/include/loaders/GP_PSD.h similarity index 66% copy from include/loaders/GP_Loaders.h copy to include/loaders/GP_PSD.h index 7ed1727c..8ab5b619 100644 --- a/include/loaders/GP_Loaders.h +++ b/include/loaders/GP_PSD.h @@ -16,42 +16,39 @@ * 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. + PSD thumbnail image loader.
*/
-#ifndef LOADERS_GP_LOADERS_H -#define LOADERS_GP_LOADERS_H +#ifndef LOADERS_GP_PSD_H +#define LOADERS_GP_PSD_H
#include "core/GP_Context.h" #include "core/GP_ProgressCallback.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_PCX.h" -#include "loaders/GP_PSP.h" - -#include "loaders/GP_TmpFile.h" - -#include "loaders/GP_MetaData.h" - -#include "loaders/GP_Loader.h" - -#include "loaders/GP_Container.h" -#include "loaders/GP_ZIP.h" - -#endif /* LOADERS_GP_LOADERS_H */ +#include "loaders/GP_IO.h" + +/* + * Reads a PSD thumbnail 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_ReadPSD(GP_IO *io, GP_ProgressCallback *callback); + +/* + * Loads a PSD image from a file. + */ +GP_Context *GP_LoadPSD(const char *src_path, GP_ProgressCallback *callback); + +/* + * Match PSD signature. + */ +int GP_MatchPSD(const void *buf); + +#endif /* LOADERS_GP_PSD_H */ diff --git a/libs/loaders/GP_IO.c b/libs/loaders/GP_IO.c index 9a5d9492..46009893 100644 --- a/libs/loaders/GP_IO.c +++ b/libs/loaders/GP_IO.c @@ -314,33 +314,44 @@ int GP_IOFill(GP_IO *io, void *buf, size_t size) #define TYPE(x) ((x) & GP_IO_TYPE_MASK) #define VAL(x) ((x) & ~GP_IO_TYPE_MASK)
-static unsigned int readf_size(uint16_t *types) +static void readf_size(uint16_t *types, + unsigned int *min_size, unsigned int *max_size) { - unsigned int size = 0; + unsigned int min = 0; + unsigned int max = 0;
while (*types != GP_IO_END) { switch (TYPE(*types)) { case GP_IO_CONST: case GP_IO_BYTE: - size++; + min++; + max++; break; case GP_IO_L2: case GP_IO_B2: - size += 2; + min += 2; + max += 2; break; case GP_IO_L4: case GP_IO_B4: - size += 4; + min += 4; + max += 4; break; case GP_IO_ARRAY: case GP_IO_IGN: - size+=VAL(*types); + min += VAL(*types); + max += VAL(*types); + break; + case GP_IO_PPSTR: + min += 2; + max += 255; break; } types++; }
- return size; + *min_size = min; + *max_size = max; }
static int needs_swap(uint16_t type) @@ -358,19 +369,36 @@ static int needs_swap(uint16_t type) #endif }
+static void write_str(uint16_t type, uint8_t *dest, + uint8_t *src, unsigned int size) +{ + unsigned int dest_size = VAL(type); + unsigned int i; + + if (!dest_size) + return; + + for (i = 0; i < dest_size - 1 && i < size; i++) + dest[i] = src[i]; + + dest[i] = '0'; +} + int GP_IOReadF(GP_IO *self, uint16_t *types, ...) { - unsigned int size = readf_size(types); + unsigned int read_size, buf_size, size; int ret; va_list va; uint8_t *ptr;
- if (size == 0) + readf_size(types, &read_size, &buf_size); + + if (!read_size) return 0;
- uint8_t buffer[size], *buf = buffer; + uint8_t buffer[buf_size], *buf = buffer;
- if (GP_IOFill(self, buf, size)) + if (GP_IOFill(self, buf, read_size)) return -1;
ret = 0; @@ -427,6 +455,23 @@ int GP_IOReadF(GP_IO *self, uint16_t *types, ...) case GP_IO_IGN: buf += VAL(*types); break; + case GP_IO_PPSTR: + ptr = va_arg(va, void*); + size = *buf; + + /* empty string */ + if (!size) { + write_str(*types, ptr, NULL, 0); + buf += 2; + } else { + /* fill up another part of the buffer */ + if (GP_IOFill(self, buf + read_size, size)) + return -1; + read_size += size; + write_str(*types, ptr, buf + 1, size); + buf += GP_ALIGN2(size + 1); + } + break; }
types++; @@ -437,3 +482,13 @@ end: va_end(va); return ret; } + +int GP_IOReadB4(GP_IO *io, uint32_t *val) +{ + uint16_t desc[] = { + GP_IO_B4, + GP_IO_END + }; + + return GP_IOReadF(io, desc, val) != 1; +} diff --git a/libs/loaders/GP_Loader.c b/libs/loaders/GP_Loader.c index e1f78a5d..d88bf5f6 100644 --- a/libs/loaders/GP_Loader.c +++ b/libs/loaders/GP_Loader.c @@ -39,13 +39,23 @@ #include "loaders/GP_Loaders.h" #include "loaders/GP_Loader.h"
+static GP_Loader psd_loader = { + .Read = GP_ReadPSD, + .Load = GP_LoadPSD, + .Save = NULL, + .Match = GP_MatchPSD, + .fmt_name = "Adobe Photoshop Image", + .next = NULL, + .extensions = {"psd", NULL}, +}; + static GP_Loader psp_loader = { .Read = GP_ReadPSP, .Load = GP_LoadPSP, .Save = NULL, .Match = GP_MatchPSP, .fmt_name = "Paint Shop Pro Image", - .next = NULL, + .next = &psd_loader, .extensions = {"psp", "pspimage", NULL}, };
diff --git a/libs/loaders/GP_PSD.c b/libs/loaders/GP_PSD.c new file mode 100644 index 00000000..3b74a9c9 --- /dev/null +++ b/libs/loaders/GP_PSD.c @@ -0,0 +1,281 @@ +/***************************************************************************** + * 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 * + * * + *****************************************************************************/ + +/* + + Photoshop PSD thumbnail image loader. + + Written using documentation available freely on the internet. + + */ + +#include <stdint.h> +#include <inttypes.h> +#include <string.h> +#include <errno.h> + +#include "core/GP_Debug.h" +#include "core/GP_Common.h" +#include "GP_JPG.h" +#include "GP_PSD.h" + +#define PSD_SIGNATURE "8BPSx00x01" +#define PSD_SIGNATURE_LEN 6 + +int GP_MatchPSD(const void *buf) +{ + return !memcmp(buf, PSD_SIGNATURE, PSD_SIGNATURE_LEN); +} + +enum psd_img_res_id { + PSD_THUMBNAIL_RES40 = 1033, + PSD_THUMBNAIL_RES50 = 1036, +}; + +enum thumbnail_fmt { + PSD_RAW_RGB = 0, + PSD_JPG_RGB = 1, +}; + +static const char *thumbnail_fmt_name(uint16_t fmt) +{ + switch (fmt) { + case PSD_RAW_RGB: + return "Raw RGB"; + case PSD_JPG_RGB: + return "JPEG RGB"; + default: + return "Unknown"; + } +} + +static GP_Context *psd_thumbnail50(GP_IO *io, GP_ProgressCallback *callback) +{ + uint32_t fmt, w, h; + uint16_t bpp, nr_planes; + + uint16_t res_thumbnail_header[] = { + GP_IO_B4, /* Format */ + GP_IO_B4, /* Width */ + GP_IO_B4, /* Height */ + /* + * Widthbytes: + * Padded row bytes = (width * bits per pixel + 31) / 32 * 4 + */ + GP_IO_I4, + GP_IO_I4, /* Total size: widthbytes * height * planes */ + GP_IO_I4, /* Size after compression */ + GP_IO_B2, /* Bits per pixel = 24 */ + GP_IO_B2, /* Number of planes = 1 */ + GP_IO_END, + }; + + if (GP_IOReadF(io, res_thumbnail_header, &fmt, &w, &h, + &bpp, &nr_planes) != 8) { + GP_DEBUG(1, "Failed to read image thumbnail header"); + return NULL; + } + + GP_DEBUG(1, "%"PRIu32"x%"PRIu32" format=%s (%"PRIu16") bpp=%"PRIu16 + " nr_planes=%"PRIu16, w, h, thumbnail_fmt_name(fmt), fmt, + bpp, nr_planes); + + if (fmt != PSD_JPG_RGB) { + GP_DEBUG(1, "Unsupported thumbnail format"); + return NULL; + } + + return GP_ReadJPG(io, callback); +} + +static unsigned int psd_next_img_res_block(GP_IO *io, GP_Context **res, + GP_ProgressCallback *callback) +{ + uint16_t res_id; + uint32_t res_size; + + uint16_t res_block_header[] = { + '8', 'B', 'I', 'M', /* Image resource block signature */ + GP_IO_B2, /* Resource ID */ + //TODO: photoshop pascall string, it's set to 00 00 in most cases though + GP_IO_I2, + GP_IO_B4, /* Resource block size */ + GP_IO_END, + }; + + if (GP_IOReadF(io, res_block_header, &res_id, &res_size) != 7) { + GP_DEBUG(1, "Failed to read image resource header"); + return 0; + } + + GP_DEBUG(1, "Image resource id=%"PRIu16" size=%"PRIu32, + res_id, res_size); + + switch (res_id) { + case PSD_THUMBNAIL_RES40: + GP_DEBUG(1, "Unsupported thumbnail version 4.0"); + break; + case PSD_THUMBNAIL_RES50: + *res = psd_thumbnail50(io, callback); + return 0; + } + + res_size = GP_ALIGN2(res_size); + + if (GP_IOSeek(io, res_size, GP_IO_SEEK_CUR) == (off_t)-1) { + GP_DEBUG(1, "Failed skip image resource"); + return 0; + } + + return res_size + 10; +} + +enum psd_color_mode { + PSD_BITMAP = 0x00, + PSD_GRAYSCALE = 0x01, + PSD_INDEXED = 0x02, + PSD_RGB = 0x03, + PSD_CMYK = 0x04, + PSD_MULTICHANNEL = 0x07, + PSD_DUOTONE = 0x08, + PSD_LAB = 0x09, +}; + +static const char *psd_color_mode_name(uint16_t color_mode) +{ + switch (color_mode) { + case PSD_BITMAP: + return "Bitmap"; + case PSD_GRAYSCALE: + return "Grayscale"; + case PSD_INDEXED: + return "Indexed"; + case PSD_RGB: + return "RGB"; + case PSD_CMYK: + return "CMYK"; + case PSD_MULTICHANNEL: + return "Multichannel"; + case PSD_DUOTONE: + return "Duotone"; + case PSD_LAB: + return "Lab"; + default: + return "Unknown"; + } +} + +GP_Context *GP_ReadPSD(GP_IO *io, GP_ProgressCallback *callback) +{ + int err; + uint32_t w; + uint32_t h; + uint16_t depth; + uint16_t channels; + uint16_t color_mode; + uint32_t len, size, read_size = 0; + + uint16_t psd_header[] = { + '8', 'B', 'P', 'S', + 0x00, 0x01, /* Version always 1 */ + GP_IO_IGN | 6, /* Reserved, should be 0 */ + GP_IO_B2, /* Channels 1 to 56 */ + GP_IO_B4, /* Height */ + GP_IO_B4, /* Width */ + GP_IO_B2, /* Depth (bits per channel) */ + GP_IO_B2, /* Color mode */ + GP_IO_B4, /* Color mode data lenght */ + GP_IO_END + }; + + if (GP_IOReadF(io, psd_header, &channels, &h, &w, &depth, + &color_mode, &len) != 13) { + GP_DEBUG(1, "Failed to read file header"); + err = EIO; + goto err0; + } + + GP_DEBUG(1, "Have PSD %"PRIu32"x%"PRIu32" channels=%"PRIu16"," + " bpp=%"PRIu16" color_mode=%s (%"PRIu16") " + " color_mode_data_len=%"PRIu32, w, h, channels, + depth, psd_color_mode_name(color_mode), color_mode, len); + + switch (color_mode) { + case PSD_INDEXED: + case PSD_DUOTONE: + break; + default: + if (len) + GP_WARN("Color mode_mode_data_len != 0 (is %"PRIu32")" + "for %s (%"PRIu16")", len, + psd_color_mode_name(color_mode), color_mode); + } + + /* Seek after the color mode data */ + if (GP_IOSeek(io, len, GP_IO_SEEK_CUR) == (off_t)-1) { + GP_DEBUG(1, "Failed skip color mode data"); + return NULL; + } + + if (GP_IOReadB4(io, &len)) { + GP_DEBUG(1, "Failed to load Image Resource Section Lenght"); + return NULL; + } + + GP_DEBUG(1, "Image Resource Section length is %x", len); + + GP_Context *res = NULL; + + do { + size = psd_next_img_res_block(io, &res, callback); + + if (!size) + return res; + + read_size += size; + } while (read_size < len); + + errno = ENOSYS; + return NULL; +err0: + errno = err; + return NULL; +} + +GP_Context *GP_LoadPSD(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_ReadPSD(io, callback); + + err = errno; + GP_IOClose(io); + errno = err; + + return res; +}
http://repo.or.cz/w/gfxprim.git/commit/c39571abe960d7892e9eb06735bfbb49d7435...
commit c39571abe960d7892e9eb06735bfbb49d74352ef Author: Cyril Hrubis metan@ucw.cz Date: Sat Feb 15 23:49:02 2014 +0100
core: Add GP_ALIGN2() macro.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h index 5de85469..57d4e131 100644 --- a/include/core/GP_Common.h +++ b/include/core/GP_Common.h @@ -71,6 +71,14 @@ })
/* + * Aligns value to be even + */ +#define GP_ALIGN2(a) ({ + typeof(a) _a = a; + _a + (_a%2); +}) + +/* * Swap a and b using an intermediate variable */ #define GP_SWAP(a, b) do { http://repo.or.cz/w/gfxprim.git/commit/27ff06feef1cd3abdbca1ee6267f9e2febe43...
commit 27ff06feef1cd3abdbca1ee6267f9e2febe43d6e Author: Cyril Hrubis metan@ucw.cz Date: Wed Feb 12 22:59:58 2014 +0100
doc: asciidoc.css: underline links on mouse over.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/doc/asciidoc.css b/doc/asciidoc.css index 11089def..9d4173ad 100644 --- a/doc/asciidoc.css +++ b/doc/asciidoc.css @@ -26,7 +26,7 @@ a, a:visited {
a:hover { font-weight: bolder; - text-decoration: none; + text-decoration: underline ! important; color: OrangeRed ! important; }
http://repo.or.cz/w/gfxprim.git/commit/70edd6e78312f8357776c81f6b5124a96233b...
commit 70edd6e78312f8357776c81f6b5124a96233b5b2 Author: Cyril Hrubis metan@ucw.cz Date: Sat Feb 8 00:52:49 2014 +0100
loaders: ZIP: Propagate errno from GP_ReadImage()
Propagate errno from GP_ReadImage() from zip_next_file() if loading was canceled from callback.
Signed-off-by: Cyril Hrubis metan@ucw.cz
diff --git a/libs/loaders/GP_ZIP.c b/libs/loaders/GP_ZIP.c index c0b417a1..ec80e963 100644 --- a/libs/loaders/GP_ZIP.c +++ b/libs/loaders/GP_ZIP.c @@ -379,6 +379,8 @@ static GP_Context *zip_next_file(struct zip_priv *priv, GP_IOMark(priv->io, GP_IO_MARK);
ret = GP_ReadImage(priv->io, callback); + if (errno == ECANCELED) + err = errno;
GP_IOSeek(priv->io, priv->io->mark + header.comp_size, GP_IO_SEEK_SET);
@@ -391,6 +393,8 @@ static GP_Context *zip_next_file(struct zip_priv *priv, } GP_DEBUG(1, "Reading image"); ret = GP_ReadImage(io, callback); + if (errno == ECANCELED) + err = errno;
GP_IOClose(io); goto out;
-----------------------------------------------------------------------
Summary of changes: doc/asciidoc.css | 2 +- include/core/GP_Common.h | 8 + include/loaders/GP_IO.h | 15 ++ include/loaders/GP_Loaders.h | 3 +- include/loaders/{GP_PCX.h => GP_PSD.h} | 21 +-- libs/loaders/GP_IO.c | 77 ++++++++-- libs/loaders/GP_Loader.c | 12 ++- libs/loaders/GP_PSD.c | 281 ++++++++++++++++++++++++++++++++ libs/loaders/GP_ZIP.c | 4 + 9 files changed, 398 insertions(+), 25 deletions(-) copy include/loaders/{GP_PCX.h => GP_PSD.h} (83%) create mode 100644 libs/loaders/GP_PSD.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.