mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
11 Commits
3a1076598b
...
soc-2013-p
Author | SHA1 | Date | |
---|---|---|---|
|
3624c93209 | ||
|
beb298fbfd | ||
|
d688887e38 | ||
|
feee5bd75a | ||
|
505090d2ee | ||
|
bf5c9e3e98 | ||
|
bc5ebbe276 | ||
|
fce974e1d3 | ||
|
d77c0833a2 | ||
|
4dd45e0c26 | ||
|
33a0e20451 |
@@ -64,6 +64,7 @@ LDADD = \
|
||||
$(libgimpbase) \
|
||||
$(JPEG_LIBS) \
|
||||
$(GTK_LIBS) \
|
||||
$(GEGL_LIBS) \
|
||||
$(EXIF_LIBS) \
|
||||
$(IPTCDATA_LIBS) \
|
||||
$(RT_LIBS) \
|
||||
|
@@ -75,11 +75,40 @@
|
||||
PSD_ALPHA_ID = 1053, Loaded * 0x041d - Alpha IDs *
|
||||
PSD_URL_LIST_UNI = 1054, * 0x041e - URL list - unicode *
|
||||
PSD_VERSION_INFO = 1057, * 0x0421 - Version info *
|
||||
PSD_EXIF_DATA = 1058, Loaded * 0x0422 - Exif data block *
|
||||
PSD_EXIF_DATA = 1058, Loaded * 0x0422 - Exif data block 1 *
|
||||
PSD_EXIF_DATA_3 = 1059 * 0X0423 - Exif data block 3 (?) *
|
||||
PSD_XMP_DATA = 1060, Loaded * 0x0424 - XMP data block *
|
||||
PSD_CAPTION_DIGEST = 1061, * 0x0425 - Caption digest *
|
||||
PSD_PRINT_SCALE = 1062, * 0x0426 - Print scale *
|
||||
PSD_PIXEL_AR = 1064, * 0x0428 - Pixel aspect ratio *
|
||||
PSD_LAYER_COMPS = 1065, * 0x0429 - Layer comps *
|
||||
PSD_ALT_DUOTONE_COLOR = 1066, * 0x042A - Alternative Duotone colors *
|
||||
PSD_ALT_SPOT_COLOR = 1067, * 0x042B - Alternative Spot colors *
|
||||
PSD_LAYER_SELECT_ID = 1069, * 0x042D - Layer selection ID *
|
||||
PSD_HDR_TONING_INFO = 1070, * 0x042E - HDR toning information *
|
||||
PSD_PRINT_INFO_SCALE = 1071, * 0x042F - Print scale *
|
||||
PSD_LAYER_GROUP_E_ID = 1072, * 0x0430 - Layer group(s) enabled ID *
|
||||
PSD_COLOR_SAMPLER_NEW = 1073, * 0x0431 - Color sampler resource for ps CS3 and higher PSD files *
|
||||
PSD_MEASURE_SCALE = 1074, * 0x0432 - Measurement scale *
|
||||
PSD_TIMELINE_INFO = 1075, * 0x0433 - Timeline information *
|
||||
PSD_SHEET_DISCLOSE = 1076, * 0x0434 - Sheet discloser *
|
||||
PSD_DISPLAY_INFO_NEW = 1077, Loaded * 0x0435 - DisplayInfo structure for ps CS3 and higher PSD files *
|
||||
PSD_ONION_SKINS = 1078, * 0x0436 - Onion skins *
|
||||
PSD_COUNT_INFO = 1080, * 0x0438 - Count information*
|
||||
PSD_PRINT_INFO = 1082, * 0x043A - Print information added in ps CS5*
|
||||
PSD_PRINT_STYLE = 1083, * 0x043B - Print style *
|
||||
PSD_MAC_NSPRINTINFO = 1084, * 0x043C - Mac NSPrintInfo*
|
||||
PSD_WIN_DEVMODE = 1085, * 0x043D - Windows DEVMODE *
|
||||
PSD_AUTO_SAVE_PATH = 1086, * 0x043E - Auto save file path *
|
||||
PSD_AUTO_SAVE_FORMAT = 1087, * 0x043F - Auto save format *
|
||||
PSD_PATH_INFO_FIRST = 2000, Loaded * 0x07d0 - First path info block *
|
||||
PSD_PATH_INFO_LAST = 2998, Loaded * 0x0bb6 - Last path info block *
|
||||
PSD_CLIPPING_PATH = 2999, * 0x0bb7 - Name of clipping path *
|
||||
PSD_PLUGIN_R_FIRST = 4000, * 0x0FA0 - First plugin resource *
|
||||
PSD_PLUGIN_R_LAST = 4999, * 0x1387 - Last plugin resource *
|
||||
PSD_IMAGEREADY_VARS = 7000, PS Only * 0x1B58 - Imageready variables *
|
||||
PSD_IMAGEREADY_DATA = 7001, PS Only * 0x1B59 - Imageready data sets *
|
||||
PSD_LIGHTROOM_WORK = 8000, PS Only * 0x1F40 - Lightroom workflow *
|
||||
PSD_PRINT_FLAGS_2 = 10000 * 0x2710 - Print flags *
|
||||
*/
|
||||
|
||||
@@ -193,6 +222,12 @@ static gint load_resource_1058 (const PSDimageres *res_a,
|
||||
FILE *f,
|
||||
GError **error);
|
||||
|
||||
static gint load_resource_1077 (const PSDimageres *res_a,
|
||||
const gint32 image_id,
|
||||
PSDimage *img_a,
|
||||
FILE *f,
|
||||
GError **error);
|
||||
|
||||
static gint load_resource_2000 (const PSDimageres *res_a,
|
||||
const gint32 image_id,
|
||||
FILE *f,
|
||||
@@ -254,7 +289,7 @@ load_image_resource (PSDimageres *res_a,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process image resource blocks */
|
||||
/* Process image resource blocks */
|
||||
if (memcmp (res_a->type, "8BIM", 4) != 0 &&
|
||||
memcmp (res_a->type, "MeSa", 4) !=0)
|
||||
{
|
||||
@@ -349,6 +384,10 @@ load_image_resource (PSDimageres *res_a,
|
||||
case PSD_XMP_DATA:
|
||||
break;
|
||||
|
||||
case PSD_DISPLAY_INFO_NEW:
|
||||
load_resource_1077 (res_a, image_id, img_a, f, error);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (res_a->id >= 2000 &&
|
||||
res_a->id < 2999)
|
||||
@@ -390,14 +429,14 @@ load_thumbnail_resource (PSDimageres *res_a,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process image resource blocks */
|
||||
if (res_a->id == PSD_THUMB_RES
|
||||
|| res_a->id == PSD_THUMB_RES2)
|
||||
{
|
||||
/* Load thumbnails from standard file load */
|
||||
load_resource_1033 (res_a, image_id, f, error);
|
||||
rtn = 1;
|
||||
}
|
||||
/* Process image resource blocks */
|
||||
if (res_a->id == PSD_THUMB_RES
|
||||
|| res_a->id == PSD_THUMB_RES2)
|
||||
{
|
||||
/* Load thumbnails from standard file load */
|
||||
load_resource_1033 (res_a, image_id, f, error);
|
||||
rtn = 1;
|
||||
}
|
||||
|
||||
/* Image blocks are null padded to even length */
|
||||
if (res_a->data_len % 2 == 0)
|
||||
@@ -439,7 +478,7 @@ load_resource_unknown (const PSDimageres *res_a,
|
||||
}
|
||||
|
||||
name = g_strdup_printf ("psd-image-resource-%.4s-%.4x",
|
||||
res_a->type, res_a->id);
|
||||
res_a->type, res_a->id);
|
||||
IFDBG(2) g_debug ("Parasite name: %s", name);
|
||||
|
||||
parasite = gimp_parasite_new (name, 0, res_a->data_len, data);
|
||||
@@ -474,7 +513,7 @@ load_resource_ps_only (const PSDimageres *res_a,
|
||||
}
|
||||
|
||||
name = g_strdup_printf ("psd-image-resource-%.4s-%.4x",
|
||||
res_a->type, res_a->id);
|
||||
res_a->type, res_a->id);
|
||||
IFDBG(2) g_debug ("Parasite name: %s", name);
|
||||
|
||||
parasite = gimp_parasite_new (name, 0, res_a->data_len, data);
|
||||
@@ -519,12 +558,12 @@ load_resource_1005 (const PSDimageres *res_a,
|
||||
res_info.heightUnit = GINT16_FROM_BE (res_info.heightUnit);
|
||||
|
||||
IFDBG(3) g_debug ("Resolution: %d, %d, %d, %d, %d, %d",
|
||||
res_info.hRes,
|
||||
res_info.hResUnit,
|
||||
res_info.widthUnit,
|
||||
res_info.vRes,
|
||||
res_info.vResUnit,
|
||||
res_info.heightUnit);
|
||||
res_info.hRes,
|
||||
res_info.hResUnit,
|
||||
res_info.widthUnit,
|
||||
res_info.vRes,
|
||||
res_info.vResUnit,
|
||||
res_info.heightUnit);
|
||||
|
||||
/* Resolution always recorded as pixels / inch in a fixed point implied
|
||||
decimal int32 with 16 bits before point and 16 after (i.e. cast as
|
||||
@@ -535,14 +574,14 @@ load_resource_1005 (const PSDimageres *res_a,
|
||||
/* GIMP only has one display unit so use ps horizontal resolution unit */
|
||||
switch (res_info.hResUnit)
|
||||
{
|
||||
case PSD_RES_INCH:
|
||||
image_unit = GIMP_UNIT_INCH;
|
||||
break;
|
||||
case PSD_RES_CM:
|
||||
image_unit = GIMP_UNIT_MM;
|
||||
break;
|
||||
default:
|
||||
image_unit = GIMP_UNIT_INCH;
|
||||
case PSD_RES_INCH:
|
||||
image_unit = GIMP_UNIT_INCH;
|
||||
break;
|
||||
case PSD_RES_CM:
|
||||
image_unit = GIMP_UNIT_MM;
|
||||
break;
|
||||
default:
|
||||
image_unit = GIMP_UNIT_INCH;
|
||||
}
|
||||
|
||||
gimp_image_set_unit (image_id, image_unit);
|
||||
@@ -681,13 +720,13 @@ load_resource_1007 (const PSDimageres *res_a,
|
||||
gimp_rgb_set_alpha (&gimp_rgb, 1.0);
|
||||
|
||||
IFDBG(2) g_debug ("PS cSpace: %d, col: %d %d %d %d, opacity: %d, kind: %d",
|
||||
dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta,
|
||||
ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity,
|
||||
dsp_info.kind);
|
||||
dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta,
|
||||
ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity,
|
||||
dsp_info.kind);
|
||||
|
||||
IFDBG(2) g_debug ("cSpace: %d, col: %g %g %g, opacity: %d, kind: %d",
|
||||
dsp_info.colorSpace, gimp_rgb.r * 255 , gimp_rgb.g * 255,
|
||||
gimp_rgb.b * 255, dsp_info.opacity, dsp_info.kind);
|
||||
dsp_info.colorSpace, gimp_rgb.r * 255 , gimp_rgb.g * 255,
|
||||
gimp_rgb.b * 255, dsp_info.opacity, dsp_info.kind);
|
||||
|
||||
img_a->alpha_display_info[cidx] = g_malloc (sizeof (PSDchanneldata));
|
||||
img_a->alpha_display_info[cidx]->gimp_color = gimp_rgb;
|
||||
@@ -748,8 +787,8 @@ load_resource_1022 (const PSDimageres *res_a,
|
||||
img_a->quick_mask_id = GUINT16_FROM_BE (img_a->quick_mask_id);
|
||||
|
||||
IFDBG(3) g_debug ("Quick mask channel: %d, empty: %d",
|
||||
img_a->quick_mask_id,
|
||||
quick_mask_empty);
|
||||
img_a->quick_mask_id,
|
||||
quick_mask_empty);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -913,8 +952,8 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
struct jpeg_error_mgr jerr;
|
||||
|
||||
ThumbnailInfo thumb_info;
|
||||
GimpDrawable *drawable;
|
||||
GimpPixelRgn pixel_rgn;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
gint32 layer_id;
|
||||
guchar *buf;
|
||||
guchar *rgb_buf;
|
||||
@@ -948,9 +987,9 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
IFDBG(2) g_debug ("\nThumbnail:\n"
|
||||
"\tFormat: %d\n"
|
||||
"\tDimensions: %d x %d\n",
|
||||
thumb_info.format,
|
||||
thumb_info.width,
|
||||
thumb_info.height);
|
||||
thumb_info.format,
|
||||
thumb_info.width,
|
||||
thumb_info.height);
|
||||
|
||||
if (thumb_info.format != 1)
|
||||
{
|
||||
@@ -995,9 +1034,8 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
cinfo.output_width,
|
||||
cinfo.output_height,
|
||||
GIMP_RGB_IMAGE, 100, GIMP_NORMAL_MODE);
|
||||
drawable = gimp_drawable_get (layer_id);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
|
||||
drawable->width, drawable->height, TRUE, FALSE);
|
||||
buffer = gimp_drawable_get_buffer (layer_id);
|
||||
format = babl_format ("R'G'B'A u8");
|
||||
|
||||
/* Step 6: while (scan lines remain to be read) */
|
||||
/* jpeg_read_scanlines(...); */
|
||||
@@ -1011,7 +1049,7 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
guchar *dst = rgb_buf;
|
||||
guchar *src = buf;
|
||||
|
||||
for (i = 0; i < drawable->width * drawable->height; ++i)
|
||||
for (i = 0; i < gegl_buffer_get_width (buffer) * gegl_buffer_get_height (buffer); ++i)
|
||||
{
|
||||
guchar r, g, b;
|
||||
|
||||
@@ -1023,8 +1061,8 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
*(dst++) = r;
|
||||
}
|
||||
}
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, rgb_buf ? rgb_buf : buf,
|
||||
0, 0, drawable->width, drawable->height);
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)),
|
||||
0, format, rgb_buf ? rgb_buf : buf, GEGL_AUTO_ROWSTRIDE);
|
||||
}
|
||||
|
||||
/* Step 7: Finish decompression */
|
||||
@@ -1046,7 +1084,7 @@ load_resource_1033 (const PSDimageres *res_a,
|
||||
* jerr.num_warnings is nonzero).
|
||||
*/
|
||||
gimp_image_insert_layer (image_id, layer_id, -1, 0);
|
||||
gimp_drawable_detach (drawable);
|
||||
g_object_unref (buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1232,6 +1270,118 @@ load_resource_1058 (const PSDimageres *res_a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
load_resource_1077 (const PSDimageres *res_a,
|
||||
const gint32 image_id,
|
||||
PSDimage *img_a,
|
||||
FILE *f,
|
||||
GError **error)
|
||||
{
|
||||
/* Load alpha channel display info */
|
||||
|
||||
DisplayInfoNew dsp_info;
|
||||
CMColor ps_color;
|
||||
GimpRGB gimp_rgb;
|
||||
GimpHSV gimp_hsv;
|
||||
GimpCMYK gimp_cmyk;
|
||||
gint16 tot_rec;
|
||||
gint cidx;
|
||||
|
||||
IFDBG(2) g_debug ("Process image resource block 1077: Display Info New");
|
||||
|
||||
/* For now, skip first 4 bytes since intention is unclear. Seems to be
|
||||
a version number that is always one, but who knows. */
|
||||
fseek (f, 4, SEEK_CUR);
|
||||
|
||||
tot_rec = res_a->data_len / 13;
|
||||
if (tot_rec == 0)
|
||||
return 0;
|
||||
|
||||
img_a->alpha_display_info = g_new (PSDchanneldata *, tot_rec);
|
||||
img_a->alpha_display_count = tot_rec;
|
||||
for (cidx = 0; cidx < tot_rec; ++cidx)
|
||||
{
|
||||
if (fread (&dsp_info.colorSpace, 2, 1, f) < 1
|
||||
|| fread (&dsp_info.color, 8, 1, f) < 1
|
||||
|| fread (&dsp_info.opacity, 2, 1, f) < 1
|
||||
|| fread (&dsp_info.mode, 1, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
dsp_info.colorSpace = GINT16_FROM_BE (dsp_info.colorSpace);
|
||||
ps_color.cmyk.cyan = GUINT16_FROM_BE (dsp_info.color[0]);
|
||||
ps_color.cmyk.magenta = GUINT16_FROM_BE (dsp_info.color[1]);
|
||||
ps_color.cmyk.yellow = GUINT16_FROM_BE (dsp_info.color[2]);
|
||||
ps_color.cmyk.black = GUINT16_FROM_BE (dsp_info.color[3]);
|
||||
dsp_info.opacity = GINT16_FROM_BE (dsp_info.opacity);
|
||||
|
||||
switch (dsp_info.colorSpace)
|
||||
{
|
||||
case PSD_CS_RGB:
|
||||
gimp_rgb_set (&gimp_rgb, ps_color.rgb.red / 65535.0,
|
||||
ps_color.rgb.green / 65535.0,
|
||||
ps_color.rgb.blue / 65535.0);
|
||||
break;
|
||||
|
||||
case PSD_CS_HSB:
|
||||
gimp_hsv_set (&gimp_hsv, ps_color.hsv.hue / 65535.0,
|
||||
ps_color.hsv.saturation / 65535.0,
|
||||
ps_color.hsv.value / 65535.0);
|
||||
gimp_hsv_to_rgb (&gimp_hsv, &gimp_rgb);
|
||||
break;
|
||||
|
||||
case PSD_CS_CMYK:
|
||||
gimp_cmyk_set (&gimp_cmyk, 1.0 - ps_color.cmyk.cyan / 65535.0,
|
||||
1.0 - ps_color.cmyk.magenta / 65535.0,
|
||||
1.0 - ps_color.cmyk.yellow / 65535.0,
|
||||
1.0 - ps_color.cmyk.black / 65535.0);
|
||||
gimp_cmyk_to_rgb (&gimp_cmyk, &gimp_rgb);
|
||||
break;
|
||||
|
||||
case PSD_CS_GRAYSCALE:
|
||||
gimp_rgb_set (&gimp_rgb, ps_color.gray.gray / 10000.0,
|
||||
ps_color.gray.gray / 10000.0,
|
||||
ps_color.gray.gray / 10000.0);
|
||||
break;
|
||||
|
||||
case PSD_CS_FOCOLTONE:
|
||||
case PSD_CS_TRUMATCH:
|
||||
case PSD_CS_HKS:
|
||||
case PSD_CS_LAB:
|
||||
case PSD_CS_PANTONE:
|
||||
case PSD_CS_TOYO:
|
||||
case PSD_CS_DIC:
|
||||
case PSD_CS_ANPA:
|
||||
default:
|
||||
if (CONVERSION_WARNINGS)
|
||||
g_message ("Unsupported color space: %d",
|
||||
dsp_info.colorSpace);
|
||||
gimp_rgb_set (&gimp_rgb, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
gimp_rgb_set_alpha (&gimp_rgb, 1.0);
|
||||
|
||||
IFDBG(2) g_debug ("PS cSpace: %d, col: %d %d %d %d, opacity: %d, kind: %d",
|
||||
dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta,
|
||||
ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity,
|
||||
dsp_info.kind);
|
||||
|
||||
IFDBG(2) g_debug ("cSpace: %d, col: %g %g %g, opacity: %d, kind: %d",
|
||||
dsp_info.colorSpace, gimp_rgb.r * 255 , gimp_rgb.g * 255,
|
||||
gimp_rgb.b * 255, dsp_info.opacity, dsp_info.kind);
|
||||
|
||||
img_a->alpha_display_info[cidx] = g_malloc (sizeof (PSDchanneldata));
|
||||
img_a->alpha_display_info[cidx]->gimp_color = gimp_rgb;
|
||||
img_a->alpha_display_info[cidx]->opacity = dsp_info.opacity;
|
||||
img_a->alpha_display_info[cidx]->ps_mode = dsp_info.mode;
|
||||
img_a->alpha_display_info[cidx]->ps_cspace = dsp_info.colorSpace;
|
||||
img_a->alpha_display_info[cidx]->ps_color = ps_color;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
load_resource_2000 (const PSDimageres *res_a,
|
||||
const gint32 image_id,
|
||||
@@ -1377,11 +1527,11 @@ load_resource_2000 (const PSDimageres *res_a,
|
||||
|| type == PSD_PATH_OP_UNLNK)
|
||||
{
|
||||
if (fread (&y[0], 4, 1, f) < 1
|
||||
|| fread (&x[0], 4, 1, f) < 1
|
||||
|| fread (&y[1], 4, 1, f) < 1
|
||||
|| fread (&x[1], 4, 1, f) < 1
|
||||
|| fread (&y[2], 4, 1, f) < 1
|
||||
|| fread (&x[2], 4, 1, f) < 1)
|
||||
|| fread (&x[0], 4, 1, f) < 1
|
||||
|| fread (&y[1], 4, 1, f) < 1
|
||||
|| fread (&x[1], 4, 1, f) < 1
|
||||
|| fread (&y[2], 4, 1, f) < 1
|
||||
|| fread (&x[2], 4, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
@@ -1429,5 +1579,5 @@ load_resource_2000 (const PSDimageres *res_a,
|
||||
path_rec--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@
|
||||
All layer resources not otherwise handled, including unknown types
|
||||
are dropped with a warning.
|
||||
|
||||
* Adjustment layer IDs *
|
||||
* Adjustment layer IDs *
|
||||
PSD_LADJ_LEVEL "levl" Drop Layer * Adjustment layer - levels (PS4) *
|
||||
PSD_LADJ_CURVE "curv" Drop Layer * Adjustment layer - curves (PS4) *
|
||||
PSD_LADJ_BRIGHTNESS "brit" Drop Layer * Adjustment layer - brightness contrast (PS4) *
|
||||
@@ -38,21 +38,23 @@
|
||||
PSD_LADJ_INVERT "nvrt" Drop Layer * Adjustment layer - invert (PS4) *
|
||||
PSD_LADJ_THRESHOLD "thrs" Drop Layer * Adjustment layer - threshold (PS4) *
|
||||
PSD_LADJ_POSTERIZE "post" Drop Layer * Adjustment layer - posterize (PS4) *
|
||||
PSD_LADJ_VIBRANCE "vibA" - * Adjustment layer - vibrance (PS10) *
|
||||
PSD_LADJ_COLOR_LOOKUP "clrL" - * Adjustment layer - color lookup (PS13) *
|
||||
|
||||
* Fill Layer IDs *
|
||||
* Fill Layer IDs *
|
||||
PSD_LFIL_SOLID "SoCo" - * Solid color sheet setting (PS6) *
|
||||
PSD_LFIL_PATTERN "PtFl" - * Pattern fill setting (PS6) *
|
||||
PSD_LFIL_GRADIENT "GdFl" - * Gradient fill setting (PS6) *
|
||||
|
||||
* Effects Layer IDs *
|
||||
* Effects Layer IDs *
|
||||
PSD_LFX_FX "lrFX" - * Effects layer info (PS5) *
|
||||
PSD_LFX_FX2 "lfx2" - * Object based effects layer info (PS6) *
|
||||
|
||||
* Type Tool Layers *
|
||||
* Type Tool Layers *
|
||||
PSD_LTYP_TYPE "tySh" - * Type tool layer (PS5) *
|
||||
PSD_LTYP_TYPE2 "TySh" - * Type tool object setting (PS6) *
|
||||
|
||||
* Layer Properties *
|
||||
* Layer Properties *
|
||||
PSD_LPRP_UNICODE "luni" Loaded * Unicode layer name (PS5) *
|
||||
PSD_LPRP_SOURCE "lnsr" Loaded * Layer name source setting (PS6) *
|
||||
PSD_LPRP_ID "lyid" Loaded * Layer ID (PS5) *
|
||||
@@ -63,13 +65,13 @@
|
||||
PSD_LPRP_COLOR "lclr" - * Sheet color setting (PS6) *
|
||||
PSD_LPRP_REF_POINT "fxrp" - * Reference point (PS6) *
|
||||
|
||||
* Vector mask *
|
||||
* Vector mask *
|
||||
PSD_LMSK_VMASK "vmsk" - * Vector mask setting (PS6) *
|
||||
|
||||
* Parasites *
|
||||
* Parasites *
|
||||
PSD_LPAR_ANNOTATE "Anno" - * Annotation (PS6) *
|
||||
|
||||
* Other *
|
||||
* Other *
|
||||
PSD_LOTH_PATTERN "Patt" - * Patterns (PS6) *
|
||||
PSD_LOTH_GRADIENT "grdm" - * Gradient settings (PS6) *
|
||||
PSD_LOTH_SECTION "lsct" Loaded * Section divider setting (PS6) (Layer Groups) *
|
||||
@@ -78,14 +80,42 @@
|
||||
PSD_LOTH_PATT_DATA "shpa" - * Pattern data (PS6) *
|
||||
PSD_LOTH_META_DATA "shmd" - * Meta data setting (PS6) *
|
||||
PSD_LOTH_LAYER_DATA "layr" - * Layer data (PS6) *
|
||||
PSD_LOTH_CONTENT_GEN "CgEd" - * Content generator extra data (PS12) *
|
||||
PSD_LOTH_TEXT_ENGINE "Txt2" - * Text engine data (PS10) *
|
||||
PSD_LOTH_PATH_NAME "pths" - * Unicode path name (PS13) *
|
||||
PSD_LOTH_ANIMATION_FX "anFX" - * Animation effects (PS13) *
|
||||
PSD_LOTH_FILTER_MASK "FMsk" - * Filter mask (PS10) *
|
||||
PSD_LOTH_VECTOR_STROKE "vscg" - * Vector stroke data (PS13) *
|
||||
PSD_LOTH_ALIGN_RENDER "sn2P" - * Aligned rendering flag (?) *
|
||||
PSD_LOTH_USER_MASK "LMsk" - * User mask (?) *
|
||||
|
||||
* Effects layer resource IDs *
|
||||
* Effects layer resource IDs *
|
||||
PSD_LFX_COMMON "cmnS" - * Effects layer - common state (PS5) *
|
||||
PSD_LFX_DROP_SDW "dsdw" - * Effects layer - drop shadow (PS5) *
|
||||
PSD_LFX_INNER_SDW "isdw" - * Effects layer - inner shadow (PS5) *
|
||||
PSD_LFX_OUTER_GLW "oglw" - * Effects layer - outer glow (PS5) *
|
||||
PSD_LFX_INNER_GLW "iglw" - * Effects layer - inner glow (PS5) *
|
||||
PSD_LFX_BEVEL "bevl" - * Effects layer - bevel (PS5) *
|
||||
|
||||
* New stuff temporarily until I can get them sorted out *
|
||||
|
||||
* Placed Layer *
|
||||
PSD_LPL_PLACE_LAYER "plLd" - * Placed layer (?) *
|
||||
PSD_LPL_PLACE_LAYER_NEW "SoLd" - * Placed layer (PS10) *
|
||||
|
||||
* Linked Layer *
|
||||
PSD_LLL_LINKED_LAYER "lnkD" - * Linked layer (?) *
|
||||
PSD_LLL_LINKED_LAYER_2 "lnk2" - * Linked layer 2nd key *
|
||||
PSD_LLL_LINKED_LAYER_3 "lnk3" - * Linked layer 3rd key *
|
||||
|
||||
* Merged Transparency *
|
||||
PSD_LMT_MERGE_TRANS "Mtrn" - * Merged transperency save flag (?) *
|
||||
PSD_LMT_MERGE_TRANS_16 "Mt16" - * Merged transperency save flag 2 *
|
||||
PSD_LMT_MERGE_TRANS_32 "Mt32" - * Merged transperency save flag 3 *
|
||||
|
||||
* Filter Effects *
|
||||
PSD_LFFX_FILTER_FX "FXid" - * Filter effects (?) *
|
||||
PSD_LFFX_FILTER_FX_2 "FEid" - * Filter effects 2 *
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -143,6 +173,10 @@ static gint load_resource_lsct (const PSDlayerres *res_a,
|
||||
FILE *f,
|
||||
GError **error);
|
||||
|
||||
static gint load_resource_lrfx (const PSDlayerres *res_a,
|
||||
PSDlayer *lyr_a,
|
||||
FILE *f,
|
||||
GError **error);
|
||||
|
||||
/* Public Functions */
|
||||
gint
|
||||
@@ -161,7 +195,7 @@ get_layer_resource_header (PSDlayerres *res_a,
|
||||
res_a->data_start = ftell (f);
|
||||
|
||||
IFDBG(2) g_debug ("Sig: %.4s, key: %.4s, start: %d, len: %d",
|
||||
res_a->sig, res_a->key, res_a->data_start, res_a->data_len);
|
||||
res_a->sig, res_a->key, res_a->data_start, res_a->data_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -179,7 +213,7 @@ load_layer_resource (PSDlayerres *res_a,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process layer resource blocks */
|
||||
/* Process layer resource blocks */
|
||||
if (memcmp (res_a->sig, "8BIM", 4) != 0)
|
||||
{
|
||||
IFDBG(1) g_debug ("Unknown layer resource signature %.4s", res_a->sig);
|
||||
@@ -201,30 +235,32 @@ load_layer_resource (PSDlayerres *res_a,
|
||||
|| memcmp (res_a->key, PSD_LADJ_THRESHOLD, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LADJ_INVERT, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LADJ_POSTERIZE, 4) == 0)
|
||||
load_resource_ladj (res_a, lyr_a, f, error);
|
||||
load_resource_ladj (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LFIL_SOLID, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LFIL_PATTERN, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LFIL_GRADIENT, 4) == 0)
|
||||
load_resource_lfil (res_a, lyr_a, f, error);
|
||||
|| memcmp (res_a->key, PSD_LFIL_PATTERN, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LFIL_GRADIENT, 4) == 0)
|
||||
load_resource_lfil (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LFX_FX, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LFX_FX2, 4) == 0)
|
||||
load_resource_lfx (res_a, lyr_a, f, error);
|
||||
|| memcmp (res_a->key, PSD_LFX_FX2, 4) == 0)
|
||||
load_resource_lfx (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LTYP_TYPE, 4) == 0
|
||||
|| memcmp (res_a->key, PSD_LTYP_TYPE2, 4) == 0)
|
||||
load_resource_ltyp (res_a, lyr_a, f, error);
|
||||
|| memcmp (res_a->key, PSD_LTYP_TYPE2, 4) == 0)
|
||||
load_resource_ltyp (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LPRP_UNICODE, 4) == 0)
|
||||
load_resource_luni (res_a, lyr_a, f, error);
|
||||
load_resource_luni (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LPRP_ID, 4) == 0)
|
||||
load_resource_lyid (res_a, lyr_a, f, error);
|
||||
load_resource_lyid (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LOTH_SECTION, 4) == 0)
|
||||
load_resource_lsct (res_a, lyr_a, f, error);
|
||||
load_resource_lsct (res_a, lyr_a, f, error);
|
||||
|
||||
else if (memcmp (res_a->key, PSD_LFX_FX, 4) == 0)
|
||||
load_resource_lrfx (res_a, lyr_a, f, error);
|
||||
else
|
||||
load_resource_unknown (res_a, lyr_a, f, error);
|
||||
}
|
||||
@@ -329,18 +365,15 @@ load_resource_ltyp (const PSDlayerres *res_a,
|
||||
gint16 version;
|
||||
gint16 text_desc_vers;
|
||||
gint32 desc_version;
|
||||
gint32 read_len;
|
||||
gint32 write_len;
|
||||
guint64 t_xx;
|
||||
guint64 t_xy;
|
||||
guint64 t_yx;
|
||||
guint64 t_yy;
|
||||
guint64 t_tx;
|
||||
guint64 t_ty;
|
||||
gdouble transform_xx;
|
||||
gdouble transform_xy;
|
||||
gdouble transform_yx;
|
||||
gdouble transform_yy;
|
||||
gdouble transform_tx;
|
||||
gdouble transform_ty;
|
||||
gchar *classID;
|
||||
|
||||
static gboolean msg_flag = FALSE;
|
||||
|
||||
@@ -374,31 +407,30 @@ load_resource_ltyp (const PSDlayerres *res_a,
|
||||
version = GINT16_FROM_BE (version);
|
||||
text_desc_vers = GINT16_FROM_BE (text_desc_vers);
|
||||
desc_version = GINT32_FROM_BE (desc_version);
|
||||
// t_xx = GUINT64_FROM_BE (t_xx);
|
||||
// t_xy = GUINT64_FROM_BE (t_xy);
|
||||
// t_yx = GUINT64_FROM_BE (t_yx);
|
||||
// t_yy = GUINT64_FROM_BE (t_yy);
|
||||
// t_tx = GUINT64_FROM_BE (t_tx);
|
||||
// t_ty = GUINT64_FROM_BE (t_ty);
|
||||
// t_xx = GUINT64_FROM_BE (t_xx);
|
||||
// t_xy = GUINT64_FROM_BE (t_xy);
|
||||
// t_yx = GUINT64_FROM_BE (t_yx);
|
||||
// t_yy = GUINT64_FROM_BE (t_yy);
|
||||
// t_tx = GUINT64_FROM_BE (t_tx);
|
||||
// t_ty = GUINT64_FROM_BE (t_ty);
|
||||
|
||||
transform_xx = t_xx >> 11;
|
||||
transform_xy = t_xy >> 11;
|
||||
transform_yx = t_yx >> 11;
|
||||
transform_yy = t_yy >> 11;
|
||||
transform_tx = t_tx >> 11;
|
||||
transform_ty = t_ty >> 11;
|
||||
lyr_a->text.xx = t_xx >> 11;
|
||||
lyr_a->text.xy = t_xy >> 11;
|
||||
lyr_a->text.yx = t_yx >> 11;
|
||||
lyr_a->text.yy = t_yy >> 11;
|
||||
lyr_a->text.tx = t_tx >> 11;
|
||||
lyr_a->text.ty = t_ty >> 11;
|
||||
|
||||
IFDBG(2) g_debug ("Version: %d, Text desc. vers.: %d, Desc. vers.: %d",
|
||||
version, text_desc_vers, desc_version);
|
||||
|
||||
IFDBG(2) g_debug ("Transform\n\txx: %f\n\txy: %f\n\tyx: %f"
|
||||
"\n\tyy: %f\n\ttx: %f\n\tty: %f",
|
||||
transform_xx, transform_xy, transform_yx,
|
||||
transform_yy, transform_tx, transform_ty);
|
||||
|
||||
// classID = fread_unicode_string (&read_len, &write_len, 4, f);
|
||||
// IFDBG(2) g_debug ("Unicode name: %s", classID);
|
||||
lyr_a->text.xx, lyr_a->text.xy, lyr_a->text.yx,
|
||||
lyr_a->text.yy, lyr_a->text.tx, lyr_a->text.ty);
|
||||
|
||||
classID = fread_unicode_string (&read_len, &write_len, 4, f, error);
|
||||
IFDBG(2) g_debug ("Unicode name: %s", classID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -472,3 +504,342 @@ load_resource_lsct (const PSDlayerres *res_a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
load_resource_lrfx (const PSDlayerres *res_a,
|
||||
PSDlayer *lyr_a,
|
||||
FILE *f,
|
||||
GError **error)
|
||||
{
|
||||
gint16 version;
|
||||
gint16 count;
|
||||
gchar signature[4];
|
||||
gchar effectname[4];
|
||||
gint i;
|
||||
|
||||
IFDBG(2) g_debug ("Process layer resource block %.4s: Layer effects", res_a->key);
|
||||
|
||||
if (fread (&version, 2, 1, f) < 1
|
||||
|| fread (&count, 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (fread (&signature, 4, 1, f) < 1
|
||||
|| fread(&effectname, 4, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp (signature, "8BIM", 4) != 0)
|
||||
{
|
||||
IFDBG(1) g_debug ("Unknown layer resource signature %.4s", signature);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memcmp (effectname, "cmnS", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gchar visible;
|
||||
gint16 unused;
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&visible, 1, 1, f) < 1
|
||||
|| fread(&unused, 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "dsdw", 4) == 0
|
||||
|| memcmp (effectname, "isdw", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 blur;
|
||||
gint32 intensity;
|
||||
gint32 angle;
|
||||
gint32 distance;
|
||||
gint16 color[5];
|
||||
gint32 blendsig;
|
||||
gint32 effect;
|
||||
gchar effecton;
|
||||
gchar anglefx;
|
||||
gchar opacity;
|
||||
gint16 natcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&blur, 4, 1, f) < 1
|
||||
|| fread(&intensity, 4, 1, f) < 1
|
||||
|| fread(&angle, 4, 1, f) < 1
|
||||
|| fread(&distance, 4, 1, f) < 1
|
||||
|| fread(&color[0], 2, 1, f) < 1
|
||||
|| fread(&color[1], 2, 1, f) < 1
|
||||
|| fread(&color[2], 2, 1, f) < 1
|
||||
|| fread(&color[3], 2, 1, f) < 1
|
||||
|| fread(&color[4], 2, 1, f) < 1
|
||||
|| fread(&blendsig, 4, 1, f) < 1
|
||||
|| fread(&effect, 4, 1, f) < 1
|
||||
|| fread(&effecton, 1, 1, f) < 1
|
||||
|| fread(&anglefx, 1, 1, f) < 1
|
||||
|| fread(&opacity, 1, 1, f) < 1
|
||||
|| fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[1], 2, 1, f) < 1
|
||||
|| fread(&natcolor[2], 2, 1, f) < 1
|
||||
|| fread(&natcolor[3], 2, 1, f) < 1
|
||||
|| fread(&natcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "oglw", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 blur;
|
||||
gint32 intensity;
|
||||
gint16 color[5];
|
||||
gint32 blendsig;
|
||||
gint32 effect;
|
||||
gchar effecton;
|
||||
gchar opacity;
|
||||
gint16 natcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&blur, 4, 1, f) < 1
|
||||
|| fread(&intensity, 4, 1, f) < 1
|
||||
|| fread(&color[0], 2, 1, f) < 1
|
||||
|| fread(&color[1], 2, 1, f) < 1
|
||||
|| fread(&color[2], 2, 1, f) < 1
|
||||
|| fread(&color[3], 2, 1, f) < 1
|
||||
|| fread(&color[4], 2, 1, f) < 1
|
||||
|| fread(&blendsig, 4, 1, f) < 1
|
||||
|| fread(&effect, 4, 1, f) < 1
|
||||
|| fread(&effecton, 1, 1, f) < 1
|
||||
|| fread(&opacity, 1, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver == 42)
|
||||
{
|
||||
if (fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[1], 2, 1, f) < 1
|
||||
|| fread(&natcolor[2], 2, 1, f) < 1
|
||||
|| fread(&natcolor[3], 2, 1, f) < 1
|
||||
|| fread(&natcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "iglw", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 blur;
|
||||
gint32 intensity;
|
||||
gint32 angle;
|
||||
gint32 distance;
|
||||
gint16 color[5];
|
||||
gint32 blendsig;
|
||||
gint32 effect;
|
||||
gchar effecton;
|
||||
gchar anglefx;
|
||||
gchar opacity;
|
||||
gint16 natcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&blur, 4, 1, f) < 1
|
||||
|| fread(&intensity, 4, 1, f) < 1
|
||||
|| fread(&angle, 4, 1, f) < 1
|
||||
|| fread(&distance, 4, 1, f) < 1
|
||||
|| fread(&color[0], 2, 1, f) < 1
|
||||
|| fread(&color[1], 2, 1, f) < 1
|
||||
|| fread(&color[2], 2, 1, f) < 1
|
||||
|| fread(&color[3], 2, 1, f) < 1
|
||||
|| fread(&color[4], 2, 1, f) < 1
|
||||
|| fread(&blendsig, 4, 1, f) < 1
|
||||
|| fread(&effect, 4, 1, f) < 1
|
||||
|| fread(&effecton, 1, 1, f) < 1
|
||||
|| fread(&anglefx, 1, 1, f) < 1
|
||||
|| fread(&opacity, 1, 1, f) < 1
|
||||
|| fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[1], 2, 1, f) < 1
|
||||
|| fread(&natcolor[2], 2, 1, f) < 1
|
||||
|| fread(&natcolor[3], 2, 1, f) < 1
|
||||
|| fread(&natcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "oglw", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 blur;
|
||||
gint32 intensity;
|
||||
gint16 color[5];
|
||||
gint32 blendsig;
|
||||
gint32 effect;
|
||||
gchar effecton;
|
||||
gchar opacity;
|
||||
gchar invert;
|
||||
gint16 natcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&blur, 4, 1, f) < 1
|
||||
|| fread(&intensity, 4, 1, f) < 1
|
||||
|| fread(&color[0], 2, 1, f) < 1
|
||||
|| fread(&color[1], 2, 1, f) < 1
|
||||
|| fread(&color[2], 2, 1, f) < 1
|
||||
|| fread(&color[3], 2, 1, f) < 1
|
||||
|| fread(&color[4], 2, 1, f) < 1
|
||||
|| fread(&blendsig, 4, 1, f) < 1
|
||||
|| fread(&effect, 4, 1, f) < 1
|
||||
|| fread(&effecton, 1, 1, f) < 1
|
||||
|| fread(&opacity, 1, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver == 43)
|
||||
{
|
||||
if (fread (&invert, 1, 1, f) < 1
|
||||
|| fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[1], 2, 1, f) < 1
|
||||
|| fread(&natcolor[2], 2, 1, f) < 1
|
||||
|| fread(&natcolor[3], 2, 1, f) < 1
|
||||
|| fread(&natcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "bevl", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 angle;
|
||||
gint32 strength;
|
||||
gint32 blur;
|
||||
gint32 highlightsig;
|
||||
gint32 highlighteffect;
|
||||
gint32 shadowsig;
|
||||
gint32 shadoweffect;
|
||||
gint16 highlightcolor[5];
|
||||
gint16 shadowcolor[5];
|
||||
gchar style;
|
||||
gchar highlightopacity;
|
||||
gchar shadowopacity;
|
||||
gchar enabled;
|
||||
gchar global;
|
||||
gchar direction;
|
||||
gint16 highlightnatcolor[5];
|
||||
gint16 shadownatcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&angle, 4, 1, f) < 1
|
||||
|| fread(&strength, 4, 1, f) < 1
|
||||
|| fread(&blur, 4, 1, f) < 1
|
||||
|| fread(&highlightsig, 4, 1, f) < 1
|
||||
|| fread(&highlighteffect, 4, 1, f) < 1
|
||||
|| fread(&shadowsig, 4, 1, f) < 1
|
||||
|| fread(&highlightcolor[0], 2, 1, f) < 1
|
||||
|| fread(&shadoweffect, 4, 1, f) < 1
|
||||
|| fread(&highlightcolor[1], 2, 1, f) < 1
|
||||
|| fread(&highlightcolor[2], 2, 1, f) < 1
|
||||
|| fread(&highlightcolor[3], 2, 1, f) < 1
|
||||
|| fread(&highlightcolor[4], 2, 1, f) < 1
|
||||
|| fread(&shadowcolor[0], 2, 1, f) < 1
|
||||
|| fread(&shadowcolor[1], 2, 1, f) < 1
|
||||
|| fread(&shadowcolor[2], 2, 1, f) < 1
|
||||
|| fread(&shadowcolor[3], 2, 1, f) < 1
|
||||
|| fread(&shadowcolor[4], 2, 1, f) < 1
|
||||
|| fread(&style, 1, 1, f) < 1
|
||||
|| fread(&highlightopacity, 1, 1, f) < 1
|
||||
|| fread(&shadowopacity, 1, 1, f) < 1
|
||||
|| fread(&enabled, 1, 1, f) < 1
|
||||
|| fread(&global, 1, 1, f) < 1
|
||||
|| fread(&direction, 1, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver == 78)
|
||||
{
|
||||
if (fread(&highlightnatcolor[0], 2, 1, f) < 1
|
||||
|| fread(&highlightnatcolor[0], 2, 1, f) < 1
|
||||
|| fread(&highlightnatcolor[1], 2, 1, f) < 1
|
||||
|| fread(&highlightnatcolor[2], 2, 1, f) < 1
|
||||
|| fread(&highlightnatcolor[3], 2, 1, f) < 1
|
||||
|| fread(&highlightnatcolor[4], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[0], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[0], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[1], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[2], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[3], 2, 1, f) < 1
|
||||
|| fread(&shadownatcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (memcmp (effectname, "sofi", 4) == 0)
|
||||
{
|
||||
gint32 size;
|
||||
gint32 ver;
|
||||
gint32 key;
|
||||
gint16 color[5];
|
||||
gchar opacity;
|
||||
gchar enabled;
|
||||
gint16 natcolor[5];
|
||||
|
||||
if (fread (&size, 4, 1, f) < 1
|
||||
|| fread(&ver, 4, 1, f) < 1
|
||||
|| fread(&key, 4, 1, f) < 1
|
||||
|| fread(&color[0], 2, 1, f) < 1
|
||||
|| fread(&color[1], 2, 1, f) < 1
|
||||
|| fread(&color[2], 2, 1, f) < 1
|
||||
|| fread(&color[3], 2, 1, f) < 1
|
||||
|| fread(&color[4], 2, 1, f) < 1
|
||||
|| fread(&opacity, 1, 1, f) < 1
|
||||
|| fread(&enabled, 1, 1, f) < 1
|
||||
|| fread(&natcolor[0], 2, 1, f) < 1
|
||||
|| fread(&natcolor[1], 2, 1, f) < 1
|
||||
|| fread(&natcolor[2], 2, 1, f) < 1
|
||||
|| fread(&natcolor[3], 2, 1, f) < 1
|
||||
|| fread(&natcolor[4], 2, 1, f) < 1)
|
||||
{
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IFDBG(1) g_debug ("Unknown layer effect signature %.4s", effectname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -97,15 +97,13 @@ static gint read_channel_data (PSDchannel *channel,
|
||||
FILE *f,
|
||||
GError **error);
|
||||
|
||||
static void convert_16_bit (const gchar *src,
|
||||
gchar *dst,
|
||||
guint32 len);
|
||||
|
||||
static void convert_1_bit (const gchar *src,
|
||||
gchar *dst,
|
||||
guint32 rows,
|
||||
guint32 columns);
|
||||
|
||||
static const Babl* get_pixel_format (PSDimage *img_a);
|
||||
|
||||
|
||||
/* Main file load function */
|
||||
gint32
|
||||
@@ -326,16 +324,15 @@ read_header_block (PSDimage *img_a,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Warnings for format conversions */
|
||||
/* Warning for unsupported bit depth */
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
IFDBG(3) g_debug ("32 Bit Data");
|
||||
break;
|
||||
|
||||
case 16:
|
||||
IFDBG(3) g_debug ("16 Bit Data");
|
||||
if (CONVERSION_WARNINGS)
|
||||
g_message (_("Warning:\n"
|
||||
"The image you are loading has 16 bits per channel. GIMP "
|
||||
"can only handle 8 bit, so it will be converted for you. "
|
||||
"Information will be lost because of this conversion."));
|
||||
break;
|
||||
|
||||
case 8:
|
||||
@@ -484,6 +481,7 @@ read_layer_block (PSDimage *img_a,
|
||||
img_a->num_layers = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
img_a->mask_layer_len = GUINT32_FROM_BE (block_len);
|
||||
|
||||
IFDBG(1) g_debug ("Layer and mask block size = %d", img_a->mask_layer_len);
|
||||
@@ -525,6 +523,7 @@ read_layer_block (PSDimage *img_a,
|
||||
|
||||
/* Create pointer array for the layer records */
|
||||
lyr_a = g_new (PSDlayer *, img_a->num_layers);
|
||||
|
||||
for (lidx = 0; lidx < img_a->num_layers; ++lidx)
|
||||
{
|
||||
/* Allocate layer record */
|
||||
@@ -544,6 +543,7 @@ read_layer_block (PSDimage *img_a,
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lyr_a[lidx]->top = GINT32_FROM_BE (lyr_a[lidx]->top);
|
||||
lyr_a[lidx]->left = GINT32_FROM_BE (lyr_a[lidx]->left);
|
||||
lyr_a[lidx]->bottom = GINT32_FROM_BE (lyr_a[lidx]->bottom);
|
||||
@@ -590,6 +590,7 @@ read_layer_block (PSDimage *img_a,
|
||||
lyr_a[lidx]->num_channels);
|
||||
|
||||
lyr_a[lidx]->chn_info = g_new (ChannelLengthInfo, lyr_a[lidx]->num_channels);
|
||||
|
||||
for (cidx = 0; cidx < lyr_a[lidx]->num_channels; ++cidx)
|
||||
{
|
||||
if (fread (&lyr_a[lidx]->chn_info[cidx].channel_id, 2, 1, f) < 1
|
||||
@@ -630,6 +631,7 @@ read_layer_block (PSDimage *img_a,
|
||||
|
||||
lyr_a[lidx]->layer_flags.trans_prot = lyr_a[lidx]->flags & 1 ? TRUE : FALSE;
|
||||
lyr_a[lidx]->layer_flags.visible = lyr_a[lidx]->flags & 2 ? FALSE : TRUE;
|
||||
|
||||
if (lyr_a[lidx]->flags & 8)
|
||||
lyr_a[lidx]->layer_flags.irrelevant = lyr_a[lidx]->flags & 16 ? TRUE : FALSE;
|
||||
else
|
||||
@@ -802,9 +804,11 @@ read_layer_block (PSDimage *img_a,
|
||||
psd_set_error (feof (f), errno, error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block_len = GUINT32_FROM_BE (block_len);
|
||||
block_rem -= (block_len + 4);
|
||||
IFDBG(3) g_debug ("Remaining length %d", block_rem);
|
||||
|
||||
if (block_len > 0)
|
||||
{
|
||||
if (fseek (f, block_len, SEEK_CUR) < 0)
|
||||
@@ -818,6 +822,7 @@ read_layer_block (PSDimage *img_a,
|
||||
4, f, error);
|
||||
if (*error)
|
||||
return NULL;
|
||||
|
||||
block_rem -= read_len;
|
||||
IFDBG(3) g_debug ("Remaining length %d", block_rem);
|
||||
|
||||
@@ -827,8 +832,13 @@ read_layer_block (PSDimage *img_a,
|
||||
{
|
||||
if (get_layer_resource_header (&res_a, f, error) < 0)
|
||||
return NULL;
|
||||
|
||||
block_rem -= 12;
|
||||
|
||||
//Round up to the nearest even byte
|
||||
while (res_a.data_len % 4 != 0)
|
||||
res_a.data_len++;
|
||||
|
||||
if (res_a.data_len > block_rem)
|
||||
{
|
||||
IFDBG(1) g_debug ("Unexpected end of layer resource data");
|
||||
@@ -902,6 +912,7 @@ create_gimp_image (PSDimage *img_a,
|
||||
const gchar *filename)
|
||||
{
|
||||
gint32 image_id = -1;
|
||||
GimpPrecision precision;
|
||||
|
||||
switch (img_a->color_mode)
|
||||
{
|
||||
@@ -926,10 +937,32 @@ create_gimp_image (PSDimage *img_a,
|
||||
break;
|
||||
}
|
||||
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
precision = GIMP_PRECISION_U32_LINEAR;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
precision = GIMP_PRECISION_U16_LINEAR;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 1:
|
||||
precision = GIMP_PRECISION_U8_LINEAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Precision not supported */
|
||||
g_warning ("Invalid precision");
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create gimp image */
|
||||
IFDBG(2) g_debug ("Create image");
|
||||
image_id = gimp_image_new (img_a->columns, img_a->rows, img_a->base_type);
|
||||
|
||||
image_id = gimp_image_new_with_precision (img_a->columns, img_a->rows,
|
||||
img_a->base_type, precision);
|
||||
gimp_image_set_filename (image_id, filename);
|
||||
gimp_image_undo_disable (image_id);
|
||||
|
||||
@@ -1025,6 +1058,7 @@ add_layers (const gint32 image_id,
|
||||
guint16 layer_channels;
|
||||
guint16 channel_idx[MAX_CHANNELS];
|
||||
guint16 *rle_pack_len;
|
||||
guint16 bps;
|
||||
gint32 l_x; /* Layer x */
|
||||
gint32 l_y; /* Layer y */
|
||||
gint32 l_w; /* Layer width */
|
||||
@@ -1045,8 +1079,7 @@ add_layers (const gint32 image_id,
|
||||
gboolean user_mask;
|
||||
gboolean empty;
|
||||
gboolean empty_mask;
|
||||
GimpDrawable *drawable;
|
||||
GimpPixelRgn pixel_rgn;
|
||||
GeglBuffer *buffer;
|
||||
GimpImageType image_type;
|
||||
GimpLayerModeEffects layer_mode;
|
||||
|
||||
@@ -1092,25 +1125,25 @@ add_layers (const gint32 image_id,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lyr_a[lidx]->group_type != 0)
|
||||
{
|
||||
if (lyr_a[lidx]->group_type == 3)
|
||||
{
|
||||
/* the </Layer group> marker layers are used to
|
||||
assemble the layer structure in a single pass */
|
||||
layer_id = gimp_layer_group_new (image_id);
|
||||
}
|
||||
else /* group-type == 1 || group_type == 2 */
|
||||
{
|
||||
layer_id = g_array_index (parent_group_stack, gint32,
|
||||
parent_group_stack->len-1);
|
||||
/* since the layers are stored in reverse, the group
|
||||
layer start marker actually means we're done with
|
||||
that layer group */
|
||||
g_array_remove_index (parent_group_stack,
|
||||
parent_group_stack->len-1);
|
||||
}
|
||||
}
|
||||
if (lyr_a[lidx]->group_type != 0)
|
||||
{
|
||||
if (lyr_a[lidx]->group_type == 3)
|
||||
{
|
||||
/* the </Layer group> marker layers are used to
|
||||
assemble the layer structure in a single pass */
|
||||
layer_id = gimp_layer_group_new (image_id);
|
||||
}
|
||||
else /* group-type == 1 || group_type == 2 */
|
||||
{
|
||||
layer_id = g_array_index (parent_group_stack, gint32,
|
||||
parent_group_stack->len-1);
|
||||
/* since the layers are stored in reverse, the group
|
||||
layer start marker actually means we're done with
|
||||
that layer group */
|
||||
g_array_remove_index (parent_group_stack,
|
||||
parent_group_stack->len-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Empty layer */
|
||||
if (lyr_a[lidx]->bottom - lyr_a[lidx]->top == 0
|
||||
@@ -1228,7 +1261,7 @@ add_layers (const gint32 image_id,
|
||||
g_free (rle_pack_len);
|
||||
break;
|
||||
|
||||
case PSD_COMP_ZIP: /* ? */
|
||||
case PSD_COMP_ZIP: /* ? */
|
||||
case PSD_COMP_ZIP_PRED:
|
||||
default:
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
@@ -1292,20 +1325,15 @@ add_layers (const gint32 image_id,
|
||||
else
|
||||
{
|
||||
IFDBG(2) g_debug ("End group layer id %d.", layer_id);
|
||||
drawable = gimp_drawable_get (layer_id);
|
||||
layer_mode = psd_to_gimp_blend_mode (lyr_a[lidx]->blend_mode);
|
||||
gimp_layer_set_mode (layer_id, layer_mode);
|
||||
gimp_layer_set_opacity (layer_id,
|
||||
lyr_a[lidx]->opacity * 100 / 255);
|
||||
gimp_item_set_name (drawable->drawable_id, lyr_a[lidx]->name);
|
||||
gimp_item_set_name (layer_id, lyr_a[lidx]->name);
|
||||
g_free (lyr_a[lidx]->name);
|
||||
gimp_item_set_visible (drawable->drawable_id,
|
||||
lyr_a[lidx]->layer_flags.visible);
|
||||
gimp_item_set_visible (layer_id, lyr_a[lidx]->layer_flags.visible);
|
||||
if (lyr_a[lidx]->id)
|
||||
gimp_item_set_tattoo (drawable->drawable_id,
|
||||
lyr_a[lidx]->id);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
gimp_item_set_tattoo (layer_id, lyr_a[lidx]->id);
|
||||
}
|
||||
}
|
||||
else if (empty)
|
||||
@@ -1317,15 +1345,12 @@ add_layers (const gint32 image_id,
|
||||
image_type, 0, GIMP_NORMAL_MODE);
|
||||
g_free (lyr_a[lidx]->name);
|
||||
gimp_image_insert_layer (image_id, layer_id, parent_group_id, -1);
|
||||
drawable = gimp_drawable_get (layer_id);
|
||||
gimp_drawable_fill (drawable->drawable_id, GIMP_TRANSPARENT_FILL);
|
||||
gimp_item_set_visible (drawable->drawable_id, lyr_a[lidx]->layer_flags.visible);
|
||||
gimp_drawable_fill (layer_id, GIMP_TRANSPARENT_FILL);
|
||||
gimp_item_set_visible (layer_id, lyr_a[lidx]->layer_flags.visible);
|
||||
if (lyr_a[lidx]->id)
|
||||
gimp_item_set_tattoo (drawable->drawable_id, lyr_a[lidx]->id);
|
||||
gimp_item_set_tattoo (layer_id, lyr_a[lidx]->id);
|
||||
if (lyr_a[lidx]->layer_flags.irrelevant)
|
||||
gimp_item_set_visible (drawable->drawable_id, FALSE);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
gimp_item_set_visible (layer_id, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1338,12 +1363,16 @@ add_layers (const gint32 image_id,
|
||||
image_type = get_gimp_image_type (img_a->base_type, alpha);
|
||||
IFDBG(3) g_debug ("Layer type %d", image_type);
|
||||
layer_size = l_w * l_h;
|
||||
pixels = g_malloc (layer_size * layer_channels);
|
||||
bps = img_a->bps / 8;
|
||||
if (bps == 0)
|
||||
bps++;
|
||||
pixels = g_malloc (layer_size * layer_channels * bps);
|
||||
for (cidx = 0; cidx < layer_channels; ++cidx)
|
||||
{
|
||||
IFDBG(3) g_debug ("Start channel %d", channel_idx[cidx]);
|
||||
for (i = 0; i < layer_size; ++i)
|
||||
pixels[(i * layer_channels) + cidx] = lyr_chn[channel_idx[cidx]]->data[i];
|
||||
memcpy (&pixels[((i * layer_channels) + cidx) * bps],
|
||||
&lyr_chn[channel_idx[cidx]]->data[i * bps], bps);
|
||||
g_free (lyr_chn[channel_idx[cidx]]->data);
|
||||
}
|
||||
|
||||
@@ -1356,16 +1385,13 @@ add_layers (const gint32 image_id,
|
||||
gimp_image_insert_layer (image_id, layer_id, parent_group_id, -1);
|
||||
gimp_layer_set_offsets (layer_id, l_x, l_y);
|
||||
gimp_layer_set_lock_alpha (layer_id, lyr_a[lidx]->layer_flags.trans_prot);
|
||||
drawable = gimp_drawable_get (layer_id);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
|
||||
drawable->width, drawable->height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, pixels,
|
||||
0, 0, drawable->width, drawable->height);
|
||||
gimp_item_set_visible (drawable->drawable_id, lyr_a[lidx]->layer_flags.visible);
|
||||
buffer = gimp_drawable_get_buffer (layer_id);
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)),
|
||||
0, get_pixel_format (img_a), pixels, GEGL_AUTO_ROWSTRIDE);
|
||||
gimp_item_set_visible (layer_id, lyr_a[lidx]->layer_flags.visible);
|
||||
if (lyr_a[lidx]->id)
|
||||
gimp_item_set_tattoo (drawable->drawable_id, lyr_a[lidx]->id);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
gimp_item_set_tattoo (layer_id, lyr_a[lidx]->id);
|
||||
g_object_unref (buffer);
|
||||
g_free (pixels);
|
||||
}
|
||||
|
||||
@@ -1463,12 +1489,10 @@ add_layers (const gint32 image_id,
|
||||
|
||||
IFDBG(3) g_debug ("New layer mask %d", mask_id);
|
||||
gimp_layer_add_mask (layer_id, mask_id);
|
||||
drawable = gimp_drawable_get (mask_id);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0 , 0,
|
||||
drawable->width, drawable->height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, pixels, lm_x, lm_y, lm_w, lm_h);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
buffer = gimp_drawable_get_buffer (mask_id);
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (lm_x, lm_y, lm_w, lm_h), 0,
|
||||
get_pixel_format (img_a), pixels, GEGL_AUTO_ROWSTRIDE);
|
||||
g_object_unref (buffer);
|
||||
gimp_layer_set_apply_mask (layer_id,
|
||||
! lyr_a[lidx]->layer_mask.mask_flags.disabled);
|
||||
g_free (pixels);
|
||||
@@ -1500,6 +1524,7 @@ add_merged_image (const gint32 image_id,
|
||||
guint16 base_channels;
|
||||
guint16 extra_channels;
|
||||
guint16 total_channels;
|
||||
guint16 bps;
|
||||
guint16 *rle_pack_len[MAX_CHANNELS];
|
||||
guint32 alpha_id;
|
||||
gint32 layer_size;
|
||||
@@ -1514,13 +1539,15 @@ add_merged_image (const gint32 image_id,
|
||||
gint offset;
|
||||
gint i;
|
||||
gboolean alpha_visible;
|
||||
GimpDrawable *drawable;
|
||||
GimpPixelRgn pixel_rgn;
|
||||
GeglBuffer *buffer;
|
||||
GimpImageType image_type;
|
||||
GimpRGB alpha_rgb;
|
||||
|
||||
total_channels = img_a->channels;
|
||||
extra_channels = 0;
|
||||
bps = img_a->bps / 8;
|
||||
if (bps == 0)
|
||||
bps++;
|
||||
|
||||
if ((img_a->color_mode == PSD_BITMAP ||
|
||||
img_a->color_mode == PSD_GRAYSCALE ||
|
||||
@@ -1626,12 +1653,13 @@ add_merged_image (const gint32 image_id,
|
||||
image_type = get_gimp_image_type (img_a->base_type, img_a->transparency);
|
||||
|
||||
layer_size = img_a->columns * img_a->rows;
|
||||
pixels = g_malloc (layer_size * base_channels);
|
||||
pixels = g_malloc (layer_size * base_channels * bps);
|
||||
for (cidx = 0; cidx < base_channels; ++cidx)
|
||||
{
|
||||
for (i = 0; i < layer_size; ++i)
|
||||
{
|
||||
pixels[(i * base_channels) + cidx] = chn_a[cidx].data[i];
|
||||
memcpy (&pixels[((i * base_channels) + cidx) * bps],
|
||||
&chn_a[cidx].data[i * bps], bps);
|
||||
}
|
||||
g_free (chn_a[cidx].data);
|
||||
}
|
||||
@@ -1643,13 +1671,10 @@ add_merged_image (const gint32 image_id,
|
||||
image_type,
|
||||
100, GIMP_NORMAL_MODE);
|
||||
gimp_image_insert_layer (image_id, layer_id, -1, 0);
|
||||
drawable = gimp_drawable_get (layer_id);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
|
||||
drawable->width, drawable->height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, pixels,
|
||||
0, 0, drawable->width, drawable->height);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
buffer = gimp_drawable_get_buffer (layer_id);
|
||||
gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)),
|
||||
0, get_pixel_format (img_a), pixels, GEGL_AUTO_ROWSTRIDE);
|
||||
g_object_unref (buffer);
|
||||
g_free (pixels);
|
||||
}
|
||||
else
|
||||
@@ -1734,18 +1759,14 @@ add_merged_image (const gint32 image_id,
|
||||
alpha_opacity, &alpha_rgb);
|
||||
gimp_image_insert_channel (image_id, channel_id, -1, 0);
|
||||
g_free (alpha_name);
|
||||
drawable = gimp_drawable_get (channel_id);
|
||||
buffer = gimp_drawable_get_buffer (channel_id);
|
||||
if (alpha_id)
|
||||
gimp_item_set_tattoo (drawable->drawable_id, alpha_id);
|
||||
gimp_item_set_visible (drawable->drawable_id, alpha_visible);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
|
||||
drawable->width, drawable->height,
|
||||
TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, pixels,
|
||||
0, 0, drawable->width,
|
||||
drawable->height);
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
gimp_item_set_tattoo (channel_id, alpha_id);
|
||||
gimp_item_set_visible (channel_id, alpha_visible);
|
||||
gegl_buffer_set (buffer,
|
||||
GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)),
|
||||
0, get_pixel_format (img_a), pixels, GEGL_AUTO_ROWSTRIDE);
|
||||
g_object_unref (buffer);
|
||||
g_free (chn_a[cidx].data);
|
||||
}
|
||||
|
||||
@@ -1928,20 +1949,21 @@ read_channel_data (PSDchannel *channel,
|
||||
/* Convert channel data to GIMP format */
|
||||
switch (bps)
|
||||
{
|
||||
case 32:
|
||||
case 16:
|
||||
channel->data = (gchar *) g_malloc (channel->rows * channel->columns);
|
||||
convert_16_bit (raw_data, channel->data, (channel->rows * channel->columns) << 1);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
channel->data = (gchar *) g_malloc (channel->rows * channel->columns);
|
||||
memcpy (channel->data, raw_data, (channel->rows * channel->columns));
|
||||
channel->data = (gchar *) g_malloc (channel->rows * channel->columns * bps / 8 );
|
||||
memcpy (channel->data, raw_data, (channel->rows * channel->columns * bps / 8));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
channel->data = (gchar *) g_malloc (channel->rows * channel->columns);
|
||||
convert_1_bit (raw_data, channel->data, channel->rows, channel->columns);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (raw_data);
|
||||
@@ -1949,27 +1971,6 @@ read_channel_data (PSDchannel *channel,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
convert_16_bit (const gchar *src,
|
||||
gchar *dst,
|
||||
guint32 len)
|
||||
{
|
||||
/* Convert 16 bit to 8 bit dropping low byte
|
||||
*/
|
||||
gint i;
|
||||
|
||||
IFDBG(3) g_debug ("Start 16 bit conversion");
|
||||
|
||||
for (i = 0; i < len >> 1; ++i)
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
IFDBG(3) g_debug ("End 16 bit conversion");
|
||||
}
|
||||
|
||||
static void
|
||||
convert_1_bit (const gchar *src,
|
||||
gchar *dst,
|
||||
@@ -2002,3 +2003,108 @@ convert_1_bit (const gchar *src,
|
||||
}
|
||||
IFDBG(3) g_debug ("End 1 bit conversion");
|
||||
}
|
||||
|
||||
static const Babl*
|
||||
get_pixel_format (PSDimage *img_a)
|
||||
{
|
||||
const Babl *format;
|
||||
|
||||
switch (get_gimp_image_type (img_a->base_type, img_a->transparency))
|
||||
{
|
||||
case GIMP_GRAY_IMAGE:
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
format = babl_format ("Y u32");
|
||||
break;
|
||||
|
||||
case 16:
|
||||
format = babl_format ("Y u16");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 1:
|
||||
format = babl_format ("Y u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_GRAYA_IMAGE:
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
format = babl_format ("YA u32");
|
||||
break;
|
||||
|
||||
case 16:
|
||||
format = babl_format ("YA u16");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 1:
|
||||
format = babl_format ("YA u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_RGB_IMAGE:
|
||||
case GIMP_INDEXED_IMAGE:
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
format = babl_format ("RGB u32");
|
||||
break;
|
||||
|
||||
case 16:
|
||||
format = babl_format ("RGB u16");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 1:
|
||||
format = babl_format ("RGB u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_RGBA_IMAGE:
|
||||
case GIMP_INDEXEDA_IMAGE:
|
||||
switch (img_a->bps)
|
||||
{
|
||||
case 32:
|
||||
format = babl_format ("RGBA u32");
|
||||
break;
|
||||
|
||||
case 16:
|
||||
format = babl_format ("RGBA u16");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case 1:
|
||||
format = babl_format ("RGBA u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
@@ -86,12 +86,11 @@
|
||||
#define DEBUG FALSE
|
||||
|
||||
/* 1: Normal debuggin, 2: Deep debuggin */
|
||||
#define DEBUG_LEVEL 1
|
||||
#define DEBUG_LEVEL 2
|
||||
|
||||
#define IFDBG if (DEBUG)
|
||||
#define IF_DEEP_DBG if (DEBUG && DEBUG_LEVEL == 2)
|
||||
|
||||
|
||||
#define PSD_UNIT_INCH 1
|
||||
#define PSD_UNIT_CM 2
|
||||
|
||||
@@ -101,7 +100,6 @@
|
||||
/* Local types etc
|
||||
*/
|
||||
|
||||
|
||||
typedef struct PsdLayerDimension
|
||||
{
|
||||
gint left;
|
||||
@@ -110,7 +108,6 @@ typedef struct PsdLayerDimension
|
||||
gint32 height;
|
||||
} PSD_Layer_Dimension;
|
||||
|
||||
|
||||
typedef struct PsdImageData
|
||||
{
|
||||
gboolean compression;
|
||||
@@ -134,64 +131,80 @@ typedef struct PsdImageData
|
||||
|
||||
static PSD_Image_Data PSDImageData;
|
||||
|
||||
|
||||
/* Declare some local functions.
|
||||
*/
|
||||
|
||||
static void query (void);
|
||||
static void run (const gchar *name,
|
||||
gint nparams,
|
||||
const GimpParam *param,
|
||||
gint *nreturn_vals,
|
||||
GimpParam **return_vals);
|
||||
static void query (void);
|
||||
|
||||
static void psd_lmode_layer (gint32 idLayer,
|
||||
gchar *psdMode);
|
||||
static void reshuffle_cmap_write (guchar *mapGimp);
|
||||
static void save_header (FILE *fd,
|
||||
gint32 image_id);
|
||||
static void save_color_mode_data (FILE *fd,
|
||||
gint32 image_id);
|
||||
static void save_resources (FILE *fd,
|
||||
gint32 image_id);
|
||||
static void save_layer_and_mask (FILE *fd,
|
||||
gint32 image_id);
|
||||
static void save_data (FILE *fd,
|
||||
gint32 image_id);
|
||||
static gint save_image (const gchar *filename,
|
||||
gint32 image_id,
|
||||
GError **error);
|
||||
static void xfwrite (FILE *fd,
|
||||
gconstpointer buf,
|
||||
glong len,
|
||||
const gchar *why);
|
||||
static void write_pascalstring (FILE *fd,
|
||||
const gchar *val,
|
||||
gint padding,
|
||||
const gchar *why);
|
||||
static void write_string (FILE *fd,
|
||||
const gchar *val,
|
||||
const gchar *why);
|
||||
static void write_gchar (FILE *fd,
|
||||
guchar val,
|
||||
const gchar *why);
|
||||
static void write_gint16 (FILE *fd,
|
||||
gint16 val,
|
||||
const gchar *why);
|
||||
static void write_gint32 (FILE *fd,
|
||||
gint32 val,
|
||||
const gchar *why);
|
||||
static void write_datablock_luni (FILE *fd,
|
||||
const gchar *val,
|
||||
const gchar *why);
|
||||
static void run (const gchar *name,
|
||||
gint nparams,
|
||||
const GimpParam *param,
|
||||
gint *nreturn_vals,
|
||||
GimpParam **return_vals);
|
||||
|
||||
static void write_pixel_data (FILE *fd,
|
||||
gint32 drawableID,
|
||||
glong *ChanLenPosition,
|
||||
gint32 rowlenOffset);
|
||||
static void psd_lmode_layer (gint32 idLayer,
|
||||
gchar *psdMode);
|
||||
|
||||
static gint32 create_merged_image (gint32 imageID);
|
||||
static void reshuffle_cmap_write (guchar *mapGimp);
|
||||
|
||||
static void save_header (FILE *fd,
|
||||
gint32 image_id);
|
||||
|
||||
static void save_color_mode_data (FILE *fd,
|
||||
gint32 image_id);
|
||||
|
||||
static void save_resources (FILE *fd,
|
||||
gint32 image_id);
|
||||
|
||||
static void save_layer_and_mask (FILE *fd,
|
||||
gint32 image_id);
|
||||
|
||||
static void save_data (FILE *fd,
|
||||
gint32 image_id);
|
||||
|
||||
static gint save_image (const gchar *filename,
|
||||
gint32 image_id,
|
||||
GError **error);
|
||||
|
||||
static void xfwrite (FILE *fd,
|
||||
gconstpointer buf,
|
||||
glong len,
|
||||
const gchar *why);
|
||||
|
||||
static void write_pascalstring (FILE *fd,
|
||||
const gchar *val,
|
||||
gint padding,
|
||||
const gchar *why);
|
||||
|
||||
static void write_string (FILE *fd,
|
||||
const gchar *val,
|
||||
const gchar *why);
|
||||
|
||||
static void write_gchar (FILE *fd,
|
||||
guchar val,
|
||||
const gchar *why);
|
||||
|
||||
static void write_gint16 (FILE *fd,
|
||||
gint16 val,
|
||||
const gchar *why);
|
||||
|
||||
static void write_gint32 (FILE *fd,
|
||||
gint32 val,
|
||||
const gchar *why);
|
||||
|
||||
static void write_datablock_luni (FILE *fd,
|
||||
const gchar *val,
|
||||
const gchar *why);
|
||||
|
||||
|
||||
static void write_pixel_data (FILE *fd,
|
||||
gint32 drawableID,
|
||||
glong *ChanLenPosition,
|
||||
gint32 rowlenOffset);
|
||||
|
||||
static gint32 create_merged_image (gint32 imageID);
|
||||
|
||||
static const Babl* get_pixel_format (gint32 drawableID);
|
||||
|
||||
const GimpPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
@@ -235,7 +248,6 @@ query (void)
|
||||
gimp_register_save_handler (SAVE_PROC, "psd", "");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run (const gchar *name,
|
||||
gint nparams,
|
||||
@@ -411,7 +423,6 @@ psd_lmode_layer (gint32 idLayer,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_string (FILE *fd,
|
||||
const gchar *val,
|
||||
@@ -421,7 +432,6 @@ write_string (FILE *fd,
|
||||
xfwrite (fd, val, strlen (val), why);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_pascalstring (FILE *fd,
|
||||
const gchar *val,
|
||||
@@ -459,7 +469,6 @@ write_pascalstring (FILE *fd,
|
||||
write_gchar (fd, 0, why);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xfwrite (FILE *fd,
|
||||
gconstpointer buf,
|
||||
@@ -476,7 +485,6 @@ xfwrite (FILE *fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_gchar (FILE *fd,
|
||||
guchar val,
|
||||
@@ -497,7 +505,6 @@ write_gchar (FILE *fd,
|
||||
fseek (fd, pos + 1, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_gint16 (FILE *fd,
|
||||
gint16 val,
|
||||
@@ -517,9 +524,6 @@ write_gint16 (FILE *fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
write_gint32 (FILE *fd,
|
||||
gint32 val,
|
||||
@@ -539,7 +543,6 @@ write_gint32 (FILE *fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_datablock_luni (FILE *fd,
|
||||
const gchar *val,
|
||||
@@ -581,7 +584,6 @@ write_datablock_luni (FILE *fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gint32
|
||||
pack_pb_line (guchar *start,
|
||||
gint32 length,
|
||||
@@ -666,7 +668,6 @@ gimpBaseTypeToPsdMode (GimpImageBaseType gimpBaseType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
nChansLayer (gint gimpBaseType,
|
||||
gint hasAlpha,
|
||||
@@ -691,7 +692,6 @@ nChansLayer (gint gimpBaseType,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
reshuffle_cmap_write (guchar *mapGimp)
|
||||
{
|
||||
@@ -715,7 +715,6 @@ reshuffle_cmap_write (guchar *mapGimp)
|
||||
g_free (mapPSD);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_header (FILE *fd,
|
||||
gint32 image_id)
|
||||
@@ -736,13 +735,10 @@ save_header (FILE *fd,
|
||||
"channels");
|
||||
write_gint32 (fd, PSDImageData.image_height, "rows");
|
||||
write_gint32 (fd, PSDImageData.image_width, "columns");
|
||||
write_gint16 (fd, 8, "depth"); /* Apparently GIMP only supports 8 bit deep
|
||||
PSD images. */
|
||||
write_gint16 (fd, 8, "depth"); /* Saving can only be done in 8 bits at the moment. */
|
||||
write_gint16 (fd, gimpBaseTypeToPsdMode (PSDImageData.baseType), "mode");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
save_color_mode_data (FILE *fd,
|
||||
gint32 image_id)
|
||||
@@ -800,8 +796,6 @@ save_color_mode_data (FILE *fd,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
save_resources (FILE *fd,
|
||||
gint32 image_id)
|
||||
@@ -1031,8 +1025,6 @@ save_resources (FILE *fd,
|
||||
fseek (fd, eof_pos, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
get_compress_channel_data (guchar *channel_data,
|
||||
gint32 channel_cols,
|
||||
@@ -1062,7 +1054,6 @@ get_compress_channel_data (guchar *channel_data,
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_layer_and_mask (FILE *fd,
|
||||
gint32 image_id)
|
||||
@@ -1284,32 +1275,26 @@ save_layer_and_mask (FILE *fd,
|
||||
fseek (fd, eof_pos, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
write_pixel_data (FILE *fd,
|
||||
gint32 drawableID,
|
||||
glong *ChanLenPosition,
|
||||
gint32 ltable_offset)
|
||||
{
|
||||
GimpPixelRgn region; /* Image region */
|
||||
guchar *data; /* Temporary copy of pixel data */
|
||||
|
||||
gint32 tile_height = gimp_tile_height();
|
||||
|
||||
GimpDrawable *drawable = gimp_drawable_get (drawableID);
|
||||
|
||||
gint32 height = drawable->height;
|
||||
gint32 width = drawable->width;
|
||||
gint32 bytes = drawable->bpp;
|
||||
gint32 colors = bytes; /* fixed up down below */
|
||||
gint32 y;
|
||||
|
||||
gint32 len; /* Length of compressed data */
|
||||
gint16 *LengthsTable; /* Lengths of every compressed row */
|
||||
guchar *rledata; /* Compressed data from a region */
|
||||
glong length_table_pos; /* position in file of the length table */
|
||||
int i, j;
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (drawableID);
|
||||
const Babl *format = get_pixel_format (drawableID);
|
||||
gint32 tile_height = gimp_tile_height();
|
||||
gint32 height = gegl_buffer_get_height (buffer);
|
||||
gint32 width = gegl_buffer_get_width (buffer);
|
||||
gint32 bytes = babl_format_get_bytes_per_pixel (format);
|
||||
gint32 colors = bytes; /* fixed up down below */
|
||||
gint32 y;
|
||||
gint32 len; /* Length of compressed data */
|
||||
gint16 *LengthsTable; /* Lengths of every compressed row */
|
||||
guchar *rledata; /* Compressed data from a region */
|
||||
guchar *data; /* Temporary copy of pixel data */
|
||||
glong length_table_pos; /* position in file of the length table */
|
||||
int i, j;
|
||||
|
||||
IFDBG printf (" Function: write_pixel_data, drw %d, lto %d\n",
|
||||
drawableID, ltable_offset);
|
||||
@@ -1318,17 +1303,12 @@ write_pixel_data (FILE *fd,
|
||||
!gimp_drawable_is_indexed (drawableID))
|
||||
colors -= 1;
|
||||
|
||||
gimp_tile_cache_ntiles (2* (drawable->width / gimp_tile_width () + 1));
|
||||
|
||||
LengthsTable = g_new (gint16, height);
|
||||
rledata = g_new (guchar, (MIN (height, tile_height) *
|
||||
(width + 10 + (width / 100))));
|
||||
|
||||
data = g_new (guchar, MIN(height, tile_height) * width * bytes);
|
||||
|
||||
gimp_pixel_rgn_init (®ion, drawable, 0, 0,
|
||||
width, height, FALSE, FALSE);
|
||||
|
||||
for (i = 0; i < bytes; i++)
|
||||
{
|
||||
gint chan;
|
||||
@@ -1374,8 +1354,8 @@ write_pixel_data (FILE *fd,
|
||||
for (y = 0; y < height; y += tile_height)
|
||||
{
|
||||
int tlen;
|
||||
gimp_pixel_rgn_get_rect (®ion, data, 0, y,
|
||||
width, MIN(height - y, tile_height));
|
||||
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, y, width, MIN (height - y, tile_height)),
|
||||
0, format, data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
tlen = get_compress_channel_data (&data[chan],
|
||||
width,
|
||||
MIN(height - y, tile_height),
|
||||
@@ -1409,12 +1389,9 @@ write_pixel_data (FILE *fd,
|
||||
|
||||
if (maskID != -1)
|
||||
{
|
||||
GimpDrawable *mdrawable = gimp_drawable_get (maskID);
|
||||
GeglBuffer *mbuffer = gimp_drawable_get_buffer (maskID);
|
||||
len = 0;
|
||||
|
||||
gimp_pixel_rgn_init (®ion, mdrawable, 0, 0,
|
||||
width, height, FALSE, FALSE);
|
||||
|
||||
if (ChanLenPosition)
|
||||
{
|
||||
write_gint16 (fd, 1, "Compression type (RLE)");
|
||||
@@ -1442,8 +1419,8 @@ write_pixel_data (FILE *fd,
|
||||
for (y = 0; y < height; y += tile_height)
|
||||
{
|
||||
int tlen;
|
||||
gimp_pixel_rgn_get_rect (®ion, data, 0, y,
|
||||
width, MIN(height - y, tile_height));
|
||||
gegl_buffer_get (mbuffer, GEGL_RECTANGLE (0, y, width, MIN (height - y, tile_height)),
|
||||
0, format, data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
tlen = get_compress_channel_data (&data[0],
|
||||
width,
|
||||
MIN(height - y, tile_height),
|
||||
@@ -1473,19 +1450,17 @@ write_pixel_data (FILE *fd,
|
||||
fseek (fd, 0, SEEK_END);
|
||||
IF_DEEP_DBG printf ("\t\t\t\t. Cur pos %ld\n", ftell(fd));
|
||||
|
||||
gimp_drawable_detach (mdrawable);
|
||||
g_object_unref (mbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_drawable_detach (drawable);
|
||||
g_object_unref (buffer);
|
||||
|
||||
g_free (data);
|
||||
g_free (rledata);
|
||||
g_free (LengthsTable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
save_data (FILE *fd,
|
||||
gint32 image_id)
|
||||
@@ -1541,50 +1516,50 @@ create_merged_image (gint32 image_id)
|
||||
|
||||
if (gimp_image_base_type (image_id) != GIMP_INDEXED)
|
||||
{
|
||||
GimpDrawable *drawable = gimp_drawable_get (projection);
|
||||
GimpPixelRgn region;
|
||||
gboolean transparency_found = FALSE;
|
||||
gpointer pr;
|
||||
GeglBuffer *buffer = gimp_drawable_get_buffer (projection);
|
||||
const Babl *format = get_pixel_format (projection);
|
||||
gboolean transparency_found = FALSE;
|
||||
gint bpp = babl_format_get_bytes_per_pixel (format);
|
||||
gint n_components = babl_format_get_n_components (format);
|
||||
gint width = gegl_buffer_get_width (buffer);
|
||||
gint height = gegl_buffer_get_height (buffer);
|
||||
GeglBufferIterator *iter = gegl_buffer_iterator_new (buffer, GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
|
||||
|
||||
gimp_pixel_rgn_init (®ion, drawable,
|
||||
0, 0, drawable->width, drawable->height,
|
||||
TRUE, FALSE);
|
||||
while (gegl_buffer_iterator_next (iter))
|
||||
{
|
||||
guchar *data = iter->data[0];
|
||||
gint y;
|
||||
|
||||
for (pr = gimp_pixel_rgns_register (1, ®ion);
|
||||
pr != NULL;
|
||||
pr = gimp_pixel_rgns_process (pr))
|
||||
{
|
||||
guchar *data = region.data;
|
||||
gint y;
|
||||
for (y = 0; y < iter->roi->height; y++)
|
||||
{
|
||||
guchar *d = data;
|
||||
gint x;
|
||||
|
||||
for (y = 0; y < region.h; y++)
|
||||
{
|
||||
guchar *d = data;
|
||||
gint x;
|
||||
for (x = 0; x < iter->roi->width; x++)
|
||||
{
|
||||
gint32 alpha = d[bpp - 1];
|
||||
|
||||
for (x = 0; x < region.w; x++)
|
||||
{
|
||||
guint32 alpha = d[region.bpp - 1];
|
||||
if (alpha < 255)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (alpha < 255)
|
||||
{
|
||||
gint i;
|
||||
transparency_found = TRUE;
|
||||
|
||||
transparency_found = TRUE;
|
||||
/* blend against white, photoshop does this. */
|
||||
for (i = 0; i < bpp - 1; i++)
|
||||
d[i] = ((guint32) d[i] * alpha) / 255 + 255 - alpha;
|
||||
}
|
||||
|
||||
/* blend against white, photoshop does this. */
|
||||
for (i = 0; i < region.bpp - 1; i++)
|
||||
d[i] = ((guint32) d[i] * alpha) / 255 + 255 - alpha;
|
||||
}
|
||||
}
|
||||
|
||||
d += region.bpp;
|
||||
}
|
||||
d += bpp;
|
||||
}
|
||||
|
||||
data += region.rowstride;
|
||||
}
|
||||
}
|
||||
data += n_components;
|
||||
}
|
||||
|
||||
gimp_drawable_detach (drawable);
|
||||
g_object_unref (buffer);
|
||||
|
||||
if (! transparency_found)
|
||||
gimp_layer_flatten (projection);
|
||||
@@ -1628,18 +1603,16 @@ get_image_data (FILE *fd,
|
||||
PSDImageData.layersDim = g_new (PSD_Layer_Dimension, PSDImageData.nLayers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gint
|
||||
save_image (const gchar *filename,
|
||||
gint32 image_id,
|
||||
GError **error)
|
||||
{
|
||||
FILE *fd;
|
||||
gint32 *layers;
|
||||
gint nlayers;
|
||||
gint i;
|
||||
GimpDrawable *drawable;
|
||||
FILE *fd;
|
||||
gint32 *layers;
|
||||
gint nlayers;
|
||||
gint i;
|
||||
GeglBuffer *buffer;
|
||||
|
||||
IFDBG printf (" Function: save_image\n");
|
||||
|
||||
@@ -1658,8 +1631,8 @@ save_image (const gchar *filename,
|
||||
layers = gimp_image_get_layers (image_id, &nlayers);
|
||||
for (i = 0; i < nlayers; i++)
|
||||
{
|
||||
drawable = gimp_drawable_get (layers[i]);
|
||||
if (drawable->width > 30000 || drawable->height > 30000)
|
||||
buffer = gimp_drawable_get_buffer (layers[i]);
|
||||
if (gegl_buffer_get_width (buffer) > 30000 || gegl_buffer_get_height (buffer) > 30000)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Unable to save '%s'. The PSD file format does not "
|
||||
@@ -1669,6 +1642,7 @@ save_image (const gchar *filename,
|
||||
g_free (layers);
|
||||
return FALSE;
|
||||
}
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
g_free (layers);
|
||||
|
||||
@@ -1713,3 +1687,36 @@ save_image (const gchar *filename,
|
||||
fclose (fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const Babl*
|
||||
get_pixel_format (gint32 drawableID)
|
||||
{
|
||||
const Babl *format;
|
||||
|
||||
switch (gimp_drawable_type (drawableID))
|
||||
{
|
||||
case GIMP_GRAY_IMAGE:
|
||||
format = babl_format ("Y u8");
|
||||
break;
|
||||
|
||||
case GIMP_GRAYA_IMAGE:
|
||||
format = babl_format ("YA u8");
|
||||
break;
|
||||
|
||||
case GIMP_RGB_IMAGE:
|
||||
case GIMP_INDEXED_IMAGE:
|
||||
format = babl_format ("RGB u8");
|
||||
break;
|
||||
|
||||
case GIMP_RGBA_IMAGE:
|
||||
case GIMP_INDEXEDA_IMAGE:
|
||||
format = babl_format ("RGBA u8");
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
@@ -182,6 +182,7 @@ run (const gchar *name,
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
INIT_I18N ();
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
*nreturn_vals = 1;
|
||||
*return_vals = values;
|
||||
|
@@ -31,7 +31,7 @@
|
||||
/* Set to the level of debugging output you want, 0 for none.
|
||||
* Setting higher than 2 will result in a very large amount of debug
|
||||
* output being produced. */
|
||||
#define PSD_DEBUG 0
|
||||
#define PSD_DEBUG 3
|
||||
#define IFDBG(level) if (PSD_DEBUG >= level)
|
||||
|
||||
/* Set to FALSE to suppress pop-up warnings about lossy file conversions */
|
||||
@@ -83,6 +83,8 @@
|
||||
#define PSD_LADJ_INVERT "nvrt" /* Adjustment layer - invert (PS4) */
|
||||
#define PSD_LADJ_THRESHOLD "thrs" /* Adjustment layer - threshold (PS4) */
|
||||
#define PSD_LADJ_POSTERIZE "post" /* Adjustment layer - posterize (PS4) */
|
||||
#define PSD_LADJ_VIBRANCE "vibA" /* Adjustment layer - vibrance (PS10) */
|
||||
#define PSD_LADJ_COLOR_LOOKUP "clrL" /* Adjustment layer - color lookup (PS13) */
|
||||
|
||||
/* Fill Layer IDs */
|
||||
#define PSD_LFIL_SOLID "SoCo" /* Solid color sheet setting (PS6) */
|
||||
@@ -117,12 +119,22 @@
|
||||
/* Other */
|
||||
#define PSD_LOTH_SECTION "lsct" /* Section divider setting - Layer groups (PS6) */
|
||||
#define PSD_LOTH_PATTERN "Patt" /* Patterns (PS6) */
|
||||
#define PSD_LOTH_PATTERN_2 "Pat2" /* Patterns 2nd key (PS6) */
|
||||
#define PSD_LOTH_PATTERN_3 "Pat3" /* Patterns 3rd key (PS6) */
|
||||
#define PSD_LOTH_GRADIENT "grdm" /* Gradient settings (PS6) */
|
||||
#define PSD_LOTH_RESTRICT "brst" /* Channel blending restriction setting (PS6) */
|
||||
#define PSD_LOTH_FOREIGN_FX "ffxi" /* Foreign effect ID (PS6) */
|
||||
#define PSD_LOTH_PATT_DATA "shpa" /* Pattern data (PS6) */
|
||||
#define PSD_LOTH_META_DATA "shmd" /* Meta data setting (PS6) */
|
||||
#define PSD_LOTH_LAYER_DATA "layr" /* Layer data (PS6) */
|
||||
#define PSD_LOTH_CONTENT_GEN "CgEd" /* Content generator extra data (PS12) */
|
||||
#define PSD_LOTH_TEXT_ENGINE "Txt2" /* Text engine data (PS10) */
|
||||
#define PSD_LOTH_PATH_NAME "pths" /* Unicode path name (PS13) */
|
||||
#define PSD_LOTH_ANIMATION_FX "anFX" /* Animation effects (PS13) */
|
||||
#define PSD_LOTH_FILTER_MASK "FMsk" /* Filter mask (PS10) */
|
||||
#define PSD_LOTH_VECTOR_STROKE "vscg" /* Vector stroke data (PS13) */
|
||||
#define PSD_LOTH_ALIGN_RENDER "sn2P" /* Aligned rendering flag (?) */
|
||||
#define PSD_LOTH_USER_MASK "LMsk" /* User mask (?) */
|
||||
|
||||
/* Effects layer resource IDs */
|
||||
#define PSD_LFX_COMMON "cmnS" /* Effects layer - common state (PS5) */
|
||||
@@ -132,6 +144,24 @@
|
||||
#define PSD_LFX_INNER_GLW "iglw" /* Effects layer - inner glow (PS5) */
|
||||
#define PSD_LFX_BEVEL "bevl" /* Effects layer - bevel (PS5) */
|
||||
|
||||
/* Placed Layer */
|
||||
#define PSD_LPL_PLACE_LAYER "plLd" /* Placed layer (?) */
|
||||
#define PSD_LPL_PLACE_LAYER_NEW "SoLd" /* Placed layer (PS10) */
|
||||
|
||||
/* Linked Layer */
|
||||
#define PSD_LLL_LINKED_LAYER "lnkD" /* Linked layer (?) */
|
||||
#define PSD_LLL_LINKED_LAYER_2 "lnk2" /* Linked layer 2nd key */
|
||||
#define PSD_LLL_LINKED_LAYER_3 "lnk3" /* Linked layer 3rd key */
|
||||
|
||||
/* Merged Transparency */
|
||||
#define PSD_LMT_MERGE_TRANS "Mtrn" /* Merged transperency save flag (?) */
|
||||
#define PSD_LMT_MERGE_TRANS_16 "Mt16" /* Merged transperency save flag 2 */
|
||||
#define PSD_LMT_MERGE_TRANS_32 "Mt32" /* Merged transperency save flag 3 */
|
||||
|
||||
/* Filter Effects */
|
||||
#define PSD_LFFX_FILTER_FX "FXid" /* Filter effects (?) */
|
||||
#define PSD_LFFX_FILTER_FX_2 "FEid" /* Filter effects 2 */
|
||||
|
||||
/* PSD spec enums */
|
||||
|
||||
/* Image color modes */
|
||||
@@ -169,7 +199,7 @@ typedef enum {
|
||||
PSD_PS2_COLOR_TAB = 1003, /* 0x03eb - Obsolete - ps 2.0 indexed color table */
|
||||
PSD_RESN_INFO = 1005, /* 0x03ed - ResolutionInfo structure */
|
||||
PSD_ALPHA_NAMES = 1006, /* 0x03ee - Alpha channel names */
|
||||
PSD_DISPLAY_INFO = 1007, /* 0x03ef - DisplayInfo structure */
|
||||
PSD_DISPLAY_INFO = 1007, /* 0x03ef - Superceded by PSD_DISPLAY_INFO_NEW for ps CS3 and higher - DisplayInfo structure */
|
||||
PSD_CAPTION = 1008, /* 0x03f0 - Optional - Caption string */
|
||||
PSD_BORDER_INFO = 1009, /* 0x03f1 - Border info */
|
||||
PSD_BACKGROUND_COL = 1010, /* 0x03f2 - Background color */
|
||||
@@ -198,8 +228,8 @@ typedef enum {
|
||||
PSD_COPYRIGHT_FLG = 1034, /* 0x040a - Copyright flag */
|
||||
PSD_URL = 1035, /* 0x040b - URL string */
|
||||
PSD_THUMB_RES2 = 1036, /* 0x040c - Thumbnail resource */
|
||||
PSD_GLOBAL_ANGLE = 1037, /* 0x040d - Global angle */
|
||||
PSD_COLOR_SAMPLER = 1038, /* 0x040e - Color samplers resource */
|
||||
PSD_GLOBAL_ANGLE = 1037, /* 0x040d - Superceded by PSD_NEW_COLOR_SAMPLER for ps CS3 and higher - Global angle */
|
||||
PSD_COLOR_SAMPLER = 1038, /* 0x040e - Superceded by PSD_NEW_COLOR_SAMPLER for ps CS3 and higher - Color samplers resource */
|
||||
PSD_ICC_PROFILE = 1039, /* 0x040f - ICC Profile */
|
||||
PSD_WATERMARK = 1040, /* 0x0410 - Watermark */
|
||||
PSD_ICC_UNTAGGED = 1041, /* 0x0411 - Do not use ICC profile flag */
|
||||
@@ -216,11 +246,40 @@ typedef enum {
|
||||
PSD_ALPHA_ID = 1053, /* 0x041d - Alpha IDs */
|
||||
PSD_URL_LIST_UNI = 1054, /* 0x041e - URL list - unicode */
|
||||
PSD_VERSION_INFO = 1057, /* 0x0421 - Version info */
|
||||
PSD_EXIF_DATA = 1058, /* 0x0422 - Exif data block */
|
||||
PSD_EXIF_DATA = 1058, /* 0x0422 - Exif data block 1 */
|
||||
PSD_EXIF_DATA_3 = 1059, /* 0X0423 - Exif data block 3 (?) */
|
||||
PSD_XMP_DATA = 1060, /* 0x0424 - XMP data block */
|
||||
PSD_CAPTION_DIGEST = 1061, /* 0x0425 - Caption digest */
|
||||
PSD_PRINT_SCALE = 1062, /* 0x0426 - Print scale */
|
||||
PSD_PIXEL_AR = 1064, /* 0x0428 - Pixel aspect ratio */
|
||||
PSD_LAYER_COMPS = 1065, /* 0x0429 - Layer comps */
|
||||
PSD_ALT_DUOTONE_COLOR = 1066, /* 0x042A - Alternative Duotone colors */
|
||||
PSD_ALT_SPOT_COLOR = 1067, /* 0x042B - Alternative Spot colors */
|
||||
PSD_LAYER_SELECT_ID = 1069, /* 0x042D - Layer selection ID */
|
||||
PSD_HDR_TONING_INFO = 1070, /* 0x042E - HDR toning information */
|
||||
PSD_PRINT_INFO_SCALE = 1071, /* 0x042F - Print scale */
|
||||
PSD_LAYER_GROUP_E_ID = 1072, /* 0x0430 - Layer group(s) enabled ID */
|
||||
PSD_COLOR_SAMPLER_NEW = 1073, /* 0x0431 - Color sampler resource for ps CS3 and higher PSD files */
|
||||
PSD_MEASURE_SCALE = 1074, /* 0x0432 - Measurement scale */
|
||||
PSD_TIMELINE_INFO = 1075, /* 0x0433 - Timeline information */
|
||||
PSD_SHEET_DISCLOSE = 1076, /* 0x0434 - Sheet discloser */
|
||||
PSD_DISPLAY_INFO_NEW = 1077, /* 0x0435 - DisplayInfo structure for ps CS3 and higher PSD files */
|
||||
PSD_ONION_SKINS = 1078, /* 0x0436 - Onion skins */
|
||||
PSD_COUNT_INFO = 1080, /* 0x0438 - Count information*/
|
||||
PSD_PRINT_INFO = 1082, /* 0x043A - Print information added in ps CS5*/
|
||||
PSD_PRINT_STYLE = 1083, /* 0x043B - Print style */
|
||||
PSD_MAC_NSPRINTINFO = 1084, /* 0x043C - Mac NSPrintInfo*/
|
||||
PSD_WIN_DEVMODE = 1085, /* 0x043D - Windows DEVMODE */
|
||||
PSD_AUTO_SAVE_PATH = 1086, /* 0x043E - Auto save file path */
|
||||
PSD_AUTO_SAVE_FORMAT = 1087, /* 0x043F - Auto save format */
|
||||
PSD_PATH_INFO_FIRST = 2000, /* 0x07d0 - First path info block */
|
||||
PSD_PATH_INFO_LAST = 2998, /* 0x0bb6 - Last path info block */
|
||||
PSD_CLIPPING_PATH = 2999, /* 0x0bb7 - Name of clipping path */
|
||||
PSD_PLUGIN_R_FIRST = 4000, /* 0x0FA0 - First plugin resource */
|
||||
PSD_PLUGIN_R_LAST = 4999, /* 0x1387 - Last plugin resource */
|
||||
PSD_IMAGEREADY_VARS = 7000, /* 0x1B58 - Imageready variables */
|
||||
PSD_IMAGEREADY_DATA = 7001, /* 0x1B59 - Imageready data sets */
|
||||
PSD_LIGHTROOM_WORK = 8000, /* 0x1F40 - Lightroom workflow */
|
||||
PSD_PRINT_FLAGS_2 = 10000 /* 0x2710 - Print flags */
|
||||
} PSDImageResID;
|
||||
|
||||
@@ -306,7 +365,7 @@ typedef struct
|
||||
guint16 red;
|
||||
guint16 green;
|
||||
guint16 blue;
|
||||
}CMRGBColor;
|
||||
} CMRGBColor;
|
||||
|
||||
/* HSV Color Value
|
||||
A color value expressed in the HSV color space is composed of hue,
|
||||
@@ -321,7 +380,7 @@ typedef struct
|
||||
guint16 hue;
|
||||
guint16 saturation;
|
||||
guint16 value;
|
||||
}CMHSVColor;
|
||||
} CMHSVColor;
|
||||
|
||||
/* CMYK Color Value
|
||||
A color value expressed in the CMYK color space is composed of cyan, magenta,
|
||||
@@ -336,7 +395,7 @@ typedef struct
|
||||
guint16 magenta;
|
||||
guint16 yellow;
|
||||
guint16 black;
|
||||
}CMCMYKColor;
|
||||
} CMCMYKColor;
|
||||
|
||||
/* L*a*b* Color Value
|
||||
The first three values in the color data are, respectively, the colors
|
||||
@@ -363,17 +422,16 @@ typedef struct
|
||||
} CMGrayColor ;
|
||||
|
||||
/* The color union is defined by the CMColor type definition.
|
||||
*/
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
CMRGBColor rgb;
|
||||
CMHSVColor hsv;
|
||||
CMLabColor Lab;
|
||||
CMCMYKColor cmyk;
|
||||
CMGrayColor gray;
|
||||
CMRGBColor rgb;
|
||||
CMHSVColor hsv;
|
||||
CMLabColor Lab;
|
||||
CMCMYKColor cmyk;
|
||||
CMGrayColor gray;
|
||||
} CMColor;
|
||||
|
||||
|
||||
/* Image resolution data */
|
||||
typedef struct {
|
||||
Fixed hRes; /* Horizontal resolution pixels/inch */
|
||||
@@ -410,15 +468,24 @@ typedef struct {
|
||||
gint16 planes; /* Number of planes (always 1) */
|
||||
} ThumbnailInfo;
|
||||
|
||||
/* Channel display info data */
|
||||
/* Channel display info data for Adobe Photoshop CS2 and lower */
|
||||
typedef struct {
|
||||
gint16 colorSpace; /* Color space from PSDColorSpace */
|
||||
gint16 colorSpace; /* Color space from PSDColorSpace */
|
||||
guint16 color[4]; /* 4 * 16 bit color components */
|
||||
gint16 opacity; /* Opacity 0 to 100 */
|
||||
gchar kind; /* Selected = 0, Protected = 1 */
|
||||
gchar padding; /* Padding */
|
||||
} DisplayInfo;
|
||||
|
||||
/* Channel display info data for Adobe Photoshop CS3 and higher to support floating point colors */
|
||||
typedef struct {
|
||||
gint16 colorSpace; /* Color space from PSDColorSpace */
|
||||
guint16 color[4]; /* 4 * 16 bit color components */
|
||||
gint16 opacity; /* Opacity 0 to 100 */
|
||||
gchar kind; /* Selected = 0, Protected = 1 */
|
||||
gchar mode; /* Alpha = 0, Inverted alpha = 1, Spot = 2 */
|
||||
} DisplayInfoNew;
|
||||
|
||||
/* PSD Channel length info data structure */
|
||||
typedef struct
|
||||
{
|
||||
@@ -444,6 +511,33 @@ typedef struct
|
||||
gboolean invert; /* Invert mask on blending */
|
||||
} MaskFlags;
|
||||
|
||||
/* PSD Slices */
|
||||
typedef struct
|
||||
{
|
||||
gint32 id; /* ID */
|
||||
gint32 groupid; /* Group ID */
|
||||
gint32 origin; /* Origin */
|
||||
gint32 associatedid; /* Associated Layer ID */
|
||||
gchar *name; /* Name */
|
||||
gint32 type; /* Type */
|
||||
gint32 left; /* Position coordinates */
|
||||
gint32 top;
|
||||
gint32 right;
|
||||
gint32 bottom;
|
||||
gchar *url; /* URL */
|
||||
gchar *target; /* Target */
|
||||
gchar *message; /* Message */
|
||||
gchar *alttag; /* Alt Tag */
|
||||
gchar html; /* Boolean for if cell text is HTML */
|
||||
gchar *celltext; /* Cell text */
|
||||
gint32 horizontal; /* Horizontal alignment */
|
||||
gint32 vertical; /* Vertical alignment */
|
||||
gchar alpha; /* Alpha */
|
||||
gchar red; /* Red */
|
||||
gchar green; /* Green */
|
||||
gchar blue; /* Blue */
|
||||
} PSDSlice;
|
||||
|
||||
/* PSD Layer mask data (length 20) */
|
||||
typedef struct
|
||||
{
|
||||
@@ -467,6 +561,18 @@ typedef struct
|
||||
gint32 right; /* Layer right */
|
||||
} LayerMaskExtra;
|
||||
|
||||
/* PSD text reading */
|
||||
typedef struct
|
||||
{
|
||||
gdouble xx; /* Transform information */
|
||||
gdouble xy;
|
||||
gdouble yx;
|
||||
gdouble yy;
|
||||
gdouble tx;
|
||||
gdouble ty;
|
||||
gchar *info; /* Text information */
|
||||
} PSDText;
|
||||
|
||||
/* PSD Layer data structure */
|
||||
typedef struct
|
||||
{
|
||||
@@ -489,6 +595,7 @@ typedef struct
|
||||
LayerMask layer_mask; /* Layer mask data */
|
||||
LayerMaskExtra layer_mask_extra; /* Layer mask extra data */
|
||||
LayerFlags layer_flags; /* Layer flags */
|
||||
PSDText text; /* PSD text */
|
||||
guint32 id; /* Layer ID (Tattoo) */
|
||||
guchar group_type; /* 0 -> not a group; 1 -> open folder; 2 -> closed folder; 3 -> end of group */
|
||||
} PSDlayer;
|
||||
@@ -508,6 +615,7 @@ typedef struct
|
||||
{
|
||||
GimpRGB gimp_color; /* Gimp RGB color */
|
||||
gint16 opacity; /* Opacity */
|
||||
guchar ps_mode; /* PS mode flag */
|
||||
guchar ps_kind; /* PS type flag */
|
||||
gint16 ps_cspace; /* PS color space */
|
||||
CMColor ps_color; /* PS color */
|
||||
@@ -539,7 +647,7 @@ typedef struct
|
||||
gboolean transparency; /* Image has merged transparency alpha channel */
|
||||
guint32 rows; /* Number of rows: 1 - 30000 */
|
||||
guint32 columns; /* Number of columns: 1 - 30000 */
|
||||
guint16 bps; /* Bits per channel: 1, 8 or 16 */
|
||||
guint16 bps; /* Bits per sample: 1, 8, 16, or 32 */
|
||||
guint16 color_mode; /* Image color mode: {PSDColorMode} */
|
||||
GimpImageBaseType base_type; /* Image base color mode: (GIMP) */
|
||||
guint16 comp_mode; /* Merged image compression mode */
|
||||
|
Reference in New Issue
Block a user