mirror of https://github.com/GNOME/gimp.git
parent
644a0060f5
commit
bf81cf4df9
|
@ -1,3 +1,7 @@
|
|||
Sun Apr 26 03:06:16 PDT 1998 Manish Singh <yosh@gimp.org>
|
||||
|
||||
* oh goodie, the PSD plugin doesn't relay on endian junk anymore
|
||||
|
||||
Sun Apr 26 02:34:21 PDT 1998 Manish Singh <yosh@gimp.org>
|
||||
|
||||
* updated CEL plugin
|
||||
|
|
|
@ -46,10 +46,6 @@
|
|||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Define if your processor stores words with the most significant
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
#undef HAVE_DIRENT_H
|
||||
#undef HAVE_DOPRNT
|
||||
#undef HAVE_IPC_H
|
||||
|
|
|
@ -262,9 +262,6 @@ AC_HEADER_TIME
|
|||
AC_CHECK_HEADER(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H))
|
||||
AC_CHECK_HEADER(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
|
||||
|
||||
dnl for the psd plugin
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PSD Plugin version 1.9.9.5 (BETA)
|
||||
* PSD Plugin version 1.9.9.8 (BETA)
|
||||
* This GIMP plug-in is designed to load Adobe Photoshop(tm) files (.PSD)
|
||||
*
|
||||
* Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
|
@ -33,20 +33,14 @@
|
|||
* Incorporated that may be registered in certain jurisdictions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Aux channels for layered files
|
||||
* 16bpp channels?
|
||||
* CMYK -> RGB
|
||||
* Load BITMAP mode
|
||||
*
|
||||
* File saving.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Revision history:
|
||||
*
|
||||
* 98.04.26 / v1.9.9.8 / Adam D. Moss
|
||||
* Implemented Aux-channels for layered files. Got rid
|
||||
* of <endian.h> nonsense. Improved Layer Mask padding.
|
||||
* Enforced num_layers/num_channels limit checks.
|
||||
*
|
||||
* 98.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
|
||||
|
@ -69,12 +63,33 @@
|
|||
* Flat PSD image loading.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Crush 16bpp channels
|
||||
* CMYK -> RGB
|
||||
* Load BITMAP mode
|
||||
*
|
||||
* File saving. (I am not going 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!
|
||||
*/
|
||||
|
||||
/*
|
||||
* BUGS:
|
||||
*
|
||||
* Sometimes creates a superfluous aux channel? Harmless.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* *** DEFINES *** */
|
||||
/* the max number of layers that this plugin should try to load */
|
||||
#define MAX_LAYERS 100
|
||||
/* the max number of channels that this plugin should let a layer have */
|
||||
#define MAX_CHANNELS 40
|
||||
#define MAX_CHANNELS 30
|
||||
/* *** END OF DEFINES *** */
|
||||
|
||||
|
||||
|
@ -84,7 +99,6 @@
|
|||
#include <glib.h>
|
||||
#include "libgimp/gimp.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Local types etc
|
||||
*/
|
||||
|
@ -243,7 +257,7 @@ static void cmykp2rgb(guchar *src, guchar *destp,
|
|||
static void cmyk_to_rgb(int *c, int *m, int *y, int *k);
|
||||
static guchar getguchar(FILE *fd, gchar *why);
|
||||
static gshort getgshort(FILE *fd, gchar *why);
|
||||
static gulong getglong(FILE *fd, gchar *why);
|
||||
static glong getglong(FILE *fd, gchar *why);
|
||||
static void xfread(FILE *fd, void *buf, long len, gchar *why);
|
||||
static void *xmalloc(size_t n);
|
||||
static void read_whole_file(FILE *fd);
|
||||
|
@ -253,7 +267,8 @@ void throwchunk(size_t n, FILE * fd, guchar *why);
|
|||
void dumpchunk(size_t n, FILE * fd, guchar *why);
|
||||
|
||||
|
||||
MAIN ();
|
||||
MAIN()
|
||||
|
||||
|
||||
static void
|
||||
query ()
|
||||
|
@ -383,10 +398,10 @@ psd_lmode_to_gimp_lmode (gchar modekey[4])
|
|||
if (strncmp(modekey, "diff", 4)==0) return(DIFFERENCE_MODE);
|
||||
|
||||
if (strncmp(modekey, "lum ", 4)==0) return(VALUE_MODE); /* ? */
|
||||
if (strncmp(modekey, "over", 4)==0) return(ADDITION_MODE); /* ? */
|
||||
|
||||
printf("PSD: Warning - unsupported layer-blend mode '%c%c%c%c', using 'addition' mode\n", modekey[0], modekey[1], modekey[2], modekey[3]);
|
||||
|
||||
if (strncmp(modekey, "over", 4)==0) return(ADDITION_MODE); /* ? */
|
||||
if (strncmp(modekey, "hLit", 4)==0) return(/**/ADDITION_MODE);
|
||||
if (strncmp(modekey, "sLit", 4)==0) return(/**/ADDITION_MODE);
|
||||
|
||||
|
@ -493,6 +508,12 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size)
|
|||
|
||||
psd_image.num_aux_channels++;
|
||||
|
||||
if (psd_image.num_aux_channels > MAX_CHANNELS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many aux channels. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
(*offset) += alpha_name_len+1;
|
||||
remaining -= alpha_name_len+1;
|
||||
}
|
||||
|
@ -641,25 +662,16 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
|
||||
printf("\t\t\tLAYER RECORD (layer %d)\n", (int)layernum);
|
||||
|
||||
getgshort (fd, "layer top throw");
|
||||
(*offset)+=2;
|
||||
top = getgshort (fd, "layer top");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer left throw");
|
||||
(*offset)+=2;
|
||||
left = getgshort (fd, "layer left");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer bottom throw");
|
||||
(*offset)+=2;
|
||||
bottom = getgshort (fd, "layer bottom");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer right throw");
|
||||
(*offset)+=2;
|
||||
right = getgshort (fd, "layer right");
|
||||
(*offset)+=2;
|
||||
/* table 11-12 */
|
||||
top = getglong (fd, "layer top");
|
||||
(*offset)+=4;
|
||||
left = getglong (fd, "layer left");
|
||||
(*offset)+=4;
|
||||
bottom = getglong (fd, "layer bottom");
|
||||
(*offset)+=4;
|
||||
right = getglong (fd, "layer right");
|
||||
(*offset)+=4;
|
||||
|
||||
psd_image.layer[layernum].x = left;
|
||||
psd_image.layer[layernum].y = top;
|
||||
|
@ -672,11 +684,18 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
getgshort (fd, "layer num_channels");
|
||||
(*offset)+=2;
|
||||
|
||||
if (psd_image.layer[layernum].num_channels > MAX_CHANNELS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many channels. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
printf("\t\t\t\tNumber of channels: %d\n",
|
||||
(int)psd_image.layer[layernum].num_channels);
|
||||
|
||||
for (i=0;i<psd_image.layer[layernum].num_channels;i++)
|
||||
{
|
||||
/* table 11-13 */
|
||||
printf("\t\t\t\tCHANNEL LENGTH INFO (%d)\n", i);
|
||||
|
||||
psd_image.layer[layernum].channel[i].type = getgshort(fd, "channel id");
|
||||
|
@ -790,9 +809,13 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
|
||||
printf("\t\t\t\t\t\tLAYER NAME: '%s'\n",psd_image.layer[layernum].name);
|
||||
|
||||
throwchunk(totaloff-(*offset), fd, "layer record crap throw");
|
||||
if (totaloff-(*offset) > 0)
|
||||
{
|
||||
printf("Warning: layer record dross: ");
|
||||
dumpchunk(totaloff-(*offset), fd, "layer record dross throw");
|
||||
(*offset) = totaloff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
|
@ -820,6 +843,12 @@ do_layer_struct(FILE *fd, guint32 *offset)
|
|||
psd_image.absolute_alpha = FALSE;
|
||||
}
|
||||
|
||||
if (psd_image.num_layers > MAX_LAYERS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many layers. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
for (i=0; i<psd_image.num_layers; i++)
|
||||
{
|
||||
do_layer_record(fd, offset, i);
|
||||
|
@ -942,6 +971,9 @@ do_layer_pixeldata(FILE *fd, guint32 *offset)
|
|||
|
||||
g_free(tmpline);
|
||||
}
|
||||
|
||||
/* printf("\n[[%ld]]\n", getglong(fd, "uhhhh"));
|
||||
(*offset)+=4;*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -970,6 +1002,9 @@ do_layer_and_mask(FILE *fd)
|
|||
guint32 Size = PSDheader.miscsizelen;
|
||||
|
||||
|
||||
guint32 offset_now = ftell(fd);
|
||||
|
||||
|
||||
printf("LAYER AND MASK INFO\n");
|
||||
printf("\tSECTION LENGTH: %u\n",Size);
|
||||
|
||||
|
@ -977,33 +1012,31 @@ do_layer_and_mask(FILE *fd)
|
|||
|
||||
do_layers(fd, &offset);
|
||||
|
||||
|
||||
if (offset < Size)
|
||||
{
|
||||
printf("PSD: Supposedly there are %d bytes of mask info left.\n",
|
||||
Size-offset);
|
||||
if ((Size-offset == 4) || (Size-offset == 0x14))
|
||||
if ((Size-offset == 4) || (Size-offset == 24))
|
||||
printf(" That sounds good to me.\n");
|
||||
else
|
||||
printf(" That sounds strange to me.\n");
|
||||
|
||||
|
||||
/* FIXME: supposed to do something with this */
|
||||
/* dumpchunk(4, fd, "mask info throw");*/
|
||||
|
||||
if ((getguchar(fd, "mask info throw")!=0) ||
|
||||
/* if ((getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0))
|
||||
{
|
||||
/* printf("*** This is bogus. Quitting.\n");
|
||||
gimp_quit(); */
|
||||
printf("*** This mask info block looks pretty bogus.\n");
|
||||
}
|
||||
|
||||
/* do_masks(&offset);*/
|
||||
}*/
|
||||
}
|
||||
else
|
||||
printf("PSD: Stern warning - no mask info.\n");
|
||||
|
||||
|
||||
/* If 'offset' wasn't being buggily updated, we wouldn't need this. */
|
||||
fseek(fd, Size+offset_now, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1261,6 +1294,56 @@ void extract_data_and_channels(guchar* src, gint gimpstep, gint psstep,
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
void extract_channels(guchar* src, gint num_wanted, gint psstep,
|
||||
gint32 image_ID,
|
||||
gint width, gint height)
|
||||
{
|
||||
guchar* aux_data;
|
||||
GPixelRgn pixel_rgn;
|
||||
|
||||
printf("Extracting %d/%d auxiliary channels.\n", num_wanted, psstep);
|
||||
|
||||
aux_data = xmalloc(width * height);
|
||||
{
|
||||
int pix, chan;
|
||||
gint32 channel_ID;
|
||||
GDrawable* chdrawable;
|
||||
guchar colour[3]= {0, 0, 0};
|
||||
|
||||
for (chan=psstep-num_wanted; chan<psstep; chan++)
|
||||
{
|
||||
for (pix=0; pix<width*height; pix++)
|
||||
{
|
||||
aux_data [pix] =
|
||||
src [pix*psstep + chan];
|
||||
}
|
||||
|
||||
channel_ID = gimp_channel_new(image_ID,
|
||||
psd_image.aux_channel[chan-(psstep-num_wanted)].name,
|
||||
width, height,
|
||||
100.0, colour);
|
||||
gimp_image_add_channel(image_ID, channel_ID, 0);
|
||||
gimp_channel_set_visible(channel_ID, FALSE);
|
||||
|
||||
chdrawable = gimp_drawable_get(channel_ID);
|
||||
|
||||
gimp_pixel_rgn_init (&pixel_rgn, chdrawable,
|
||||
0, 0, chdrawable->width, chdrawable->height,
|
||||
TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, aux_data,
|
||||
0, 0, chdrawable->width, chdrawable->height);
|
||||
|
||||
gimp_drawable_flush (chdrawable);
|
||||
gimp_drawable_detach (chdrawable);
|
||||
}
|
||||
}
|
||||
g_free(aux_data);
|
||||
|
||||
printf("Done with that.\n\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
resize_mask(guchar* src, guchar* dest,
|
||||
gint32 src_x, gint32 src_y,
|
||||
|
@ -1287,7 +1370,7 @@ resize_mask(guchar* src, guchar* dest,
|
|||
}
|
||||
else
|
||||
{
|
||||
dest[dest_w * y + x] = 0;
|
||||
dest[dest_w * y + x] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1298,20 +1381,21 @@ static gint32
|
|||
load_image(char *name)
|
||||
{
|
||||
FILE *fd;
|
||||
gboolean want_aux;
|
||||
char *name_buf, *cmykbuf;
|
||||
static int number = 1;
|
||||
unsigned char *dest, *temp;
|
||||
long rowstride, channels, nguchars;
|
||||
long channels, nguchars;
|
||||
psd_imagetype imagetype;
|
||||
int cmyk = 0, step = 1;
|
||||
gint32 image_ID = -1;
|
||||
gint32 layer_ID = -1;
|
||||
GDrawable *drawable;
|
||||
GDrawable *drawable = NULL;
|
||||
GPixelRgn pixel_rgn;
|
||||
gint32 iter;
|
||||
|
||||
|
||||
printf("------- %s --------------------------------------\n",name);
|
||||
printf("------- %s ---------------------------------\n",name);
|
||||
|
||||
|
||||
name_buf = xmalloc(strlen(name) + 11);
|
||||
|
@ -1510,100 +1594,52 @@ load_image(char *name)
|
|||
gimp_progress_update ((double)(lnum+1.0) /
|
||||
(double)psd_image.num_layers);
|
||||
}
|
||||
gimp_displays_flush();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else /* PS2-style - NO LAYERS. */
|
||||
|
||||
|
||||
|
||||
if ((psd_image.num_aux_channels > 0) &&
|
||||
(psd_image.num_layers > 0))
|
||||
{
|
||||
want_aux = TRUE;
|
||||
printf("::::::::::: WANT AUX :::::::::::::::::::::::::::::::::::::::\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
want_aux = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (want_aux || (psd_image.num_layers==0)) /* PS2-style - NO LAYERS. */
|
||||
{
|
||||
|
||||
printf("Image data %ld chars\n", PSDheader.imgdatalen);
|
||||
|
||||
step = PSDheader.channels;
|
||||
|
||||
imagetype = PSD_UNKNOWN_IMAGE;
|
||||
switch (PSDheader.mode) {
|
||||
switch (PSDheader.mode)
|
||||
{
|
||||
case 0: /* Bitmap */
|
||||
break;
|
||||
case 1: /* Grayscale */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 1:
|
||||
step = 1;
|
||||
imagetype = PSD_GRAY_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
step = 2;
|
||||
imagetype = PSD_GRAYA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base GRAY image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
imagetype = PSD_GRAYA_IMAGE;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_GRAY_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 2: /* Indexed Colour */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 1:
|
||||
step = 1;
|
||||
imagetype = PSD_INDEXED_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
step = 2;
|
||||
printf("Warning: base INDEXED image has 2 channels - "
|
||||
"ignoring alpha.\n");
|
||||
imagetype = PSD_INDEXEDA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base INDEXED image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
imagetype = PSD_INDEXEDA_IMAGE;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_INDEXED_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 3: /* RGB Colour */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 3:
|
||||
step = 3;
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
break;
|
||||
case 4:
|
||||
step = 4;
|
||||
imagetype = PSD_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base RGB image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 4: /* CMYK Colour */
|
||||
cmyk = 1;
|
||||
switch (PSDheader.channels) {
|
||||
switch (PSDheader.channels)
|
||||
{
|
||||
case 4:
|
||||
step = 4;
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
break;
|
||||
case 5:
|
||||
step = 5;
|
||||
imagetype = PSD_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
|
@ -1620,6 +1656,7 @@ load_image(char *name)
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
if (imagetype == PSD_UNKNOWN_IMAGE)
|
||||
{
|
||||
printf("%s: Image type %d (%s) is not supported in this data format\n",
|
||||
|
@ -1629,6 +1666,7 @@ load_image(char *name)
|
|||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (PSDheader.bpp != 8)
|
||||
{
|
||||
printf("%s: The GIMP only supports 8-bit deep PSD images\n",
|
||||
|
@ -1644,6 +1682,8 @@ load_image(char *name)
|
|||
);
|
||||
|
||||
|
||||
if (!want_aux)
|
||||
{
|
||||
image_ID = gimp_image_new (PSDheader.columns, PSDheader.rows,
|
||||
psd_type_to_gimp_base_type(imagetype));
|
||||
gimp_image_set_filename (image_ID, name);
|
||||
|
@ -1675,24 +1715,48 @@ load_image(char *name)
|
|||
gimp_image_add_layer (image_ID, layer_ID, 0);
|
||||
drawable = gimp_drawable_get (layer_ID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (want_aux)
|
||||
{
|
||||
switch (PSDheader.mode)
|
||||
{
|
||||
case 1: /* Grayscale */
|
||||
channels = 1;
|
||||
break;
|
||||
case 2: /* Indexed Colour */
|
||||
channels = 1;
|
||||
break;
|
||||
case 3: /* RGB Colour */
|
||||
channels = 3;
|
||||
break;
|
||||
default:
|
||||
printf("aux? Aieeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee!!!!!!!!!\n");
|
||||
channels = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
channels = PSDheader.channels - channels;
|
||||
|
||||
/* dest = gimp_image_data (image);
|
||||
channels = gimp_image_channels (image);
|
||||
rowstride = gimp_image_width (image) * channels;*/
|
||||
|
||||
if (psd_image.absolute_alpha)
|
||||
{
|
||||
channels--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
channels = gimp_drawable_bpp(drawable->id);
|
||||
rowstride = PSDheader.columns * channels;
|
||||
dest = xmalloc( step * PSDheader.columns * PSDheader.rows );
|
||||
}
|
||||
|
||||
|
||||
dest = xmalloc( step * PSDheader.columns * PSDheader.rows );
|
||||
|
||||
|
||||
gimp_progress_update ((double)0.0);
|
||||
|
||||
|
||||
if (PSDheader.compression!=0)
|
||||
if (PSDheader.compression == 1)
|
||||
{
|
||||
nguchars = PSDheader.columns * PSDheader.rows;
|
||||
temp = xmalloc(PSDheader.imgdatalen);
|
||||
|
@ -1716,6 +1780,7 @@ load_image(char *name)
|
|||
g_free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cmyk)
|
||||
{
|
||||
gimp_progress_update ((double)0.50);
|
||||
|
@ -1731,17 +1796,31 @@ load_image(char *name)
|
|||
PSDheader.columns, PSDheader.rows, step > 4);
|
||||
g_free(cmykbuf);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_progress_update ((double)1.00);
|
||||
|
||||
if (want_aux) /* want_aux */
|
||||
{
|
||||
extract_channels(dest, channels, step,
|
||||
image_ID,
|
||||
PSDheader.columns, PSDheader.rows);
|
||||
goto finish_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_progress_update ((double)0.96);
|
||||
|
||||
if (channels == step) /* gimp bpp == psd bpp */
|
||||
{
|
||||
|
||||
if (psd_type_to_gimp_type(imagetype)==INDEXEDA_IMAGE)
|
||||
{
|
||||
printf("@@@@ Didn't know about this.\n");
|
||||
for (iter=0; iter<drawable->width*drawable->height; iter++)
|
||||
{
|
||||
dest[iter*2+1] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable,
|
||||
0, 0, drawable->width, drawable->height,
|
||||
|
@ -1760,6 +1839,11 @@ load_image(char *name)
|
|||
image_ID, drawable,
|
||||
drawable->width, drawable->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_up:
|
||||
|
||||
g_free (dest);
|
||||
|
||||
|
@ -1767,8 +1851,12 @@ load_image(char *name)
|
|||
g_free(psd_image.colmapdata);
|
||||
}
|
||||
|
||||
printf("-- %d layers : pos %ld --\n",
|
||||
psd_image.num_layers, (long int)ftell(fd));
|
||||
|
||||
gimp_displays_flush();
|
||||
|
||||
printf("--- %d layers : pos %ld : a-alph %d ---\n",
|
||||
psd_image.num_layers, (long int)ftell(fd),
|
||||
psd_image.absolute_alpha);
|
||||
|
||||
return(image_ID);
|
||||
}
|
||||
|
@ -1969,7 +2057,7 @@ cmykp2rgb(unsigned char * src, unsigned char * dst,
|
|||
static void
|
||||
cmyk_to_rgb(gint *c, gint *m, gint *y, gint *k)
|
||||
{
|
||||
#if 1
|
||||
#if 0
|
||||
gint cyan, magenta, yellow, black;
|
||||
|
||||
cyan = *c;
|
||||
|
@ -2074,61 +2162,32 @@ getguchar(FILE *fd, char *why)
|
|||
static gshort
|
||||
getgshort(FILE *fd, char *why)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
union {
|
||||
struct {
|
||||
unsigned char b1, b2;
|
||||
} b;
|
||||
gshort w;
|
||||
} s;
|
||||
#endif
|
||||
gushort w;
|
||||
guchar b;
|
||||
guchar b1, b2;
|
||||
|
||||
xfread(fd, &w, 2, why);
|
||||
xfread(fd, &b1, 1, why);
|
||||
xfread(fd, &b2, 1, why);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN)
|
||||
return (gshort) w;
|
||||
#else
|
||||
s.w = w;
|
||||
b = s.b.b2;
|
||||
s.b.b2 = s.b.b1;
|
||||
s.b.b1 = b;
|
||||
return s.w;
|
||||
#endif
|
||||
w = (b1*256) + b2;
|
||||
|
||||
return ((gshort) w);
|
||||
}
|
||||
|
||||
|
||||
static gulong
|
||||
static glong
|
||||
getglong(FILE *fd, char * why)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
union {
|
||||
struct {
|
||||
unsigned char b1, b2, b3, b4;
|
||||
} b;
|
||||
gulong w;
|
||||
} s;
|
||||
unsigned char s1, s2, s3, s4;
|
||||
#endif
|
||||
gulong w;
|
||||
|
||||
xfread(fd, &w, 4, why);
|
||||
xfread(fd, &s1, 1, why);
|
||||
xfread(fd, &s2, 1, why);
|
||||
xfread(fd, &s3, 1, why);
|
||||
xfread(fd, &s4, 1, why);
|
||||
|
||||
w = (s1*256*256*256) + (s2*256*256) + (s3*256) + s4;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
return (glong) w;
|
||||
#else
|
||||
s.w = w;
|
||||
s1 = s.b.b1;
|
||||
s2 = s.b.b2;
|
||||
s3 = s.b.b3;
|
||||
s4 = s.b.b4;
|
||||
s.b.b3 = s2;
|
||||
s.b.b4 = s1;
|
||||
s.b.b1 = s4;
|
||||
s.b.b2 = s3;
|
||||
return s.w;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2212,8 +2271,8 @@ read_whole_file(FILE * fd)
|
|||
|
||||
|
||||
PSDheader.compression = getgshort(fd, "compression");
|
||||
printf("<<%d>>", (int)PSDheader.compression);
|
||||
if (PSDheader.compression)
|
||||
printf("<<compr:%d>>", (int)PSDheader.compression);
|
||||
if (PSDheader.compression == 1) /* RLE */
|
||||
{
|
||||
PSDheader.rowlength = xmalloc(PSDheader.rows *
|
||||
PSDheader.channels * sizeof(gushort));
|
||||
|
@ -2225,6 +2284,7 @@ read_whole_file(FILE * fd)
|
|||
PSDheader.imgdatalen = ftell(fd)-pos;
|
||||
fseek(fd, pos, SEEK_SET);
|
||||
|
||||
|
||||
if (strncmp(PSDheader.signature, "8BPS", 4) != 0)
|
||||
{
|
||||
printf("%s: not an Adobe Photoshop PSD file\n", prog_name);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PSD Plugin version 1.9.9.5 (BETA)
|
||||
* PSD Plugin version 1.9.9.8 (BETA)
|
||||
* This GIMP plug-in is designed to load Adobe Photoshop(tm) files (.PSD)
|
||||
*
|
||||
* Adam D. Moss <adam@gimp.org> <adam@foxbox.org>
|
||||
|
@ -33,20 +33,14 @@
|
|||
* Incorporated that may be registered in certain jurisdictions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Aux channels for layered files
|
||||
* 16bpp channels?
|
||||
* CMYK -> RGB
|
||||
* Load BITMAP mode
|
||||
*
|
||||
* File saving.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Revision history:
|
||||
*
|
||||
* 98.04.26 / v1.9.9.8 / Adam D. Moss
|
||||
* Implemented Aux-channels for layered files. Got rid
|
||||
* of <endian.h> nonsense. Improved Layer Mask padding.
|
||||
* Enforced num_layers/num_channels limit checks.
|
||||
*
|
||||
* 98.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
|
||||
|
@ -69,12 +63,33 @@
|
|||
* Flat PSD image loading.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Crush 16bpp channels
|
||||
* CMYK -> RGB
|
||||
* Load BITMAP mode
|
||||
*
|
||||
* File saving. (I am not going 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!
|
||||
*/
|
||||
|
||||
/*
|
||||
* BUGS:
|
||||
*
|
||||
* Sometimes creates a superfluous aux channel? Harmless.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* *** DEFINES *** */
|
||||
/* the max number of layers that this plugin should try to load */
|
||||
#define MAX_LAYERS 100
|
||||
/* the max number of channels that this plugin should let a layer have */
|
||||
#define MAX_CHANNELS 40
|
||||
#define MAX_CHANNELS 30
|
||||
/* *** END OF DEFINES *** */
|
||||
|
||||
|
||||
|
@ -84,7 +99,6 @@
|
|||
#include <glib.h>
|
||||
#include "libgimp/gimp.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* Local types etc
|
||||
*/
|
||||
|
@ -243,7 +257,7 @@ static void cmykp2rgb(guchar *src, guchar *destp,
|
|||
static void cmyk_to_rgb(int *c, int *m, int *y, int *k);
|
||||
static guchar getguchar(FILE *fd, gchar *why);
|
||||
static gshort getgshort(FILE *fd, gchar *why);
|
||||
static gulong getglong(FILE *fd, gchar *why);
|
||||
static glong getglong(FILE *fd, gchar *why);
|
||||
static void xfread(FILE *fd, void *buf, long len, gchar *why);
|
||||
static void *xmalloc(size_t n);
|
||||
static void read_whole_file(FILE *fd);
|
||||
|
@ -253,7 +267,8 @@ void throwchunk(size_t n, FILE * fd, guchar *why);
|
|||
void dumpchunk(size_t n, FILE * fd, guchar *why);
|
||||
|
||||
|
||||
MAIN ();
|
||||
MAIN()
|
||||
|
||||
|
||||
static void
|
||||
query ()
|
||||
|
@ -383,10 +398,10 @@ psd_lmode_to_gimp_lmode (gchar modekey[4])
|
|||
if (strncmp(modekey, "diff", 4)==0) return(DIFFERENCE_MODE);
|
||||
|
||||
if (strncmp(modekey, "lum ", 4)==0) return(VALUE_MODE); /* ? */
|
||||
if (strncmp(modekey, "over", 4)==0) return(ADDITION_MODE); /* ? */
|
||||
|
||||
printf("PSD: Warning - unsupported layer-blend mode '%c%c%c%c', using 'addition' mode\n", modekey[0], modekey[1], modekey[2], modekey[3]);
|
||||
|
||||
if (strncmp(modekey, "over", 4)==0) return(ADDITION_MODE); /* ? */
|
||||
if (strncmp(modekey, "hLit", 4)==0) return(/**/ADDITION_MODE);
|
||||
if (strncmp(modekey, "sLit", 4)==0) return(/**/ADDITION_MODE);
|
||||
|
||||
|
@ -493,6 +508,12 @@ dispatch_resID(guint ID, FILE *fd, guint32 *offset, guint32 Size)
|
|||
|
||||
psd_image.num_aux_channels++;
|
||||
|
||||
if (psd_image.num_aux_channels > MAX_CHANNELS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many aux channels. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
(*offset) += alpha_name_len+1;
|
||||
remaining -= alpha_name_len+1;
|
||||
}
|
||||
|
@ -641,25 +662,16 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
|
||||
printf("\t\t\tLAYER RECORD (layer %d)\n", (int)layernum);
|
||||
|
||||
getgshort (fd, "layer top throw");
|
||||
(*offset)+=2;
|
||||
top = getgshort (fd, "layer top");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer left throw");
|
||||
(*offset)+=2;
|
||||
left = getgshort (fd, "layer left");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer bottom throw");
|
||||
(*offset)+=2;
|
||||
bottom = getgshort (fd, "layer bottom");
|
||||
(*offset)+=2;
|
||||
|
||||
getgshort (fd, "layer right throw");
|
||||
(*offset)+=2;
|
||||
right = getgshort (fd, "layer right");
|
||||
(*offset)+=2;
|
||||
/* table 11-12 */
|
||||
top = getglong (fd, "layer top");
|
||||
(*offset)+=4;
|
||||
left = getglong (fd, "layer left");
|
||||
(*offset)+=4;
|
||||
bottom = getglong (fd, "layer bottom");
|
||||
(*offset)+=4;
|
||||
right = getglong (fd, "layer right");
|
||||
(*offset)+=4;
|
||||
|
||||
psd_image.layer[layernum].x = left;
|
||||
psd_image.layer[layernum].y = top;
|
||||
|
@ -672,11 +684,18 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
getgshort (fd, "layer num_channels");
|
||||
(*offset)+=2;
|
||||
|
||||
if (psd_image.layer[layernum].num_channels > MAX_CHANNELS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many channels. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
printf("\t\t\t\tNumber of channels: %d\n",
|
||||
(int)psd_image.layer[layernum].num_channels);
|
||||
|
||||
for (i=0;i<psd_image.layer[layernum].num_channels;i++)
|
||||
{
|
||||
/* table 11-13 */
|
||||
printf("\t\t\t\tCHANNEL LENGTH INFO (%d)\n", i);
|
||||
|
||||
psd_image.layer[layernum].channel[i].type = getgshort(fd, "channel id");
|
||||
|
@ -790,9 +809,13 @@ do_layer_record(FILE *fd, guint32 *offset, gint layernum)
|
|||
|
||||
printf("\t\t\t\t\t\tLAYER NAME: '%s'\n",psd_image.layer[layernum].name);
|
||||
|
||||
throwchunk(totaloff-(*offset), fd, "layer record crap throw");
|
||||
if (totaloff-(*offset) > 0)
|
||||
{
|
||||
printf("Warning: layer record dross: ");
|
||||
dumpchunk(totaloff-(*offset), fd, "layer record dross throw");
|
||||
(*offset) = totaloff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
|
@ -820,6 +843,12 @@ do_layer_struct(FILE *fd, guint32 *offset)
|
|||
psd_image.absolute_alpha = FALSE;
|
||||
}
|
||||
|
||||
if (psd_image.num_layers > MAX_LAYERS)
|
||||
{
|
||||
printf("\nPSD: Sorry - this image has too many layers. Tell Adam!\n");
|
||||
gimp_quit();
|
||||
}
|
||||
|
||||
for (i=0; i<psd_image.num_layers; i++)
|
||||
{
|
||||
do_layer_record(fd, offset, i);
|
||||
|
@ -942,6 +971,9 @@ do_layer_pixeldata(FILE *fd, guint32 *offset)
|
|||
|
||||
g_free(tmpline);
|
||||
}
|
||||
|
||||
/* printf("\n[[%ld]]\n", getglong(fd, "uhhhh"));
|
||||
(*offset)+=4;*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -970,6 +1002,9 @@ do_layer_and_mask(FILE *fd)
|
|||
guint32 Size = PSDheader.miscsizelen;
|
||||
|
||||
|
||||
guint32 offset_now = ftell(fd);
|
||||
|
||||
|
||||
printf("LAYER AND MASK INFO\n");
|
||||
printf("\tSECTION LENGTH: %u\n",Size);
|
||||
|
||||
|
@ -977,33 +1012,31 @@ do_layer_and_mask(FILE *fd)
|
|||
|
||||
do_layers(fd, &offset);
|
||||
|
||||
|
||||
if (offset < Size)
|
||||
{
|
||||
printf("PSD: Supposedly there are %d bytes of mask info left.\n",
|
||||
Size-offset);
|
||||
if ((Size-offset == 4) || (Size-offset == 0x14))
|
||||
if ((Size-offset == 4) || (Size-offset == 24))
|
||||
printf(" That sounds good to me.\n");
|
||||
else
|
||||
printf(" That sounds strange to me.\n");
|
||||
|
||||
|
||||
/* FIXME: supposed to do something with this */
|
||||
/* dumpchunk(4, fd, "mask info throw");*/
|
||||
|
||||
if ((getguchar(fd, "mask info throw")!=0) ||
|
||||
/* if ((getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0) ||
|
||||
(getguchar(fd, "mask info throw")!=0))
|
||||
{
|
||||
/* printf("*** This is bogus. Quitting.\n");
|
||||
gimp_quit(); */
|
||||
printf("*** This mask info block looks pretty bogus.\n");
|
||||
}
|
||||
|
||||
/* do_masks(&offset);*/
|
||||
}*/
|
||||
}
|
||||
else
|
||||
printf("PSD: Stern warning - no mask info.\n");
|
||||
|
||||
|
||||
/* If 'offset' wasn't being buggily updated, we wouldn't need this. */
|
||||
fseek(fd, Size+offset_now, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1261,6 +1294,56 @@ void extract_data_and_channels(guchar* src, gint gimpstep, gint psstep,
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
void extract_channels(guchar* src, gint num_wanted, gint psstep,
|
||||
gint32 image_ID,
|
||||
gint width, gint height)
|
||||
{
|
||||
guchar* aux_data;
|
||||
GPixelRgn pixel_rgn;
|
||||
|
||||
printf("Extracting %d/%d auxiliary channels.\n", num_wanted, psstep);
|
||||
|
||||
aux_data = xmalloc(width * height);
|
||||
{
|
||||
int pix, chan;
|
||||
gint32 channel_ID;
|
||||
GDrawable* chdrawable;
|
||||
guchar colour[3]= {0, 0, 0};
|
||||
|
||||
for (chan=psstep-num_wanted; chan<psstep; chan++)
|
||||
{
|
||||
for (pix=0; pix<width*height; pix++)
|
||||
{
|
||||
aux_data [pix] =
|
||||
src [pix*psstep + chan];
|
||||
}
|
||||
|
||||
channel_ID = gimp_channel_new(image_ID,
|
||||
psd_image.aux_channel[chan-(psstep-num_wanted)].name,
|
||||
width, height,
|
||||
100.0, colour);
|
||||
gimp_image_add_channel(image_ID, channel_ID, 0);
|
||||
gimp_channel_set_visible(channel_ID, FALSE);
|
||||
|
||||
chdrawable = gimp_drawable_get(channel_ID);
|
||||
|
||||
gimp_pixel_rgn_init (&pixel_rgn, chdrawable,
|
||||
0, 0, chdrawable->width, chdrawable->height,
|
||||
TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, aux_data,
|
||||
0, 0, chdrawable->width, chdrawable->height);
|
||||
|
||||
gimp_drawable_flush (chdrawable);
|
||||
gimp_drawable_detach (chdrawable);
|
||||
}
|
||||
}
|
||||
g_free(aux_data);
|
||||
|
||||
printf("Done with that.\n\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
resize_mask(guchar* src, guchar* dest,
|
||||
gint32 src_x, gint32 src_y,
|
||||
|
@ -1287,7 +1370,7 @@ resize_mask(guchar* src, guchar* dest,
|
|||
}
|
||||
else
|
||||
{
|
||||
dest[dest_w * y + x] = 0;
|
||||
dest[dest_w * y + x] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1298,20 +1381,21 @@ static gint32
|
|||
load_image(char *name)
|
||||
{
|
||||
FILE *fd;
|
||||
gboolean want_aux;
|
||||
char *name_buf, *cmykbuf;
|
||||
static int number = 1;
|
||||
unsigned char *dest, *temp;
|
||||
long rowstride, channels, nguchars;
|
||||
long channels, nguchars;
|
||||
psd_imagetype imagetype;
|
||||
int cmyk = 0, step = 1;
|
||||
gint32 image_ID = -1;
|
||||
gint32 layer_ID = -1;
|
||||
GDrawable *drawable;
|
||||
GDrawable *drawable = NULL;
|
||||
GPixelRgn pixel_rgn;
|
||||
gint32 iter;
|
||||
|
||||
|
||||
printf("------- %s --------------------------------------\n",name);
|
||||
printf("------- %s ---------------------------------\n",name);
|
||||
|
||||
|
||||
name_buf = xmalloc(strlen(name) + 11);
|
||||
|
@ -1510,100 +1594,52 @@ load_image(char *name)
|
|||
gimp_progress_update ((double)(lnum+1.0) /
|
||||
(double)psd_image.num_layers);
|
||||
}
|
||||
gimp_displays_flush();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else /* PS2-style - NO LAYERS. */
|
||||
|
||||
|
||||
|
||||
if ((psd_image.num_aux_channels > 0) &&
|
||||
(psd_image.num_layers > 0))
|
||||
{
|
||||
want_aux = TRUE;
|
||||
printf("::::::::::: WANT AUX :::::::::::::::::::::::::::::::::::::::\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
want_aux = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (want_aux || (psd_image.num_layers==0)) /* PS2-style - NO LAYERS. */
|
||||
{
|
||||
|
||||
printf("Image data %ld chars\n", PSDheader.imgdatalen);
|
||||
|
||||
step = PSDheader.channels;
|
||||
|
||||
imagetype = PSD_UNKNOWN_IMAGE;
|
||||
switch (PSDheader.mode) {
|
||||
switch (PSDheader.mode)
|
||||
{
|
||||
case 0: /* Bitmap */
|
||||
break;
|
||||
case 1: /* Grayscale */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 1:
|
||||
step = 1;
|
||||
imagetype = PSD_GRAY_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
step = 2;
|
||||
imagetype = PSD_GRAYA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base GRAY image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
imagetype = PSD_GRAYA_IMAGE;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_GRAY_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 2: /* Indexed Colour */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 1:
|
||||
step = 1;
|
||||
imagetype = PSD_INDEXED_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
step = 2;
|
||||
printf("Warning: base INDEXED image has 2 channels - "
|
||||
"ignoring alpha.\n");
|
||||
imagetype = PSD_INDEXEDA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base INDEXED image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
imagetype = PSD_INDEXEDA_IMAGE;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_INDEXED_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 3: /* RGB Colour */
|
||||
#if 0
|
||||
switch (PSDheader.channels) {
|
||||
case 3:
|
||||
step = 3;
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
break;
|
||||
case 4:
|
||||
step = 4;
|
||||
imagetype = PSD_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
printf("Warning: base RGB image has %d channels...\n",
|
||||
step = PSDheader.channels);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
#endif
|
||||
break;
|
||||
case 4: /* CMYK Colour */
|
||||
cmyk = 1;
|
||||
switch (PSDheader.channels) {
|
||||
switch (PSDheader.channels)
|
||||
{
|
||||
case 4:
|
||||
step = 4;
|
||||
imagetype = PSD_RGB_IMAGE;
|
||||
break;
|
||||
case 5:
|
||||
step = 5;
|
||||
imagetype = PSD_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
|
@ -1620,6 +1656,7 @@ load_image(char *name)
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
if (imagetype == PSD_UNKNOWN_IMAGE)
|
||||
{
|
||||
printf("%s: Image type %d (%s) is not supported in this data format\n",
|
||||
|
@ -1629,6 +1666,7 @@ load_image(char *name)
|
|||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (PSDheader.bpp != 8)
|
||||
{
|
||||
printf("%s: The GIMP only supports 8-bit deep PSD images\n",
|
||||
|
@ -1644,6 +1682,8 @@ load_image(char *name)
|
|||
);
|
||||
|
||||
|
||||
if (!want_aux)
|
||||
{
|
||||
image_ID = gimp_image_new (PSDheader.columns, PSDheader.rows,
|
||||
psd_type_to_gimp_base_type(imagetype));
|
||||
gimp_image_set_filename (image_ID, name);
|
||||
|
@ -1675,24 +1715,48 @@ load_image(char *name)
|
|||
gimp_image_add_layer (image_ID, layer_ID, 0);
|
||||
drawable = gimp_drawable_get (layer_ID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (want_aux)
|
||||
{
|
||||
switch (PSDheader.mode)
|
||||
{
|
||||
case 1: /* Grayscale */
|
||||
channels = 1;
|
||||
break;
|
||||
case 2: /* Indexed Colour */
|
||||
channels = 1;
|
||||
break;
|
||||
case 3: /* RGB Colour */
|
||||
channels = 3;
|
||||
break;
|
||||
default:
|
||||
printf("aux? Aieeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee!!!!!!!!!\n");
|
||||
channels = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
channels = PSDheader.channels - channels;
|
||||
|
||||
/* dest = gimp_image_data (image);
|
||||
channels = gimp_image_channels (image);
|
||||
rowstride = gimp_image_width (image) * channels;*/
|
||||
|
||||
if (psd_image.absolute_alpha)
|
||||
{
|
||||
channels--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
channels = gimp_drawable_bpp(drawable->id);
|
||||
rowstride = PSDheader.columns * channels;
|
||||
dest = xmalloc( step * PSDheader.columns * PSDheader.rows );
|
||||
}
|
||||
|
||||
|
||||
dest = xmalloc( step * PSDheader.columns * PSDheader.rows );
|
||||
|
||||
|
||||
gimp_progress_update ((double)0.0);
|
||||
|
||||
|
||||
if (PSDheader.compression!=0)
|
||||
if (PSDheader.compression == 1)
|
||||
{
|
||||
nguchars = PSDheader.columns * PSDheader.rows;
|
||||
temp = xmalloc(PSDheader.imgdatalen);
|
||||
|
@ -1716,6 +1780,7 @@ load_image(char *name)
|
|||
g_free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cmyk)
|
||||
{
|
||||
gimp_progress_update ((double)0.50);
|
||||
|
@ -1731,17 +1796,31 @@ load_image(char *name)
|
|||
PSDheader.columns, PSDheader.rows, step > 4);
|
||||
g_free(cmykbuf);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_progress_update ((double)1.00);
|
||||
|
||||
if (want_aux) /* want_aux */
|
||||
{
|
||||
extract_channels(dest, channels, step,
|
||||
image_ID,
|
||||
PSDheader.columns, PSDheader.rows);
|
||||
goto finish_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_progress_update ((double)0.96);
|
||||
|
||||
if (channels == step) /* gimp bpp == psd bpp */
|
||||
{
|
||||
|
||||
if (psd_type_to_gimp_type(imagetype)==INDEXEDA_IMAGE)
|
||||
{
|
||||
printf("@@@@ Didn't know about this.\n");
|
||||
for (iter=0; iter<drawable->width*drawable->height; iter++)
|
||||
{
|
||||
dest[iter*2+1] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable,
|
||||
0, 0, drawable->width, drawable->height,
|
||||
|
@ -1760,6 +1839,11 @@ load_image(char *name)
|
|||
image_ID, drawable,
|
||||
drawable->width, drawable->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_up:
|
||||
|
||||
g_free (dest);
|
||||
|
||||
|
@ -1767,8 +1851,12 @@ load_image(char *name)
|
|||
g_free(psd_image.colmapdata);
|
||||
}
|
||||
|
||||
printf("-- %d layers : pos %ld --\n",
|
||||
psd_image.num_layers, (long int)ftell(fd));
|
||||
|
||||
gimp_displays_flush();
|
||||
|
||||
printf("--- %d layers : pos %ld : a-alph %d ---\n",
|
||||
psd_image.num_layers, (long int)ftell(fd),
|
||||
psd_image.absolute_alpha);
|
||||
|
||||
return(image_ID);
|
||||
}
|
||||
|
@ -1969,7 +2057,7 @@ cmykp2rgb(unsigned char * src, unsigned char * dst,
|
|||
static void
|
||||
cmyk_to_rgb(gint *c, gint *m, gint *y, gint *k)
|
||||
{
|
||||
#if 1
|
||||
#if 0
|
||||
gint cyan, magenta, yellow, black;
|
||||
|
||||
cyan = *c;
|
||||
|
@ -2074,61 +2162,32 @@ getguchar(FILE *fd, char *why)
|
|||
static gshort
|
||||
getgshort(FILE *fd, char *why)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
union {
|
||||
struct {
|
||||
unsigned char b1, b2;
|
||||
} b;
|
||||
gshort w;
|
||||
} s;
|
||||
#endif
|
||||
gushort w;
|
||||
guchar b;
|
||||
guchar b1, b2;
|
||||
|
||||
xfread(fd, &w, 2, why);
|
||||
xfread(fd, &b1, 1, why);
|
||||
xfread(fd, &b2, 1, why);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN)
|
||||
return (gshort) w;
|
||||
#else
|
||||
s.w = w;
|
||||
b = s.b.b2;
|
||||
s.b.b2 = s.b.b1;
|
||||
s.b.b1 = b;
|
||||
return s.w;
|
||||
#endif
|
||||
w = (b1*256) + b2;
|
||||
|
||||
return ((gshort) w);
|
||||
}
|
||||
|
||||
|
||||
static gulong
|
||||
static glong
|
||||
getglong(FILE *fd, char * why)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
union {
|
||||
struct {
|
||||
unsigned char b1, b2, b3, b4;
|
||||
} b;
|
||||
gulong w;
|
||||
} s;
|
||||
unsigned char s1, s2, s3, s4;
|
||||
#endif
|
||||
gulong w;
|
||||
|
||||
xfread(fd, &w, 4, why);
|
||||
xfread(fd, &s1, 1, why);
|
||||
xfread(fd, &s2, 1, why);
|
||||
xfread(fd, &s3, 1, why);
|
||||
xfread(fd, &s4, 1, why);
|
||||
|
||||
w = (s1*256*256*256) + (s2*256*256) + (s3*256) + s4;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
return (glong) w;
|
||||
#else
|
||||
s.w = w;
|
||||
s1 = s.b.b1;
|
||||
s2 = s.b.b2;
|
||||
s3 = s.b.b3;
|
||||
s4 = s.b.b4;
|
||||
s.b.b3 = s2;
|
||||
s.b.b4 = s1;
|
||||
s.b.b1 = s4;
|
||||
s.b.b2 = s3;
|
||||
return s.w;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2212,8 +2271,8 @@ read_whole_file(FILE * fd)
|
|||
|
||||
|
||||
PSDheader.compression = getgshort(fd, "compression");
|
||||
printf("<<%d>>", (int)PSDheader.compression);
|
||||
if (PSDheader.compression)
|
||||
printf("<<compr:%d>>", (int)PSDheader.compression);
|
||||
if (PSDheader.compression == 1) /* RLE */
|
||||
{
|
||||
PSDheader.rowlength = xmalloc(PSDheader.rows *
|
||||
PSDheader.channels * sizeof(gushort));
|
||||
|
@ -2225,6 +2284,7 @@ read_whole_file(FILE * fd)
|
|||
PSDheader.imgdatalen = ftell(fd)-pos;
|
||||
fseek(fd, pos, SEEK_SET);
|
||||
|
||||
|
||||
if (strncmp(PSDheader.signature, "8BPS", 4) != 0)
|
||||
{
|
||||
printf("%s: not an Adobe Photoshop PSD file\n", prog_name);
|
||||
|
|
Loading…
Reference in New Issue