From 1fa91b23aa74e1881a337a5bcb6a9055282310c4 Mon Sep 17 00:00:00 2001 From: "GMT 1999 Adam D. Moss" Date: Sun, 10 Jan 1999 20:15:45 +0000 Subject: [PATCH] Greatly reduced memory requirements for layered image loading - we now do Sun Jan 10 20:13:13 GMT 1999 Adam D. Moss * plug-ins/psd/psd.c: Greatly reduced memory requirements for layered image loading - we now do just-in-time channel unpacking. Some little cleanups too. --- ChangeLog | 7 + plug-ins/common/psd.c | 417 ++++++++++++++++++++++++------------------ plug-ins/psd/psd.c | 417 ++++++++++++++++++++++++------------------ 3 files changed, 481 insertions(+), 360 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d09a76c2b..8a5bc703c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun Jan 10 20:13:13 GMT 1999 Adam D. Moss + + * plug-ins/psd/psd.c: + Greatly reduced memory requirements for layered image loading - + we now do just-in-time channel unpacking. Some little + cleanups too. + Sat Jan 9 21:24:20 PST 1999 Manish Singh * autogen.sh: rework to do gcg by ourselves diff --git a/plug-ins/common/psd.c b/plug-ins/common/psd.c index a676433a56..2151758f9d 100644 --- a/plug-ins/common/psd.c +++ b/plug-ins/common/psd.c @@ -1,5 +1,5 @@ /* - * PSD Plugin version 2.0.0 + * PSD Plugin version 2.0.1 * This GIMP plug-in is designed to load Adobe Photoshop(tm) files (.PSD) * * Adam D. Moss @@ -35,67 +35,68 @@ /* * Revision history: * - * 98.09.04 / v2.0.0 / Adam D. Moss + * 1999.01.10 / v2.0.1 / Adam D. Moss + * Greatly reduced memory requirements for layered image loading - + * we now do just-in-time channel unpacking. Some little + * cleanups too. + * + * 1998.09.04 / v2.0.0 / Adam D. Moss * Now recognises and loads the new Guides extensions written * by Photoshop 4 and 5. * - * 98.07.31 / v1.9.9.9f / Adam D. Moss + * 1998.07.31 / v1.9.9.9f / Adam D. Moss * Use OVERLAY_MODE if available. * - * 98.07.31 / v1.9.9.9e / Adam D. Moss + * 1998.07.31 / v1.9.9.9e / Adam D. Moss * Worked around some buggy PSD savers (suspect PS4 on Mac) - ugh. * Fixed a bug when loading layer masks of certain dimensions. * - * 98.05.04 / v1.9.9.9b / Adam D. Moss + * 1998.05.04 / v1.9.9.9b / Adam D. Moss * Changed the Pascal-style string-reading stuff. That fixed * some file-padding problems. Made all debugging output * compile-time optional (please leave it enabled for now). * Reduced memory requirements; still much room for improvement. * - * 98.04.28 / v1.9.9.9 / Adam D. Moss + * 1998.04.28 / v1.9.9.9 / Adam D. Moss * Fixed the correct channel interlacing of 'raw' flat images. * Thanks to Christian Kirsch and Jay Cox for spotting this. * Changed some of the I/O routines. * - * 98.04.26 / v1.9.9.8 / Adam D. Moss + * 1998.04.26 / v1.9.9.8 / Adam D. Moss * Implemented Aux-channels for layered files. Got rid * of nonsense. Improved Layer Mask padding. * Enforced num_layers/num_channels limit checks. * - * 98.04.23 / v1.9.9.5 / Adam D. Moss + * 1998.04.23 / v1.9.9.5 / Adam D. Moss * Got Layer Masks working, got Aux-channels working * for unlayered files, fixed 'raw' channel loading, fixed * some other mini-bugs, slightly better progress meters. * Thanks to everyone who is helping with the testing! * - * 98.04.21 / v1.9.9.1 / Adam D. Moss + * 1998.04.21 / v1.9.9.1 / Adam D. Moss * A little cleanup. Implemented Layer Masks but disabled * them again - PS masks can be a different size to their * owning layer, unlike those in GIMP. * - * 98.04.19 / v1.9.9.0 / Adam D. Moss + * 1998.04.19 / v1.9.9.0 / Adam D. Moss * Much happier now. * - * 97.03.13 / v1.9.0 / Adam D. Moss + * 1997.03.13 / v1.9.0 / Adam D. Moss * Layers, channels and masks, oh my. * + Bugfixes & rearchitecturing. * - * 97.01.30 / v1.0.12 / Torsten Martinsen + * 1997.01.30 / v1.0.12 / Torsten Martinsen * Flat PSD image loading. */ /* * TODO: * - * Crush 16bpp channels + * Crush 16bpp channels (Wait until GIMP 2.0, probably) * CMYK -> RGB * Load BITMAP mode * - * File saving. (I am unlikely to be able to do this for - * practical reasons. Suggest someone works on it as a - * separate plugin - please let me know.) - * - * Reduce memory requirements! + * File saving */ /* @@ -106,7 +107,7 @@ -/* *** DEFINES *** */ +/* *** USER DEFINES *** */ /* set to TRUE if you want debugging, FALSE otherwise */ #define PSD_DEBUG TRUE @@ -120,7 +121,7 @@ /* the max number of guides that this plugin should let an image have */ #define MAX_GUIDES 200 -/* *** END OF DEFINES *** */ +/* *** END OF USER DEFINES *** */ @@ -149,35 +150,6 @@ typedef enum } psd_imagetype; - -/* Declare some local functions. - */ -static void query (void); -static void run (char *name, - int nparams, - GParam *param, - int *nreturn_vals, - GParam **return_vals); -GDrawableType psd_type_to_gimp_type - (psd_imagetype psdtype); -GImageType psd_type_to_gimp_base_type - (psd_imagetype psdtype); -GLayerMode psd_lmode_to_gimp_lmode - (gchar modekey[4]); -static gint32 load_image (char *filename); - - - -GPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - - - typedef struct PsdChannel { gchar *name; @@ -185,11 +157,21 @@ typedef struct PsdChannel gint type; guint32 compressedsize; + + fpos_t fpos; /* Remember where the data is in the file, so we can + come back to it! */ + + /* We can't just assume that the channel's width and height are the + * same as those of the layer that owns the channel, since this + * channel may be a layer mask, which Photoshop allows to have a + * different size from the layer which it applies to. + */ + guint32 width; + guint32 height; } PSDchannel; - typedef struct PsdGuide { gboolean horizontal; /* else vertical */ @@ -197,7 +179,6 @@ typedef struct PsdGuide } PSDguide; - typedef struct PsdLayer { gint num_channels; @@ -225,7 +206,6 @@ typedef struct PsdLayer } PSDlayer; - typedef struct PsdImage { gint num_layers; @@ -247,15 +227,42 @@ typedef struct PsdImage gchar *caption; guint active_layer_num; - } PSDimage; -static PSDimage psd_image; +/* Declare some local functions. + */ +static void query (void); +static void run (char *name, + int nparams, + GParam *param, + int *nreturn_vals, + GParam **return_vals); +static GDrawableType psd_type_to_gimp_type + (psd_imagetype psdtype); +static GImageType psd_type_to_gimp_base_type + (psd_imagetype psdtype); +static GLayerMode psd_lmode_to_gimp_lmode + (gchar modekey[4]); +static gint32 load_image (char *filename); +/* Various local variables... + */ +GPlugInInfo PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + query, /* query_proc */ + run, /* run_proc */ +}; + + +static PSDimage psd_image; + + static struct { gchar signature[4]; gushort version; @@ -312,8 +319,9 @@ static void read_whole_file(FILE *fd); static void reshuffle_cmap(guchar *map256); static guchar* getpascalstring(FILE *fd, gchar *why); static gchar* getstring(size_t n, FILE * fd, gchar *why); -void throwchunk(size_t n, FILE * fd, gchar *why); -void dumpchunk(size_t n, FILE * fd, gchar *why); +static void throwchunk(size_t n, FILE * fd, gchar *why); +static void dumpchunk(size_t n, FILE * fd, gchar *why); +static void seek_to_and_unpack_pixeldata(FILE* fd, gint layeri, gint channeli); MAIN() @@ -390,7 +398,7 @@ run (char *name, } -GDrawableType +static GDrawableType psd_type_to_gimp_type (psd_imagetype psdtype) { switch(psdtype) @@ -407,7 +415,7 @@ psd_type_to_gimp_type (psd_imagetype psdtype) -GLayerMode +static GLayerMode psd_lmode_to_gimp_lmode (gchar modekey[4]) { if (strncmp(modekey, "norm", 4)==0) return(NORMAL_MODE); @@ -444,7 +452,7 @@ psd_lmode_to_gimp_lmode (gchar modekey[4]) -GImageType +static GImageType psd_type_to_gimp_base_type (psd_imagetype psdtype) { switch(psdtype) @@ -787,7 +795,10 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size) default: IFDBG printf ("\t\t\n"); - dumpchunk(Size, fd, "dispatch_res"); + IFDBG + dumpchunk(Size, fd, "dispatch_res"); + else + throwchunk(Size, fd, "dispatch_res"); (*offset) += Size; break; } @@ -1013,9 +1024,7 @@ do_layer_struct(FILE *fd, guint32 *offset) static void do_layer_pixeldata(FILE *fd, guint32 *offset) { - guint16 compression; gint layeri, channeli; - guchar *tmpline; for (layeri=0; layeri 0) && @@ -1821,7 +1859,7 @@ load_image(char *name) - if (want_aux || (psd_image.num_layers==0)) /* PS2-style - NO LAYERS. */ + if (want_aux || (psd_image.num_layers==0)) /* Photoshop2-style: NO LAYERS. */ { IFDBG printf("Image data %ld chars\n", PSDheader.imgdatalen); @@ -1879,7 +1917,8 @@ load_image(char *name) if (PSDheader.bpp != 8) { - printf("%s: The GIMP only supports 8-bit deep PSD images\n", + printf("%s: The GIMP only supports 8-bit deep PSD images " + "at this time.\n", prog_name); return(-1); } @@ -1963,9 +2002,6 @@ load_image(char *name) dest = xmalloc( step * PSDheader.columns * PSDheader.rows ); - gimp_progress_update ((double)0.0); - - if (PSDheader.compression == 1) { nguchars = PSDheader.columns * PSDheader.rows; @@ -1973,16 +2009,15 @@ load_image(char *name) xfread(fd, temp, PSDheader.imgdatalen, "image data"); if (!cmyk) { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); decode(PSDheader.imgdatalen, nguchars, temp, dest, step); } else { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); cmykbuf = xmalloc(step * nguchars); decode(PSDheader.imgdatalen, nguchars, temp, cmykbuf, step); - gimp_progress_update ((double)0.50); cmyk2rgb(cmykbuf, dest, PSDheader.columns, PSDheader.rows, step > 4); g_free(cmykbuf); @@ -1993,18 +2028,17 @@ load_image(char *name) { if (!cmyk) { - gimp_progress_update ((double)0.50); + gimp_progress_update ((double)1.00); xfread_interlaced(fd, dest, PSDheader.imgdatalen, "raw image data", step); } else { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); cmykbuf = xmalloc(PSDheader.imgdatalen); xfread_interlaced(fd, cmykbuf, PSDheader.imgdatalen, "raw cmyk image data", step); - gimp_progress_update ((double)0.50); cmykp2rgb(cmykbuf, dest, PSDheader.columns, PSDheader.rows, step > 4); g_free(cmykbuf); @@ -2022,7 +2056,7 @@ load_image(char *name) } else { - gimp_progress_update ((double)0.96); + gimp_progress_update ((double)1.00); if (channels == step) /* gimp bpp == psd bpp */ { @@ -2100,18 +2134,27 @@ decode(long clen, long uclen, char * src, char * dst, int step) l = clen; for (i = 0; i < PSDheader.rows*PSDheader.channels; ++i) + { l -= PSDheader.rowlength[i]; + } if (l) + { g_warning("decode: %ld should be zero\n", (long)l); + } w = PSDheader.rowlength; packbitsdecode(&clen, uclen, src, dst++, step); - for (j = 0; j < step-1; ++j) { + + for (j = 0; j < step-1; ++j) + { for (i = 0; i < PSDheader.rows; ++i) + { src += *w++; + } packbitsdecode(&clen, uclen, src, dst++, step); - } + } + IFDBG printf("clen %ld\n", clen); } @@ -2308,7 +2351,7 @@ cmyk_to_rgb(gint *c, gint *m, gint *y, gint *k) } -void +static void dumpchunk(size_t n, FILE * fd, gchar *why) { guint32 i; @@ -2324,9 +2367,10 @@ dumpchunk(size_t n, FILE * fd, gchar *why) } -void +static void throwchunk(size_t n, FILE * fd, gchar *why) { +#if 0 guchar *tmpchunk; if (n==0) @@ -2337,6 +2381,19 @@ throwchunk(size_t n, FILE * fd, gchar *why) tmpchunk = xmalloc(n); xfread(fd, tmpchunk, n, why); g_free(tmpchunk); +#else + if (n==0) + { + return; + } + + if (fseek(fd, n, SEEK_CUR) != 0) + { + printf("%s: unable to seek forward while reading '%s' chunk\n", + prog_name, why); + gimp_quit(); + } +#endif } diff --git a/plug-ins/psd/psd.c b/plug-ins/psd/psd.c index a676433a56..2151758f9d 100644 --- a/plug-ins/psd/psd.c +++ b/plug-ins/psd/psd.c @@ -1,5 +1,5 @@ /* - * PSD Plugin version 2.0.0 + * PSD Plugin version 2.0.1 * This GIMP plug-in is designed to load Adobe Photoshop(tm) files (.PSD) * * Adam D. Moss @@ -35,67 +35,68 @@ /* * Revision history: * - * 98.09.04 / v2.0.0 / Adam D. Moss + * 1999.01.10 / v2.0.1 / Adam D. Moss + * Greatly reduced memory requirements for layered image loading - + * we now do just-in-time channel unpacking. Some little + * cleanups too. + * + * 1998.09.04 / v2.0.0 / Adam D. Moss * Now recognises and loads the new Guides extensions written * by Photoshop 4 and 5. * - * 98.07.31 / v1.9.9.9f / Adam D. Moss + * 1998.07.31 / v1.9.9.9f / Adam D. Moss * Use OVERLAY_MODE if available. * - * 98.07.31 / v1.9.9.9e / Adam D. Moss + * 1998.07.31 / v1.9.9.9e / Adam D. Moss * Worked around some buggy PSD savers (suspect PS4 on Mac) - ugh. * Fixed a bug when loading layer masks of certain dimensions. * - * 98.05.04 / v1.9.9.9b / Adam D. Moss + * 1998.05.04 / v1.9.9.9b / Adam D. Moss * Changed the Pascal-style string-reading stuff. That fixed * some file-padding problems. Made all debugging output * compile-time optional (please leave it enabled for now). * Reduced memory requirements; still much room for improvement. * - * 98.04.28 / v1.9.9.9 / Adam D. Moss + * 1998.04.28 / v1.9.9.9 / Adam D. Moss * Fixed the correct channel interlacing of 'raw' flat images. * Thanks to Christian Kirsch and Jay Cox for spotting this. * Changed some of the I/O routines. * - * 98.04.26 / v1.9.9.8 / Adam D. Moss + * 1998.04.26 / v1.9.9.8 / Adam D. Moss * Implemented Aux-channels for layered files. Got rid * of nonsense. Improved Layer Mask padding. * Enforced num_layers/num_channels limit checks. * - * 98.04.23 / v1.9.9.5 / Adam D. Moss + * 1998.04.23 / v1.9.9.5 / Adam D. Moss * Got Layer Masks working, got Aux-channels working * for unlayered files, fixed 'raw' channel loading, fixed * some other mini-bugs, slightly better progress meters. * Thanks to everyone who is helping with the testing! * - * 98.04.21 / v1.9.9.1 / Adam D. Moss + * 1998.04.21 / v1.9.9.1 / Adam D. Moss * A little cleanup. Implemented Layer Masks but disabled * them again - PS masks can be a different size to their * owning layer, unlike those in GIMP. * - * 98.04.19 / v1.9.9.0 / Adam D. Moss + * 1998.04.19 / v1.9.9.0 / Adam D. Moss * Much happier now. * - * 97.03.13 / v1.9.0 / Adam D. Moss + * 1997.03.13 / v1.9.0 / Adam D. Moss * Layers, channels and masks, oh my. * + Bugfixes & rearchitecturing. * - * 97.01.30 / v1.0.12 / Torsten Martinsen + * 1997.01.30 / v1.0.12 / Torsten Martinsen * Flat PSD image loading. */ /* * TODO: * - * Crush 16bpp channels + * Crush 16bpp channels (Wait until GIMP 2.0, probably) * CMYK -> RGB * Load BITMAP mode * - * File saving. (I am unlikely to be able to do this for - * practical reasons. Suggest someone works on it as a - * separate plugin - please let me know.) - * - * Reduce memory requirements! + * File saving */ /* @@ -106,7 +107,7 @@ -/* *** DEFINES *** */ +/* *** USER DEFINES *** */ /* set to TRUE if you want debugging, FALSE otherwise */ #define PSD_DEBUG TRUE @@ -120,7 +121,7 @@ /* the max number of guides that this plugin should let an image have */ #define MAX_GUIDES 200 -/* *** END OF DEFINES *** */ +/* *** END OF USER DEFINES *** */ @@ -149,35 +150,6 @@ typedef enum } psd_imagetype; - -/* Declare some local functions. - */ -static void query (void); -static void run (char *name, - int nparams, - GParam *param, - int *nreturn_vals, - GParam **return_vals); -GDrawableType psd_type_to_gimp_type - (psd_imagetype psdtype); -GImageType psd_type_to_gimp_base_type - (psd_imagetype psdtype); -GLayerMode psd_lmode_to_gimp_lmode - (gchar modekey[4]); -static gint32 load_image (char *filename); - - - -GPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - - - typedef struct PsdChannel { gchar *name; @@ -185,11 +157,21 @@ typedef struct PsdChannel gint type; guint32 compressedsize; + + fpos_t fpos; /* Remember where the data is in the file, so we can + come back to it! */ + + /* We can't just assume that the channel's width and height are the + * same as those of the layer that owns the channel, since this + * channel may be a layer mask, which Photoshop allows to have a + * different size from the layer which it applies to. + */ + guint32 width; + guint32 height; } PSDchannel; - typedef struct PsdGuide { gboolean horizontal; /* else vertical */ @@ -197,7 +179,6 @@ typedef struct PsdGuide } PSDguide; - typedef struct PsdLayer { gint num_channels; @@ -225,7 +206,6 @@ typedef struct PsdLayer } PSDlayer; - typedef struct PsdImage { gint num_layers; @@ -247,15 +227,42 @@ typedef struct PsdImage gchar *caption; guint active_layer_num; - } PSDimage; -static PSDimage psd_image; +/* Declare some local functions. + */ +static void query (void); +static void run (char *name, + int nparams, + GParam *param, + int *nreturn_vals, + GParam **return_vals); +static GDrawableType psd_type_to_gimp_type + (psd_imagetype psdtype); +static GImageType psd_type_to_gimp_base_type + (psd_imagetype psdtype); +static GLayerMode psd_lmode_to_gimp_lmode + (gchar modekey[4]); +static gint32 load_image (char *filename); +/* Various local variables... + */ +GPlugInInfo PLUG_IN_INFO = +{ + NULL, /* init_proc */ + NULL, /* quit_proc */ + query, /* query_proc */ + run, /* run_proc */ +}; + + +static PSDimage psd_image; + + static struct { gchar signature[4]; gushort version; @@ -312,8 +319,9 @@ static void read_whole_file(FILE *fd); static void reshuffle_cmap(guchar *map256); static guchar* getpascalstring(FILE *fd, gchar *why); static gchar* getstring(size_t n, FILE * fd, gchar *why); -void throwchunk(size_t n, FILE * fd, gchar *why); -void dumpchunk(size_t n, FILE * fd, gchar *why); +static void throwchunk(size_t n, FILE * fd, gchar *why); +static void dumpchunk(size_t n, FILE * fd, gchar *why); +static void seek_to_and_unpack_pixeldata(FILE* fd, gint layeri, gint channeli); MAIN() @@ -390,7 +398,7 @@ run (char *name, } -GDrawableType +static GDrawableType psd_type_to_gimp_type (psd_imagetype psdtype) { switch(psdtype) @@ -407,7 +415,7 @@ psd_type_to_gimp_type (psd_imagetype psdtype) -GLayerMode +static GLayerMode psd_lmode_to_gimp_lmode (gchar modekey[4]) { if (strncmp(modekey, "norm", 4)==0) return(NORMAL_MODE); @@ -444,7 +452,7 @@ psd_lmode_to_gimp_lmode (gchar modekey[4]) -GImageType +static GImageType psd_type_to_gimp_base_type (psd_imagetype psdtype) { switch(psdtype) @@ -787,7 +795,10 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size) default: IFDBG printf ("\t\t\n"); - dumpchunk(Size, fd, "dispatch_res"); + IFDBG + dumpchunk(Size, fd, "dispatch_res"); + else + throwchunk(Size, fd, "dispatch_res"); (*offset) += Size; break; } @@ -1013,9 +1024,7 @@ do_layer_struct(FILE *fd, guint32 *offset) static void do_layer_pixeldata(FILE *fd, guint32 *offset) { - guint16 compression; gint layeri, channeli; - guchar *tmpline; for (layeri=0; layeri 0) && @@ -1821,7 +1859,7 @@ load_image(char *name) - if (want_aux || (psd_image.num_layers==0)) /* PS2-style - NO LAYERS. */ + if (want_aux || (psd_image.num_layers==0)) /* Photoshop2-style: NO LAYERS. */ { IFDBG printf("Image data %ld chars\n", PSDheader.imgdatalen); @@ -1879,7 +1917,8 @@ load_image(char *name) if (PSDheader.bpp != 8) { - printf("%s: The GIMP only supports 8-bit deep PSD images\n", + printf("%s: The GIMP only supports 8-bit deep PSD images " + "at this time.\n", prog_name); return(-1); } @@ -1963,9 +2002,6 @@ load_image(char *name) dest = xmalloc( step * PSDheader.columns * PSDheader.rows ); - gimp_progress_update ((double)0.0); - - if (PSDheader.compression == 1) { nguchars = PSDheader.columns * PSDheader.rows; @@ -1973,16 +2009,15 @@ load_image(char *name) xfread(fd, temp, PSDheader.imgdatalen, "image data"); if (!cmyk) { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); decode(PSDheader.imgdatalen, nguchars, temp, dest, step); } else { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); cmykbuf = xmalloc(step * nguchars); decode(PSDheader.imgdatalen, nguchars, temp, cmykbuf, step); - gimp_progress_update ((double)0.50); cmyk2rgb(cmykbuf, dest, PSDheader.columns, PSDheader.rows, step > 4); g_free(cmykbuf); @@ -1993,18 +2028,17 @@ load_image(char *name) { if (!cmyk) { - gimp_progress_update ((double)0.50); + gimp_progress_update ((double)1.00); xfread_interlaced(fd, dest, PSDheader.imgdatalen, "raw image data", step); } else { - gimp_progress_update ((double)0.25); + gimp_progress_update ((double)1.00); cmykbuf = xmalloc(PSDheader.imgdatalen); xfread_interlaced(fd, cmykbuf, PSDheader.imgdatalen, "raw cmyk image data", step); - gimp_progress_update ((double)0.50); cmykp2rgb(cmykbuf, dest, PSDheader.columns, PSDheader.rows, step > 4); g_free(cmykbuf); @@ -2022,7 +2056,7 @@ load_image(char *name) } else { - gimp_progress_update ((double)0.96); + gimp_progress_update ((double)1.00); if (channels == step) /* gimp bpp == psd bpp */ { @@ -2100,18 +2134,27 @@ decode(long clen, long uclen, char * src, char * dst, int step) l = clen; for (i = 0; i < PSDheader.rows*PSDheader.channels; ++i) + { l -= PSDheader.rowlength[i]; + } if (l) + { g_warning("decode: %ld should be zero\n", (long)l); + } w = PSDheader.rowlength; packbitsdecode(&clen, uclen, src, dst++, step); - for (j = 0; j < step-1; ++j) { + + for (j = 0; j < step-1; ++j) + { for (i = 0; i < PSDheader.rows; ++i) + { src += *w++; + } packbitsdecode(&clen, uclen, src, dst++, step); - } + } + IFDBG printf("clen %ld\n", clen); } @@ -2308,7 +2351,7 @@ cmyk_to_rgb(gint *c, gint *m, gint *y, gint *k) } -void +static void dumpchunk(size_t n, FILE * fd, gchar *why) { guint32 i; @@ -2324,9 +2367,10 @@ dumpchunk(size_t n, FILE * fd, gchar *why) } -void +static void throwchunk(size_t n, FILE * fd, gchar *why) { +#if 0 guchar *tmpchunk; if (n==0) @@ -2337,6 +2381,19 @@ throwchunk(size_t n, FILE * fd, gchar *why) tmpchunk = xmalloc(n); xfread(fd, tmpchunk, n, why); g_free(tmpchunk); +#else + if (n==0) + { + return; + } + + if (fseek(fd, n, SEEK_CUR) != 0) + { + printf("%s: unable to seek forward while reading '%s' chunk\n", + prog_name, why); + gimp_quit(); + } +#endif }