[gimp] plug-ins: merge soc-2013-psd branch, squashed into one commit
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: merge soc-2013-psd branch, squashed into one commit
- Date: Sun, 9 Feb 2014 18:17:56 +0000 (UTC)
commit fd997447e50a7e0c52da350c49ba52fe949a91db
Author: Simon Lui <simonlui src gnome org>
Date: Wed Jun 19 13:15:52 2013 -0400
plug-ins: merge soc-2013-psd branch, squashed into one commit
This ports PSD loading/saving to GEGL and adds parsing of more
PSD structs.
plug-ins/file-psd/Makefile.am | 1 +
plug-ins/file-psd/psd-image-res-load.c | 252 ++++++++++++++----
plug-ins/file-psd/psd-layer-res-load.c | 465 ++++++++++++++++++++++++++++----
plug-ins/file-psd/psd-load.c | 336 +++++++++++++++--------
plug-ins/file-psd/psd-save.c | 333 ++++++++++++-----------
plug-ins/file-psd/psd.c | 1 +
plug-ins/file-psd/psd.h | 144 +++++++++--
7 files changed, 1138 insertions(+), 394 deletions(-)
---
diff --git a/plug-ins/file-psd/Makefile.am b/plug-ins/file-psd/Makefile.am
index 0297581..8b288e6 100644
--- a/plug-ins/file-psd/Makefile.am
+++ b/plug-ins/file-psd/Makefile.am
@@ -64,6 +64,7 @@ LDADD = \
$(libgimpbase) \
$(JPEG_LIBS) \
$(GTK_LIBS) \
+ $(GEGL_LIBS) \
$(EXIF_LIBS) \
$(IPTCDATA_LIBS) \
$(RT_LIBS) \
diff --git a/plug-ins/file-psd/psd-image-res-load.c b/plug-ins/file-psd/psd-image-res-load.c
index db0153c..074eb64 100644
--- a/plug-ins/file-psd/psd-image-res-load.c
+++ b/plug-ins/file-psd/psd-image-res-load.c
@@ -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;
}
@@ -1233,6 +1271,118 @@ load_resource_1058 (const PSDimageres *res_a,
}
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,
FILE *f,
@@ -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;
}
diff --git a/plug-ins/file-psd/psd-layer-res-load.c b/plug-ins/file-psd/psd-layer-res-load.c
index f98377f..2c82d23 100644
--- a/plug-ins/file-psd/psd-layer-res-load.c
+++ b/plug-ins/file-psd/psd-layer-res-load.c
@@ -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) *
-
- * Effects layer resource IDs *
+ 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 *
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);
-
- 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;
+ // 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);
+
+ 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;
+}
diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c
index 5c556d6..8c19c3d 100644
--- a/plug-ins/file-psd/psd-load.c
+++ b/plug-ins/file-psd/psd-load.c
@@ -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);
@@ -1950,27 +1972,6 @@ read_channel_data (PSDchannel *channel,
}
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,
guint32 rows,
@@ -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;
+}
diff --git a/plug-ins/file-psd/psd-save.c b/plug-ins/file-psd/psd-save.c
index 9ffec9c..1d78b96 100644
--- a/plug-ins/file-psd/psd-save.c
+++ b/plug-ins/file-psd/psd-save.c
@@ -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 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 write_pixel_data (FILE *fd,
- gint32 drawableID,
- glong *ChanLenPosition,
- gint32 rowlenOffset);
-
-static gint32 create_merged_image (gint32 imageID);
+static void query (void);
+
+static void run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals);
+
+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 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,
@@ -412,7 +424,6 @@ psd_lmode_layer (gint32 idLayer,
}
}
-
static void
write_string (FILE *fd,
const gchar *val,
@@ -422,7 +433,6 @@ write_string (FILE *fd,
xfwrite (fd, val, strlen (val), why);
}
-
static void
write_pascalstring (FILE *fd,
const gchar *val,
@@ -460,7 +470,6 @@ write_pascalstring (FILE *fd,
write_gchar (fd, 0, why);
}
-
static void
xfwrite (FILE *fd,
gconstpointer buf,
@@ -477,7 +486,6 @@ xfwrite (FILE *fd,
}
}
-
static void
write_gchar (FILE *fd,
guchar val,
@@ -498,7 +506,6 @@ write_gchar (FILE *fd,
fseek (fd, pos + 1, SEEK_SET);
}
-
static void
write_gint16 (FILE *fd,
gint16 val,
@@ -518,9 +525,6 @@ write_gint16 (FILE *fd,
}
}
-
-
-
static void
write_gint32 (FILE *fd,
gint32 val,
@@ -540,7 +544,6 @@ write_gint32 (FILE *fd,
}
}
-
static void
write_datablock_luni (FILE *fd,
const gchar *val,
@@ -582,7 +585,6 @@ write_datablock_luni (FILE *fd,
}
}
-
static gint32
pack_pb_line (guchar *start,
gint32 length,
@@ -667,7 +669,6 @@ gimpBaseTypeToPsdMode (GimpImageBaseType gimpBaseType)
}
}
-
static gint
nChansLayer (gint gimpBaseType,
gint hasAlpha,
@@ -692,7 +693,6 @@ nChansLayer (gint gimpBaseType,
}
}
-
static void
reshuffle_cmap_write (guchar *mapGimp)
{
@@ -716,7 +716,6 @@ reshuffle_cmap_write (guchar *mapGimp)
g_free (mapPSD);
}
-
static void
save_header (FILE *fd,
gint32 image_id)
@@ -737,13 +736,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)
@@ -801,8 +797,6 @@ save_color_mode_data (FILE *fd,
}
}
-
-
static void
save_resources (FILE *fd,
gint32 image_id)
@@ -1032,8 +1026,6 @@ save_resources (FILE *fd,
fseek (fd, eof_pos, SEEK_SET);
}
-
-
static int
get_compress_channel_data (guchar *channel_data,
gint32 channel_cols,
@@ -1063,7 +1055,6 @@ get_compress_channel_data (guchar *channel_data,
return len;
}
-
static void
save_layer_and_mask (FILE *fd,
gint32 image_id)
@@ -1285,32 +1276,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);
@@ -1319,17 +1304,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;
@@ -1375,8 +1355,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),
@@ -1410,12 +1390,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)");
@@ -1443,8 +1420,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),
@@ -1474,19 +1451,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)
@@ -1542,50 +1517,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;
-
- gimp_pixel_rgn_init (®ion, drawable,
- 0, 0, drawable->width, drawable->height,
- TRUE, FALSE);
-
- for (pr = gimp_pixel_rgns_register (1, ®ion);
- pr != NULL;
- pr = gimp_pixel_rgns_process (pr))
- {
- guchar *data = region.data;
- gint y;
+ 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);
- for (y = 0; y < region.h; y++)
- {
- guchar *d = data;
- gint x;
+ while (gegl_buffer_iterator_next (iter))
+ {
+ guchar *data = iter->data[0];
+ gint y;
- for (x = 0; x < region.w; x++)
- {
- guint32 alpha = d[region.bpp - 1];
+ for (y = 0; y < iter->roi->height; y++)
+ {
+ guchar *d = data;
+ gint x;
- if (alpha < 255)
- {
- gint i;
+ for (x = 0; x < iter->roi->width; x++)
+ {
+ gint32 alpha = d[bpp - 1];
- transparency_found = TRUE;
+ if (alpha < 255)
+ {
+ gint i;
- /* blend against white, photoshop does this. */
- for (i = 0; i < region.bpp - 1; i++)
- d[i] = ((guint32) d[i] * alpha) / 255 + 255 - alpha;
- }
+ transparency_found = TRUE;
- d += region.bpp;
- }
+ /* blend against white, photoshop does this. */
+ for (i = 0; i < bpp - 1; i++)
+ d[i] = ((guint32) d[i] * alpha) / 255 + 255 - alpha;
+ }
- data += region.rowstride;
- }
- }
+ }
+
+ d += bpp;
+ }
+
+ data += n_components;
+ }
- gimp_drawable_detach (drawable);
+ g_object_unref (buffer);
if (! transparency_found)
gimp_layer_flatten (projection);
@@ -1629,18 +1604,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");
@@ -1659,8 +1632,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 "
@@ -1670,6 +1643,7 @@ save_image (const gchar *filename,
g_free (layers);
return FALSE;
}
+ g_object_unref (buffer);
}
g_free (layers);
@@ -1714,3 +1688,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;
+}
diff --git a/plug-ins/file-psd/psd.c b/plug-ins/file-psd/psd.c
index 8fb2674..a7911e6 100644
--- a/plug-ins/file-psd/psd.c
+++ b/plug-ins/file-psd/psd.c
@@ -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;
diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h
index 1bba60b..f9a6a65 100644
--- a/plug-ins/file-psd/psd.h
+++ b/plug-ins/file-psd/psd.h
@@ -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 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]