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:

committed by
Sven Neumann

parent
5d14b8d2a4
commit
dfeaec0861
@ -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
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user