applied slightly modified patch from Eric Ross that adds support for

2007-06-12  Sven Neumann  <sven@gimp.org>

	* plug-ins/common/psd-load.c: applied slightly modified patch 
from
	Eric Ross that adds support for loading long layer names from 
the
	extra layer data section (bug #445316).


svn path=/trunk/; revision=22763
This commit is contained in:
Sven Neumann
2007-06-12 06:37:34 +00:00
committed by Sven Neumann
parent 5d14b8d2a4
commit dfeaec0861
2 changed files with 337 additions and 116 deletions

View File

@ -1,3 +1,9 @@
2007-06-12 Sven Neumann <sven@gimp.org>
* plug-ins/common/psd-load.c: applied slightly modified patch from
Eric Ross that adds support for loading long layer names from the
extra layer data section (bug #445316).
2007-06-11 Sven Neumann <sven@gimp.org> 2007-06-11 Sven Neumann <sven@gimp.org>
Applied patch from Zbigniew Chyla that further improves the Applied patch from Zbigniew Chyla that further improves the

View File

@ -378,56 +378,58 @@ static void unpack_pb_channel (FILE *fd,
guint32 *offset); guint32 *offset);
static void decode (long clen, static void decode (long clen,
long uclen, long uclen,
guchar *src, const guchar *src,
guchar *dst, guchar *dst,
int step); int step);
static void packbitsdecode (long *clenp, static void packbitsdecode (long *clenp,
long uclen, long uclen,
guchar *src, const guchar *src,
guchar *dst, guchar *dst,
int step); int step);
static void cmyk2rgb (guchar *src, static void cmyk2rgb (const guchar *src,
guchar *destp, guchar *destp,
long width, long width,
long height, long height,
int alpha); int alpha);
static void cmykp2rgb (guchar *src, static void cmykp2rgb (const guchar *src,
guchar *destp, guchar *destp,
long width, long width,
long height, long height,
int alpha); int alpha);
static void bitmap2gray (guchar *src, static void bitmap2gray (const guchar *src,
guchar *dest, guchar *dest,
long w, long w,
long h); long h);
static guchar getguchar (FILE *fd, static guchar getguchar (FILE *fd,
gchar *why); const gchar *why);
static gint16 getgint16 (FILE *fd, static gint16 getgint16 (FILE *fd,
gchar *why); const gchar *why);
static gint32 getgint32 (FILE *fd, static gint32 getgint32 (FILE *fd,
gchar *why); const gchar *why);
static void xfread (FILE *fd, static void xfread (FILE *fd,
void *buf, void *buf,
long len, long len,
gchar *why); const gchar *why);
static void xfread_interlaced (FILE *fd, static void xfread_interlaced (FILE *fd,
guchar *buf, guchar *buf,
long len, long len,
gchar *why, const gchar *why,
gint step); gint step);
static void read_whole_file (FILE *fd); static void read_whole_file (FILE *fd);
static void reshuffle_cmap (guchar *map256); static void reshuffle_cmap (guchar *map256);
static gchar *getpascalstring (FILE *fd, static gchar *getpascalstring (FILE *fd,
gchar *why); const gchar *why);
static gchar *getunicodepascalstring (FILE *fd,
const gchar *why);
static gchar *getstring (size_t n, static gchar *getstring (size_t n,
FILE *fd, FILE *fd,
gchar *why); const gchar *why);
static void throwchunk (size_t n, static void throwchunk (size_t n,
FILE *fd, FILE *fd,
gchar *why); const gchar *why);
static void dumpchunk (size_t n, static void dumpchunk (size_t n,
FILE *fd, FILE *fd,
gchar *why); const gchar *why);
static void seek_to_and_unpack_pixeldata (FILE *fd, static void seek_to_and_unpack_pixeldata (FILE *fd,
gint layeri, gint layeri,
gint channeli); gint channeli);
@ -1019,6 +1021,12 @@ do_layer_record (FILE *fd,
guchar flags; guchar flags;
gint i; gint i;
/* Info used for extra data blocks */
guchar numpadchars;
guint32 xdsignature;
guint32 xdkey;
guint32 xdsize;
IFDBG printf("\t\t\tLAYER RECORD (layer %d)\n", (int)layernum); IFDBG printf("\t\t\tLAYER RECORD (layer %d)\n", (int)layernum);
layer = psd_image.layer + layernum; layer = psd_image.layer + layernum;
@ -1188,11 +1196,187 @@ do_layer_record (FILE *fd,
(*offset) += strlen (layer->name); (*offset) += strlen (layer->name);
IFDBG printf("\t\t\t\t\t\tLAYER NAME: '%s'\n", layer->name); IFDBG printf("\t\t\t\t\t\tLAYER NAME: '%s'\n", layer->name);
layer->name = sanitise_string (layer->name); layer->name = sanitise_string (layer->name);
/* Layer name string lengths are padded to be divisible by 4 */
numpadchars = 4-((1+strlen(layer->name)) % 4);
if (numpadchars == 4)
numpadchars = 0;
if (numpadchars)
{
throwchunk (numpadchars, fd, "layer record extra data block throw");
(*offset) += numpadchars;
}
} }
else else
{ {
IFDBG printf ("\t\t\t\t\t\tNULL LAYER NAME\n"); IFDBG printf ("\t\t\t\t\t\tNULL LAYER NAME\n");
} }
/*
The remaining data in this layer contains any number of blocks that follow
this structure:
4 bytes for signature (always 8BIM)
4 bytes for a key to define kind of data
4 bytes for size of data to follow
? bytes of data
*/
IFDBG printf ("\t\t\t\t\tLAYER EXTRA DATA BLOCKS\n");
/* The order of these blocks sometimes varies so read all blocks. */
while (totaloff-(*offset) > 12)
{
guint32 topofblock = ftell (fd);
xdsignature = getgint32 (fd, "layer extra data block signature");
xdkey = getgint32 (fd, "layer extra data block key");
xdsize = getgint32 (fd, "layer extra data block size");
IFDBG
{
printf ("\t\t\t\t\t\tKEY: 0x%08x '%c%c%c%c' / Size: 0x%04x ", xdkey,
((gchar*)(&xdkey))[3], ((gchar*)(&xdkey))[2],
((gchar*)(&xdkey))[1], ((gchar*)(&xdkey))[0], xdsize);
}
switch (xdkey)
{
/* luni: Long unicode name */
case 0x6c756e69:
if (layer->name)
g_free (layer->name);
layer->name = getunicodepascalstring (fd, "layer name");
if (layer->name)
layer->name = sanitise_string (layer->name);
IFDBG printf ("Long Layer Name: '%s'\n",layer->name);
break;
/* lyid: Layer id number */
case 0x6c796964:
{
guint32 idnum = getgint32 (fd, "layer extra data block lyid");
IFDBG printf ("Layer ID #%d\n",idnum);
}
break;
/* iOpa: Layer Fill (opacity?) */
case 0x694f7061:
{
guchar fill = getguchar (fd, "layer extra data block fill");
throwchunk (xdsize-1, fd, "iOpa: Layer Fill padding throw");
IFDBG printf ("Layer Fill = %d (%d%%)\n", fill, (100 * fill) / 255);
}
break;
/* lclr: Layer Color */
case 0x6c636c72:
{
guint16 labelcolor = getgint16 (fd, "lclr: Layer Color");
throwchunk (xdsize-2, fd, "lclr: Layer Color padding throw");
IFDBG
{
printf ("Layer Color=%d ",labelcolor);
switch (labelcolor)
{
case 0: printf ("None\n"); break;
case 1: printf ("Red\n"); break;
case 2: printf ("Orange\n"); break;
case 3: printf ("Yellow\n"); break;
case 4: printf ("Green\n"); break;
case 5: printf ("Blue\n"); break;
case 6: printf ("Violet\n"); break;
case 7: printf ("Grey\n"); break;
default: printf ("Undefined\n");
}
}
}
break;
/* lsct: Layer Set Controls Type */
case 0x6c736374:
{
guint32 lscttype;
guint32 blendsignature;
guint32 blendkey;
lscttype = getgint32 (fd, "layer extra data block lsct type");
IFDBG printf ("Layer Set Controls:\n\t\t\t\t\t\t\tType = 0x%08x ", lscttype);
switch (lscttype)
{
case 1:
case 2:
blendsignature = getgint32 (fd, "layer extra data block lsct");
blendkey = getgint32 (fd, "layer extra data block lsct");
IFDBG
{
printf ("Close layer set.\n\t\t\t\t\t\t\tBlend = 0x%08x '%c%c%c%c'\n",
blendkey,
((gchar*)(&blendkey))[3],
((gchar*)(&blendkey))[2],
((gchar*)(&blendkey))[1],
((gchar*)(&blendkey))[0]);
}
if (xdsize-12)
throwchunk (xdsize-12, fd, "lsct: Layer Set Controls throw");
break;
case 3:
IFDBG printf ("Open layer set.\n");
if (xdsize-4)
throwchunk (xdsize-4, fd, "lsct: Layer Set Controls throw");
break;
default:
IFDBG printf ("Unknown\n");
if (xdsize-4)
throwchunk (xdsize-4, fd, "lsct: Layer Set Controls throw");
}
}
break;
/* lnsr: Some sort of layer type key. */
case 0x6c6e7372:
{
guint32 lnsr = getgint32 (fd, "layer extra data block lnsr");
IFDBG
{
printf ("lnsr = 0x%08x '%c%c%c%c'\n", lnsr,
((guchar*)(&lnsr))[3], ((guchar*)(&lnsr))[2],
((guchar*)(&lnsr))[1], ((guchar*)(&lnsr))[0]);
switch (lnsr)
{
case 0x62676e64: /* 'bgnd' */
printf ("\t\t\t\t\t\t\t(background?)\n");
break;
case 0x6c617972: /* 'layr' */
printf ("\t\t\t\t\t\t\t(Layer?)\n");
break;
case 0x6c736574: /* 'lset' */
printf ("\t\t\t\t\t\t\tNew layer set.\n");
break;
default:
printf ("\t\t\t\t\t\t\tUnknown\n");
}
}
}
break;
/* These 2 contain all of the settings for the different layer styles. */
case 0x6c724658: /* lrFX: Layer effects settings. */
case 0x6c667832: /* lfx2: More Layer effects settings. */
default:
IFDBG printf ( "<Undefined Block>\n" );
throwchunk (xdsize, fd, "layer record extra data block throw");
}
(*offset) += ftell (fd) - topofblock;
}
/* If no layermask data - set offset and size from layer data */ /* If no layermask data - set offset and size from layer data */
if (! layermaskdatasize) if (! layermaskdatasize)
{ {
@ -2513,7 +2697,7 @@ load_image (const gchar *name)
static void static void
decode (long clen, decode (long clen,
long uclen, long uclen,
guchar *src, const guchar *src,
guchar *dst, guchar *dst,
int step) int step)
{ {
@ -2554,7 +2738,7 @@ decode (long clen,
static void static void
packbitsdecode (long *clenp, packbitsdecode (long *clenp,
long uclen, long uclen,
guchar *src, const guchar *src,
guchar *dst, guchar *dst,
int step) int step)
{ {
@ -2677,8 +2861,8 @@ unpack_pb_channel (FILE *fd,
} }
static void static void
cmyk2rgb (unsigned char *src, cmyk2rgb (const guchar *src,
unsigned char *dst, guchar *dst,
long width, long width,
long height, long height,
int alpha) int alpha)
@ -2714,16 +2898,16 @@ cmyk2rgb (unsigned char *src,
* Decode planar CMYK(A) to RGB(A). * Decode planar CMYK(A) to RGB(A).
*/ */
static void static void
cmykp2rgb (unsigned char *src, cmykp2rgb (const guchar *src,
unsigned char *dst, guchar *dst,
long width, long width,
long height, long height,
int alpha) int alpha)
{ {
const guchar *rp, *gp, *bp, *kp, *ap;
int r, g, b, k; int r, g, b, k;
int i, j; int i, j;
long n; long n;
guchar *rp, *gp, *bp, *kp, *ap;
n = width * height; n = width * height;
rp = src; rp = src;
@ -2757,7 +2941,7 @@ cmykp2rgb (unsigned char *src,
} }
static void static void
bitmap2gray (guchar *src, bitmap2gray (const guchar *src,
guchar *dest, guchar *dest,
long w, long w,
long h) long h)
@ -2770,7 +2954,7 @@ bitmap2gray (guchar *src,
for(j = 0; j < w; j++) for(j = 0; j < w; j++)
{ {
*dest++ = (*src&mask) ? 0 : 255; *dest++ = (*src & mask) ? 0 : 255;
mask >>= 1; mask >>= 1;
if(!mask) if(!mask)
@ -2787,7 +2971,7 @@ bitmap2gray (guchar *src,
static void static void
dumpchunk (size_t n, dumpchunk (size_t n,
FILE *fd, FILE *fd,
gchar *why) const gchar *why)
{ {
guint32 i; guint32 i;
@ -2804,7 +2988,7 @@ dumpchunk (size_t n,
static void static void
throwchunk (size_t n, throwchunk (size_t n,
FILE *fd, FILE *fd,
gchar *why) const gchar *why)
{ {
#if 0 #if 0
guchar *tmpchunk; guchar *tmpchunk;
@ -2830,7 +3014,7 @@ throwchunk (size_t n,
static gchar * static gchar *
getstring (size_t n, getstring (size_t n,
FILE *fd, FILE *fd,
gchar *why) const gchar *why)
{ {
gchar *tmpchunk; gchar *tmpchunk;
@ -2843,7 +3027,7 @@ getstring (size_t n,
static gchar * static gchar *
getpascalstring (FILE *fd, getpascalstring (FILE *fd,
gchar *why) const gchar *why)
{ {
guchar *tmpchunk; guchar *tmpchunk;
guchar len; guchar len;
@ -2853,7 +3037,7 @@ getpascalstring (FILE *fd,
if (len == 0) if (len == 0)
return NULL; return NULL;
tmpchunk = g_malloc(len+1); tmpchunk = g_malloc (len+1);
xfread(fd, tmpchunk, len, why); xfread(fd, tmpchunk, len, why);
tmpchunk[len]=0; tmpchunk[len]=0;
@ -2861,9 +3045,40 @@ getpascalstring (FILE *fd,
return (gchar *) tmpchunk; /* caller should free memory */ return (gchar *) tmpchunk; /* caller should free memory */
} }
static gchar *
getunicodepascalstring (FILE *fd,
const gchar *why)
{
gunichar2 *tmpunichunk;
gchar *tmpchunk;
guint32 count = 0;
guint32 len = getgint32 (fd, why);
if (len == 0)
return NULL;
/* Looks like these are always padded to an even number. */
len += len % 2;
tmpunichunk = g_new (gunichar2, len + 1);
/* Slower but necessary to get correct endianness */
for (count=0; count < len; count++)
tmpunichunk[count] = getgint16 (fd, why);
tmpunichunk[len]=0;
tmpchunk = g_convert ((gchar *) tmpunichunk, len * 2, "UTF-8", "UCS-2",
NULL, NULL, NULL);
g_free (tmpunichunk);
return tmpchunk; /* caller should free memory */
}
static guchar static guchar
getguchar (FILE *fd, getguchar (FILE *fd,
gchar *why) const gchar *why)
{ {
gint tmp; gint tmp;
@ -2880,7 +3095,7 @@ getguchar (FILE *fd,
static gint16 static gint16
getgint16 (FILE *fd, getgint16 (FILE *fd,
gchar *why) const gchar *why)
{ {
guchar b1, b2; guchar b1, b2;
@ -2892,7 +3107,7 @@ getgint16 (FILE *fd,
static gint32 static gint32
getgint32 (FILE *fd, getgint32 (FILE *fd,
gchar *why) const gchar *why)
{ {
guchar s1, s2, s3, s4; guchar s1, s2, s3, s4;
@ -2911,7 +3126,7 @@ static void
xfread (FILE *fd, xfread (FILE *fd,
void *buf, void *buf,
long len, long len,
gchar *why) const gchar *why)
{ {
if (fread (buf, len, 1, fd) == 0) if (fread (buf, len, 1, fd) == 0)
{ {
@ -2924,7 +3139,7 @@ static void
xfread_interlaced (FILE *fd, xfread_interlaced (FILE *fd,
guchar *buf, guchar *buf,
long len, long len,
gchar *why, const gchar *why,
gint step) gint step)
{ {
guchar *dest; guchar *dest;