| | 1 | /* GIMP - The GNU Image Manipulation Program |
| | 2 | * Copyright (C) 1995 Spencer Kimball and Peter Mattis |
| | 3 | * |
| | 4 | * GIMP PSD Plug-in |
| | 5 | * Copyright 2007 by John Marshall |
| | 6 | * |
| | 7 | * This program is free software: you can redistribute it and/or modify |
| | 8 | * it under the terms of the GNU General Public License as published by |
| | 9 | * the Free Software Foundation; either version 3 of the License, or |
| | 10 | * (at your option) any later version. |
| | 11 | * |
| | 12 | * This program is distributed in the hope that it will be useful, |
| | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| | 15 | * GNU General Public License for more details. |
| | 16 | * |
| | 17 | * You should have received a copy of the GNU General Public License |
| | 18 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| | 19 | */ |
| | 20 | |
| | 21 | /* ----- Known Image Resource Block Types ----- |
| | 22 | All image resources not otherwise handled, including unknown types |
| | 23 | are added as image parasites. |
| | 24 | The data is attached as-is from the file (i.e. in big endian order). |
| | 25 | |
| | 26 | PSD_PS2_IMAGE_INFO = 1000, Dropped * 0x03e8 - Obsolete - ps 2.0 image info * |
| | 27 | PSD_MAC_PRINT_INFO = 1001, PS Only * 0x03e9 - Optional - Mac print manager print info record * |
| | 28 | PSD_PS2_COLOR_TAB = 1003, Dropped * 0x03eb - Obsolete - ps 2.0 indexed color table * |
| | 29 | PSD_RESN_INFO = 1005, Loaded * 0x03ed - ResolutionInfo structure * |
| | 30 | PSD_ALPHA_NAMES = 1006, Loaded * 0x03ee - Alpha channel names * |
| | 31 | PSD_DISPLAY_INFO = 1007, Loaded * 0x03ef - DisplayInfo structure * |
| | 32 | PSD_CAPTION = 1008, Loaded * 0x03f0 - Optional - Caption string * |
| | 33 | PSD_BORDER_INFO = 1009, * 0x03f1 - Border info * |
| | 34 | PSD_BACKGROUND_COL = 1010, * 0x03f2 - Background color * |
| | 35 | PSD_PRINT_FLAGS = 1011, * 0x03f3 - Print flags * |
| | 36 | PSD_GREY_HALFTONE = 1012, * 0x03f4 - Greyscale and multichannel halftoning info * |
| | 37 | PSD_COLOR_HALFTONE = 1013, * 0x03f5 - Color halftoning info * |
| | 38 | PSD_DUOTONE_HALFTONE = 1014, * 0x03f6 - Duotone halftoning info * |
| | 39 | PSD_GREY_XFER = 1015, * 0x03f7 - Greyscale and multichannel transfer functions * |
| | 40 | PSD_COLOR_XFER = 1016, * 0x03f8 - Color transfer functions * |
| | 41 | PSD_DUOTONE_XFER = 1017, * 0x03f9 - Duotone transfer functions * |
| | 42 | PSD_DUOTONE_INFO = 1018, * 0x03fa - Duotone image information * |
| | 43 | PSD_EFFECTIVE_BW = 1019, * 0x03fb - Effective black & white values for dot range * |
| | 44 | PSD_OBSOLETE_01 = 1020, Dropped * 0x03fc - Obsolete * |
| | 45 | PSD_EPS_OPT = 1021, * 0x03fd - EPS options * |
| | 46 | PSD_QUICK_MASK = 1022, Loaded * 0x03fe - Quick mask info * |
| | 47 | PSD_OBSOLETE_02 = 1023, Dropped * 0x03ff - Obsolete * |
| | 48 | PSD_LAYER_STATE = 1024, Loaded * 0x0400 - Layer state info * |
| | 49 | PSD_WORKING_PATH = 1025, * 0x0401 - Working path (not saved) * |
| | 50 | PSD_LAYER_GROUP = 1026, * 0x0402 - Layers group info * |
| | 51 | PSD_OBSOLETE_03 = 1027, Dropped * 0x0403 - Obsolete * |
| | 52 | PSD_IPTC_NAA_DATA = 1028, Loaded * 0x0404 - IPTC-NAA record (IMV4.pdf) * |
| | 53 | PSD_IMAGE_MODE_RAW = 1029, * 0x0405 - Image mode for raw format files * |
| | 54 | PSD_JPEG_QUAL = 1030, PS Only * 0x0406 - JPEG quality * |
| | 55 | PSD_GRID_GUIDE = 1032, Loaded * 0x0408 - Grid & guide info * |
| | 56 | PSD_THUMB_RES = 1033, Special * 0x0409 - Thumbnail resource * |
| | 57 | PSD_COPYRIGHT_FLG = 1034, * 0x040a - Copyright flag * |
| | 58 | PSD_URL = 1035, * 0x040b - URL string * |
| | 59 | PSD_THUMB_RES2 = 1036, Special * 0x040c - Thumbnail resource * |
| | 60 | PSD_GLOBAL_ANGLE = 1037, * 0x040d - Global angle * |
| | 61 | PSD_COLOR_SAMPLER = 1038, * 0x040e - Color samplers resource * |
| | 62 | PSD_ICC_PROFILE = 1039, Loaded * 0x040f - ICC Profile * |
| | 63 | PSD_WATERMARK = 1040, * 0x0410 - Watermark * |
| | 64 | PSD_ICC_UNTAGGED = 1041, * 0x0411 - Do not use ICC profile flag * |
| | 65 | PSD_EFFECTS_VISIBLE = 1042, * 0x0412 - Show hide all effects layers * |
| | 66 | PSD_SPOT_HALFTONE = 1043, * 0x0413 - Spot halftone * |
| | 67 | PSD_DOC_IDS = 1044, * 0x0414 - Document specific IDs * |
| | 68 | PSD_ALPHA_NAMES_UNI = 1045, Loaded * 0x0415 - Unicode alpha names * |
| | 69 | PSD_IDX_COL_TAB_CNT = 1046, Loaded * 0x0416 - Indexed color table count * |
| | 70 | PSD_IDX_TRANSPARENT = 1047, * 0x0417 - Index of transparent color (if any) * |
| | 71 | PSD_GLOBAL_ALT = 1049, * 0x0419 - Global altitude * |
| | 72 | PSD_SLICES = 1050, * 0x041a - Slices * |
| | 73 | PSD_WORKFLOW_URL_UNI = 1051, * 0x041b - Workflow URL - Unicode string * |
| | 74 | PSD_JUMP_TO_XPEP = 1052, * 0x041c - Jump to XPEP (?) * |
| | 75 | PSD_ALPHA_ID = 1053, Loaded * 0x041d - Alpha IDs * |
| | 76 | PSD_URL_LIST_UNI = 1054, * 0x041e - URL list - unicode * |
| | 77 | PSD_VERSION_INFO = 1057, * 0x0421 - Version info * |
| | 78 | PSD_EXIF_DATA = 1058, Loaded * 0x0422 - Exif data block 1 * |
| | 79 | PSD_EXIF_DATA_3 = 1059 * 0X0423 - Exif data block 3 (?) * |
| | 80 | PSD_XMP_DATA = 1060, Loaded * 0x0424 - XMP data block * |
| | 81 | PSD_CAPTION_DIGEST = 1061, * 0x0425 - Caption digest * |
| | 82 | PSD_PRINT_SCALE = 1062, * 0x0426 - Print scale * |
| | 83 | PSD_PIXEL_AR = 1064, * 0x0428 - Pixel aspect ratio * |
| | 84 | PSD_LAYER_COMPS = 1065, * 0x0429 - Layer comps * |
| | 85 | PSD_ALT_DUOTONE_COLOR = 1066, * 0x042A - Alternative Duotone colors * |
| | 86 | PSD_ALT_SPOT_COLOR = 1067, * 0x042B - Alternative Spot colors * |
| | 87 | PSD_LAYER_SELECT_ID = 1069, * 0x042D - Layer selection ID * |
| | 88 | PSD_HDR_TONING_INFO = 1070, * 0x042E - HDR toning information * |
| | 89 | PSD_PRINT_INFO_SCALE = 1071, * 0x042F - Print scale * |
| | 90 | PSD_LAYER_GROUP_E_ID = 1072, * 0x0430 - Layer group(s) enabled ID * |
| | 91 | PSD_COLOR_SAMPLER_NEW = 1073, * 0x0431 - Color sampler resource for ps CS3 and higher PSD files * |
| | 92 | PSD_MEASURE_SCALE = 1074, * 0x0432 - Measurement scale * |
| | 93 | PSD_TIMELINE_INFO = 1075, * 0x0433 - Timeline information * |
| | 94 | PSD_SHEET_DISCLOSE = 1076, * 0x0434 - Sheet discloser * |
| | 95 | PSD_DISPLAY_INFO_NEW = 1077, Loaded * 0x0435 - DisplayInfo structure for ps CS3 and higher PSD files * |
| | 96 | PSD_ONION_SKINS = 1078, * 0x0436 - Onion skins * |
| | 97 | PSD_COUNT_INFO = 1080, * 0x0438 - Count information* |
| | 98 | PSD_PRINT_INFO = 1082, * 0x043A - Print information added in ps CS5* |
| | 99 | PSD_PRINT_STYLE = 1083, * 0x043B - Print style * |
| | 100 | PSD_MAC_NSPRINTINFO = 1084, * 0x043C - Mac NSPrintInfo* |
| | 101 | PSD_WIN_DEVMODE = 1085, * 0x043D - Windows DEVMODE * |
| | 102 | PSD_AUTO_SAVE_PATH = 1086, * 0x043E - Auto save file path * |
| | 103 | PSD_AUTO_SAVE_FORMAT = 1087, * 0x043F - Auto save format * |
| | 104 | PSD_PATH_INFO_FIRST = 2000, Loaded * 0x07d0 - First path info block * |
| | 105 | PSD_PATH_INFO_LAST = 2998, Loaded * 0x0bb6 - Last path info block * |
| | 106 | PSD_CLIPPING_PATH = 2999, * 0x0bb7 - Name of clipping path * |
| | 107 | PSD_PLUGIN_R_FIRST = 4000, * 0x0FA0 - First plugin resource * |
| | 108 | PSD_PLUGIN_R_LAST = 4999, * 0x1387 - Last plugin resource * |
| | 109 | PSD_IMAGEREADY_VARS = 7000, PS Only * 0x1B58 - Imageready variables * |
| | 110 | PSD_IMAGEREADY_DATA = 7001, PS Only * 0x1B59 - Imageready data sets * |
| | 111 | PSD_LIGHTROOM_WORK = 8000, PS Only * 0x1F40 - Lightroom workflow * |
| | 112 | PSD_PRINT_FLAGS_2 = 10000 * 0x2710 - Print flags * |
| | 113 | */ |
| | 114 | |
| | 115 | #include "config.h" |
| | 116 | |
| | 117 | #include <string.h> |
| | 118 | #include <errno.h> |
| | 119 | |
| | 120 | #include <glib/gstdio.h> |
| | 121 | #include <libgimp/gimp.h> |
| | 122 | |
| | 123 | #include <jpeglib.h> |
| | 124 | #include <jerror.h> |
| | 125 | |
| | 126 | #ifdef HAVE_IPTCDATA |
| | 127 | #include <libiptcdata/iptc-data.h> |
| | 128 | #endif /* HAVE_IPTCDATA */ |
| | 129 | |
| | 130 | #include "psd.h" |
| | 131 | #include "psd-util.h" |
| | 132 | #include "psd-image-res-load.h" |
| | 133 | |
| | 134 | #include "libgimp/stdplugins-intl.h" |
| | 135 | |
| | 136 | #define EXIF_HEADER_SIZE 8 |
| | 137 | |
| | 138 | /* Local function prototypes */ |
| | 139 | static gint load_resource_unknown (const PSDimageres *res_a, |
| | 140 | GimpImage *image, |
| | 141 | GInputStream *input, |
| | 142 | GError **error); |
| | 143 | |
| | 144 | static gint load_resource_ps_only (const PSDimageres *res_a, |
| | 145 | GimpImage *image, |
| | 146 | GInputStream *input, |
| | 147 | GError **error); |
| | 148 | |
| | 149 | static gint load_resource_1005 (const PSDimageres *res_a, |
| | 150 | GimpImage *image, |
| | 151 | GInputStream *input, |
| | 152 | GError **error); |
| | 153 | |
| | 154 | static gint load_resource_1006 (const PSDimageres *res_a, |
| | 155 | GimpImage *image, |
| | 156 | PSDimage *img_a, |
| | 157 | GInputStream *input, |
| | 158 | GError **error); |
| | 159 | |
| | 160 | static gint load_resource_1007 (const PSDimageres *res_a, |
| | 161 | GimpImage *image, |
| | 162 | PSDimage *img_a, |
| | 163 | GInputStream *input, |
| | 164 | GError **error); |
| | 165 | |
| | 166 | static gint load_resource_1008 (const PSDimageres *res_a, |
| | 167 | GimpImage *image, |
| | 168 | GInputStream *input, |
| | 169 | GError **error); |
| | 170 | |
| | 171 | static gint load_resource_1022 (const PSDimageres *res_a, |
| | 172 | GimpImage *image, |
| | 173 | PSDimage *img_a, |
| | 174 | GInputStream *input, |
| | 175 | GError **error); |
| | 176 | |
| | 177 | static gint load_resource_1024 (const PSDimageres *res_a, |
| | 178 | GimpImage *image, |
| | 179 | PSDimage *img_a, |
| | 180 | GInputStream *input, |
| | 181 | GError **error); |
| | 182 | |
| | 183 | static gint load_resource_1028 (const PSDimageres *res_a, |
| | 184 | GimpImage *image, |
| | 185 | GInputStream *input, |
| | 186 | GError **error); |
| | 187 | |
| | 188 | static gint load_resource_1032 (const PSDimageres *res_a, |
| | 189 | GimpImage *image, |
| | 190 | GInputStream *input, |
| | 191 | GError **error); |
| | 192 | |
| | 193 | /* 1033 - Thumbnail needs special handling since it calls the jpeg library |
| | 194 | * which needs a classic FILE. */ |
| | 195 | static gint load_resource_1033 (const PSDimageres *res_a, |
| | 196 | GimpImage *image, |
| | 197 | GFile *file, |
| | 198 | GInputStream *input, |
| | 199 | GError **error); |
| | 200 | |
| | 201 | static gint load_resource_1039 (const PSDimageres *res_a, |
| | 202 | PSDimage *img_a, |
| | 203 | GimpImage *image, |
| | 204 | GInputStream *input, |
| | 205 | GError **error); |
| | 206 | |
| | 207 | static gint load_resource_1045 (const PSDimageres *res_a, |
| | 208 | GimpImage *image, |
| | 209 | PSDimage *img_a, |
| | 210 | GInputStream *input, |
| | 211 | GError **error); |
| | 212 | |
| | 213 | static gint load_resource_1046 (const PSDimageres *res_a, |
| | 214 | GimpImage *image, |
| | 215 | GInputStream *input, |
| | 216 | GError **error); |
| | 217 | |
| | 218 | static gint load_resource_1053 (const PSDimageres *res_a, |
| | 219 | GimpImage *image, |
| | 220 | PSDimage *img_a, |
| | 221 | GInputStream *input, |
| | 222 | GError **error); |
| | 223 | |
| | 224 | static gint load_resource_1058 (const PSDimageres *res_a, |
| | 225 | GimpImage *image, |
| | 226 | GInputStream *input, |
| | 227 | GError **error); |
| | 228 | |
| | 229 | static gint load_resource_1069 (const PSDimageres *res_a, |
| | 230 | GimpImage *image, |
| | 231 | PSDimage *img_a, |
| | 232 | GInputStream *input, |
| | 233 | GError **error); |
| | 234 | |
| | 235 | static gint load_resource_1077 (const PSDimageres *res_a, |
| | 236 | GimpImage *image, |
| | 237 | PSDimage *img_a, |
| | 238 | GInputStream *input, |
| | 239 | GError **error); |
| | 240 | |
| | 241 | static gint load_resource_2000 (const PSDimageres *res_a, |
| | 242 | GimpImage *image, |
| | 243 | GInputStream *input, |
| | 244 | GError **error); |
| | 245 | |
| | 246 | static gint load_resource_2999 (const PSDimageres *res_a, |
| | 247 | GimpImage *image, |
| | 248 | GInputStream *input, |
| | 249 | GError **error); |
| | 250 | |
| | 251 | /* Public Functions */ |
| | 252 | gint |
| | 253 | get_image_resource_header (PSDimageres *res_a, |
| | 254 | GInputStream *input, |
| | 255 | GError **error) |
| | 256 | { |
| | 257 | gint32 read_len; |
| | 258 | gint32 write_len; |
| | 259 | gchar *name; |
| | 260 | |
| | 261 | if (psd_read (input, &res_a->type, 4, error) < 4 || |
| | 262 | psd_read (input, &res_a->id, 2, error) < 2) |
| | 263 | { |
| | 264 | psd_set_error (error); |
| | 265 | return -1; |
| | 266 | } |
| | 267 | res_a->id = GUINT16_FROM_BE (res_a->id); |
| | 268 | name = fread_pascal_string (&read_len, &write_len, 2, input, error); |
| | 269 | if (*error) |
| | 270 | return -1; |
| | 271 | if (name != NULL) |
| | 272 | g_strlcpy (res_a->name, name, write_len + 1); |
| | 273 | else |
| | 274 | res_a->name[0] = 0x0; |
| | 275 | g_free (name); |
| | 276 | if (psd_read (input, &res_a->data_len, 4, error) < 4) |
| | 277 | { |
| | 278 | psd_set_error (error); |
| | 279 | return -1; |
| | 280 | } |
| | 281 | res_a->data_len = GUINT32_FROM_BE (res_a->data_len); |
| | 282 | res_a->data_start = g_seekable_tell (G_SEEKABLE (input)); |
| | 283 | |
| | 284 | IFDBG(2) g_debug ("Type: %.4s, id: %d, start: %" G_GOFFSET_FORMAT ", len: %" G_GSIZE_FORMAT, |
| | 285 | res_a->type, res_a->id, res_a->data_start, res_a->data_len); |
| | 286 | |
| | 287 | return 0; |
| | 288 | } |
| | 289 | |
| | 290 | gint |
| | 291 | load_image_resource (PSDimageres *res_a, |
| | 292 | GimpImage *image, |
| | 293 | PSDimage *img_a, |
| | 294 | GInputStream *input, |
| | 295 | gboolean *resolution_loaded, |
| | 296 | gboolean *profile_loaded, |
| | 297 | GError **error) |
| | 298 | { |
| | 299 | gint pad; |
| | 300 | |
| | 301 | /* Set file position to start of image resource data block */ |
| | 302 | if (! psd_seek (input, res_a->data_start, G_SEEK_SET, error)) |
| | 303 | { |
| | 304 | psd_set_error (error); |
| | 305 | return -1; |
| | 306 | } |
| | 307 | |
| | 308 | /* Process image resource blocks */ |
| | 309 | if (memcmp (res_a->type, "8BIM", 4) != 0 && |
| | 310 | memcmp (res_a->type, "MeSa", 4) !=0) |
| | 311 | { |
| | 312 | IFDBG(1) g_debug ("Unknown image resource type signature %.4s", |
| | 313 | res_a->type); |
| | 314 | } |
| | 315 | else |
| | 316 | { |
| | 317 | switch (res_a->id) |
| | 318 | { |
| | 319 | case PSD_PS2_IMAGE_INFO: |
| | 320 | case PSD_PS2_COLOR_TAB: |
| | 321 | case PSD_OBSOLETE_01: |
| | 322 | case PSD_OBSOLETE_02: |
| | 323 | case PSD_OBSOLETE_03: |
| | 324 | /* Drop obsolete image resource blocks */ |
| | 325 | IFDBG(2) g_debug ("Obsolete image resource block: %d", |
| | 326 | res_a->id); |
| | 327 | break; |
| | 328 | |
| | 329 | case PSD_THUMB_RES: |
| | 330 | case PSD_THUMB_RES2: |
| | 331 | /* Drop thumbnails from standard file load */ |
| | 332 | IFDBG(2) g_debug ("Thumbnail resource block: %d", |
| | 333 | res_a->id); |
| | 334 | break; |
| | 335 | |
| | 336 | case PSD_MAC_PRINT_INFO: |
| | 337 | case PSD_JPEG_QUAL: |
| | 338 | /* Save photoshop resources with no meaning for GIMP |
| | 339 | as image parasites */ |
| | 340 | load_resource_ps_only (res_a, image, input, error); |
| | 341 | break; |
| | 342 | |
| | 343 | case PSD_RESN_INFO: |
| | 344 | if (! load_resource_1005 (res_a, image, input, error)) |
| | 345 | *resolution_loaded = TRUE; |
| | 346 | break; |
| | 347 | |
| | 348 | case PSD_ALPHA_NAMES: |
| | 349 | load_resource_1006 (res_a, image, img_a, input, error); |
| | 350 | break; |
| | 351 | |
| | 352 | case PSD_DISPLAY_INFO: |
| | 353 | load_resource_1007 (res_a, image, img_a, input, error); |
| | 354 | break; |
| | 355 | |
| | 356 | case PSD_CAPTION: |
| | 357 | load_resource_1008 (res_a, image, input, error); |
| | 358 | break; |
| | 359 | |
| | 360 | case PSD_QUICK_MASK: |
| | 361 | if (! img_a->merged_image_only) |
| | 362 | load_resource_1022 (res_a, image, img_a, input, error); |
| | 363 | break; |
| | 364 | |
| | 365 | case PSD_LAYER_STATE: |
| | 366 | if (! img_a->merged_image_only) |
| | 367 | load_resource_1024 (res_a, image, img_a, input, error); |
| | 368 | break; |
| | 369 | |
| | 370 | case PSD_WORKING_PATH: |
| | 371 | if (! img_a->merged_image_only) |
| | 372 | load_resource_2000 (res_a, image, input, error); |
| | 373 | break; |
| | 374 | |
| | 375 | case PSD_IPTC_NAA_DATA: |
| | 376 | load_resource_1028 (res_a, image, input, error); |
| | 377 | break; |
| | 378 | |
| | 379 | case PSD_GRID_GUIDE: |
| | 380 | if (! img_a->merged_image_only) |
| | 381 | load_resource_1032 (res_a, image, input, error); |
| | 382 | break; |
| | 383 | |
| | 384 | case PSD_ICC_PROFILE: |
| | 385 | if (! load_resource_1039 (res_a, img_a, image, input, error)) |
| | 386 | *profile_loaded = TRUE; |
| | 387 | break; |
| | 388 | |
| | 389 | case PSD_ALPHA_NAMES_UNI: |
| | 390 | load_resource_1045 (res_a, image, img_a, input, error); |
| | 391 | break; |
| | 392 | |
| | 393 | case PSD_IDX_COL_TAB_CNT: |
| | 394 | load_resource_1046 (res_a, image, input, error); |
| | 395 | break; |
| | 396 | |
| | 397 | case PSD_ALPHA_ID: |
| | 398 | if (! img_a->merged_image_only) |
| | 399 | load_resource_1053 (res_a, image, img_a, input, error); |
| | 400 | break; |
| | 401 | |
| | 402 | case PSD_EXIF_DATA: |
| | 403 | load_resource_1058 (res_a, image, input, error); |
| | 404 | break; |
| | 405 | |
| | 406 | case PSD_LAYER_SELECT_ID: |
| | 407 | if (! img_a->merged_image_only) |
| | 408 | load_resource_1069 (res_a, image, img_a, input, error); |
| | 409 | break; |
| | 410 | |
| | 411 | case PSD_XMP_DATA: |
| | 412 | break; |
| | 413 | |
| | 414 | case PSD_DISPLAY_INFO_NEW: |
| | 415 | load_resource_1077 (res_a, image, img_a, input, error); |
| | 416 | break; |
| | 417 | |
| | 418 | case PSD_CLIPPING_PATH: |
| | 419 | load_resource_2999 (res_a, image, input, error); |
| | 420 | break; |
| | 421 | |
| | 422 | case PSD_LAYER_COMPS: |
| | 423 | img_a->unsupported_features->layer_comp = TRUE; |
| | 424 | img_a->unsupported_features->show_gui = TRUE; |
| | 425 | load_resource_unknown (res_a, image, input, error); |
| | 426 | break; |
| | 427 | |
| | 428 | default: |
| | 429 | if (res_a->id >= 2000 && |
| | 430 | res_a->id < 2999) |
| | 431 | load_resource_2000 (res_a, image, input, error); |
| | 432 | else |
| | 433 | load_resource_unknown (res_a, image, input, error); |
| | 434 | } |
| | 435 | } |
| | 436 | |
| | 437 | /* Image blocks are null padded to even length */ |
| | 438 | if (res_a->data_len % 2 == 0) |
| | 439 | pad = 0; |
| | 440 | else |
| | 441 | pad = 1; |
| | 442 | |
| | 443 | /* Set file position to end of image resource block */ |
| | 444 | if (! psd_seek (input, res_a->data_start + res_a->data_len + pad, G_SEEK_SET, error)) |
| | 445 | { |
| | 446 | psd_set_error (error); |
| | 447 | return -1; |
| | 448 | } |
| | 449 | |
| | 450 | return 0; |
| | 451 | } |
| | 452 | |
| | 453 | gint |
| | 454 | load_thumbnail_resource (PSDimageres *res_a, |
| | 455 | GimpImage *image, |
| | 456 | GFile *file, |
| | 457 | GInputStream *input, |
| | 458 | GError **error) |
| | 459 | { |
| | 460 | gint rtn = 0; |
| | 461 | gint pad; |
| | 462 | |
| | 463 | /* Set file position to start of image resource data block */ |
| | 464 | if (! psd_seek (input, res_a->data_start, G_SEEK_SET, error)) |
| | 465 | { |
| | 466 | psd_set_error (error); |
| | 467 | return -1; |
| | 468 | } |
| | 469 | |
| | 470 | /* Process image resource blocks */ |
| | 471 | if (res_a->id == PSD_THUMB_RES |
| | 472 | || res_a->id == PSD_THUMB_RES2) |
| | 473 | { |
| | 474 | /* Load thumbnails from standard file load */ |
| | 475 | load_resource_1033 (res_a, image, file, input, error); |
| | 476 | rtn = 1; |
| | 477 | } |
| | 478 | |
| | 479 | /* Image blocks are null padded to even length */ |
| | 480 | if (res_a->data_len % 2 == 0) |
| | 481 | pad = 0; |
| | 482 | else |
| | 483 | pad = 1; |
| | 484 | |
| | 485 | /* Set file position to end of image resource block */ |
| | 486 | if (psd_seek (input, res_a->data_start + res_a->data_len + pad, G_SEEK_SET, error)) |
| | 487 | { |
| | 488 | psd_set_error (error); |
| | 489 | return -1; |
| | 490 | } |
| | 491 | |
| | 492 | return rtn; |
| | 493 | } |
| | 494 | |
| | 495 | /* Private Functions */ |
| | 496 | |
| | 497 | static gint |
| | 498 | load_resource_unknown (const PSDimageres *res_a, |
| | 499 | GimpImage *image, |
| | 500 | GInputStream *input, |
| | 501 | GError **error) |
| | 502 | { |
| | 503 | /* Unknown image resources attached as parasites to re-save later */ |
| | 504 | GimpParasite *parasite; |
| | 505 | gchar *data; |
| | 506 | gchar *name; |
| | 507 | |
| | 508 | IFDBG(2) g_debug ("Process unknown image resource block: %d", res_a->id); |
| | 509 | |
| | 510 | data = g_malloc (res_a->data_len); |
| | 511 | if (res_a->data_len > 0 && psd_read (input, data, res_a->data_len, error) < res_a->data_len) |
| | 512 | { |
| | 513 | psd_set_error (error); |
| | 514 | g_free (data); |
| | 515 | return -1; |
| | 516 | } |
| | 517 | |
| | 518 | name = g_strdup_printf ("psd-image-resource-%.4s-%.4x", |
| | 519 | res_a->type, res_a->id); |
| | 520 | IFDBG(2) g_debug ("Parasite name: %s", name); |
| | 521 | |
| | 522 | parasite = gimp_parasite_new (name, 0, res_a->data_len, data); |
| | 523 | gimp_image_attach_parasite (image, parasite); |
| | 524 | gimp_parasite_free (parasite); |
| | 525 | g_free (data); |
| | 526 | g_free (name); |
| | 527 | |
| | 528 | return 0; |
| | 529 | } |
| | 530 | |
| | 531 | static gint |
| | 532 | load_resource_ps_only (const PSDimageres *res_a, |
| | 533 | GimpImage *image, |
| | 534 | GInputStream *input, |
| | 535 | GError **error) |
| | 536 | { |
| | 537 | /* Save photoshop resources with no meaning for GIMP as image parasites |
| | 538 | to re-save later */ |
| | 539 | GimpParasite *parasite; |
| | 540 | gchar *data; |
| | 541 | gchar *name; |
| | 542 | |
| | 543 | IFDBG(3) g_debug ("Process image resource block: %d", res_a->id); |
| | 544 | |
| | 545 | data = g_malloc (res_a->data_len); |
| | 546 | if (psd_read (input, data, res_a->data_len, error) < res_a->data_len) |
| | 547 | { |
| | 548 | psd_set_error (error); |
| | 549 | g_free (data); |
| | 550 | return -1; |
| | 551 | } |
| | 552 | |
| | 553 | name = g_strdup_printf ("psd-image-resource-%.4s-%.4x", |
| | 554 | res_a->type, res_a->id); |
| | 555 | IFDBG(2) g_debug ("Parasite name: %s", name); |
| | 556 | |
| | 557 | parasite = gimp_parasite_new (name, 0, res_a->data_len, data); |
| | 558 | gimp_image_attach_parasite (image, parasite); |
| | 559 | gimp_parasite_free (parasite); |
| | 560 | g_free (data); |
| | 561 | g_free (name); |
| | 562 | |
| | 563 | return 0; |
| | 564 | } |
| | 565 | |
| | 566 | static gint |
| | 567 | load_resource_1005 (const PSDimageres *res_a, |
| | 568 | GimpImage *image, |
| | 569 | GInputStream *input, |
| | 570 | GError **error) |
| | 571 | { |
| | 572 | /* Load image resolution and unit of measure */ |
| | 573 | |
| | 574 | /* FIXME width unit and height unit unused at present */ |
| | 575 | |
| | 576 | ResolutionInfo res_info; |
| | 577 | GimpUnit *image_unit; |
| | 578 | |
| | 579 | IFDBG(2) g_debug ("Process image resource block 1005: Resolution Info"); |
| | 580 | |
| | 581 | if (psd_read (input, &res_info.hRes, 4, error) < 4 || |
| | 582 | psd_read (input, &res_info.hResUnit, 2, error) < 2 || |
| | 583 | psd_read (input, &res_info.widthUnit, 2, error) < 2 || |
| | 584 | psd_read (input, &res_info.vRes, 4, error) < 4 || |
| | 585 | psd_read (input, &res_info.vResUnit, 2, error) < 2 || |
| | 586 | psd_read (input, &res_info.heightUnit, 2, error) < 2) |
| | 587 | { |
| | 588 | psd_set_error (error); |
| | 589 | return -1; |
| | 590 | } |
| | 591 | res_info.hRes = GINT32_FROM_BE (res_info.hRes); |
| | 592 | res_info.hResUnit = GINT16_FROM_BE (res_info.hResUnit); |
| | 593 | res_info.widthUnit = GINT16_FROM_BE (res_info.widthUnit); |
| | 594 | res_info.vRes = GINT32_FROM_BE (res_info.vRes); |
| | 595 | res_info.vResUnit = GINT16_FROM_BE (res_info.vResUnit); |
| | 596 | res_info.heightUnit = GINT16_FROM_BE (res_info.heightUnit); |
| | 597 | |
| | 598 | IFDBG(3) g_debug ("Resolution: %d, %d, %d, %d, %d, %d", |
| | 599 | res_info.hRes, |
| | 600 | res_info.hResUnit, |
| | 601 | res_info.widthUnit, |
| | 602 | res_info.vRes, |
| | 603 | res_info.vResUnit, |
| | 604 | res_info.heightUnit); |
| | 605 | |
| | 606 | /* Resolution always recorded as pixels / inch in a fixed point implied |
| | 607 | decimal int32 with 16 bits before point and 16 after (i.e. cast as |
| | 608 | double and divide resolution by 2^16 */ |
| | 609 | gimp_image_set_resolution (image, |
| | 610 | res_info.hRes / 65536.0, res_info.vRes / 65536.0); |
| | 611 | |
| | 612 | /* GIMP only has one display unit so use ps horizontal resolution unit */ |
| | 613 | switch (res_info.hResUnit) |
| | 614 | { |
| | 615 | case PSD_RES_INCH: |
| | 616 | image_unit = gimp_unit_inch (); |
| | 617 | break; |
| | 618 | case PSD_RES_CM: |
| | 619 | image_unit = gimp_unit_mm (); |
| | 620 | break; |
| | 621 | default: |
| | 622 | image_unit = gimp_unit_inch (); |
| | 623 | } |
| | 624 | |
| | 625 | gimp_image_set_unit (image, image_unit); |
| | 626 | |
| | 627 | return 0; |
| | 628 | } |
| | 629 | |
| | 630 | static gint |
| | 631 | load_resource_1006 (const PSDimageres *res_a, |
| | 632 | GimpImage *image, |
| | 633 | PSDimage *img_a, |
| | 634 | GInputStream *input, |
| | 635 | GError **error) |
| | 636 | { |
| | 637 | /* Load alpha channel names stored as a series of pascal strings |
| | 638 | unpadded between strings */ |
| | 639 | |
| | 640 | gchar *str; |
| | 641 | gint32 block_rem; |
| | 642 | gint32 read_len; |
| | 643 | gint32 write_len; |
| | 644 | |
| | 645 | IFDBG(2) g_debug ("Process image resource block 1006: Alpha Channel Names"); |
| | 646 | |
| | 647 | if (img_a->alpha_names) |
| | 648 | { |
| | 649 | IFDBG(3) g_debug ("Alpha names loaded from unicode resource block"); |
| | 650 | return 0; |
| | 651 | } |
| | 652 | |
| | 653 | img_a->alpha_names = g_ptr_array_new (); |
| | 654 | |
| | 655 | block_rem = res_a->data_len; |
| | 656 | while (block_rem > 1) |
| | 657 | { |
| | 658 | str = fread_pascal_string (&read_len, &write_len, 1, input, error); |
| | 659 | if (*error) |
| | 660 | return -1; |
| | 661 | IFDBG(3) g_debug ("String: %s, %d, %d", str, read_len, write_len); |
| | 662 | if (write_len >= 0) |
| | 663 | { |
| | 664 | g_ptr_array_add (img_a->alpha_names, (gpointer) str); |
| | 665 | } |
| | 666 | block_rem -= read_len; |
| | 667 | } |
| | 668 | |
| | 669 | return 0; |
| | 670 | } |
| | 671 | |
| | 672 | static gint |
| | 673 | load_resource_1007 (const PSDimageres *res_a, |
| | 674 | GimpImage *image, |
| | 675 | PSDimage *img_a, |
| | 676 | GInputStream *input, |
| | 677 | GError **error) |
| | 678 | { |
| | 679 | /* Load alpha channel display info */ |
| | 680 | |
| | 681 | DisplayInfo dsp_info; |
| | 682 | CMColor ps_color; |
| | 683 | gint16 tot_rec; |
| | 684 | gint cidx; |
| | 685 | |
| | 686 | IFDBG(2) g_debug ("Process image resource block 1007: Display Info"); |
| | 687 | tot_rec = res_a->data_len / 14; |
| | 688 | if (tot_rec == 0) |
| | 689 | return 0; |
| | 690 | |
| | 691 | img_a->alpha_display_info = g_new (PSDchanneldata *, tot_rec); |
| | 692 | img_a->alpha_display_count = tot_rec; |
| | 693 | for (cidx = 0; cidx < tot_rec; ++cidx) |
| | 694 | { |
| | 695 | GeglColor *color; |
| | 696 | |
| | 697 | if (psd_read (input, &dsp_info.colorSpace, 2, error) < 2 || |
| | 698 | psd_read (input, &dsp_info.color, 8, error) < 8 || |
| | 699 | psd_read (input, &dsp_info.opacity, 2, error) < 2 || |
| | 700 | psd_read (input, &dsp_info.kind, 1, error) < 1 || |
| | 701 | psd_read (input, &dsp_info.padding, 1, error) < 1) |
| | 702 | { |
| | 703 | psd_set_error (error); |
| | 704 | return -1; |
| | 705 | } |
| | 706 | dsp_info.colorSpace = GINT16_FROM_BE (dsp_info.colorSpace); |
| | 707 | ps_color.cmyk.cyan = GUINT16_FROM_BE (dsp_info.color[0]); |
| | 708 | ps_color.cmyk.magenta = GUINT16_FROM_BE (dsp_info.color[1]); |
| | 709 | ps_color.cmyk.yellow = GUINT16_FROM_BE (dsp_info.color[2]); |
| | 710 | ps_color.cmyk.black = GUINT16_FROM_BE (dsp_info.color[3]); |
| | 711 | dsp_info.opacity = GINT16_FROM_BE (dsp_info.opacity); |
| | 712 | |
| | 713 | color = gegl_color_new ("red"); |
| | 714 | |
| | 715 | switch (dsp_info.colorSpace) |
| | 716 | { |
| | 717 | case PSD_CS_RGB: |
| | 718 | /* TODO: which space should we use? */ |
| | 719 | gegl_color_set_rgba_with_space (color, |
| | 720 | ps_color.rgb.red / 65535.0, |
| | 721 | ps_color.rgb.green / 65535.0, |
| | 722 | ps_color.rgb.blue / 65535.0, |
| | 723 | 1.0, NULL); |
| | 724 | break; |
| | 725 | |
| | 726 | case PSD_CS_HSB: |
| | 727 | { |
| | 728 | gfloat hsv[3] = |
| | 729 | { |
| | 730 | ps_color.hsv.hue / 65535.0f, |
| | 731 | ps_color.hsv.saturation / 65535.0f, |
| | 732 | ps_color.hsv.value / 65535.0f |
| | 733 | }; |
| | 734 | |
| | 735 | gegl_color_set_pixel (color, babl_format ("HSV float"), hsv); |
| | 736 | } |
| | 737 | break; |
| | 738 | |
| | 739 | case PSD_CS_CMYK: |
| | 740 | /* TODO: again, which space? */ |
| | 741 | gegl_color_set_cmyk (color, |
| | 742 | 1.0 - ps_color.cmyk.cyan / 65535.0, |
| | 743 | 1.0 - ps_color.cmyk.magenta / 65535.0, |
| | 744 | 1.0 - ps_color.cmyk.yellow / 65535.0, |
| | 745 | 1.0 - ps_color.cmyk.black / 65535.0, |
| | 746 | 1.0, NULL); |
| | 747 | break; |
| | 748 | |
| | 749 | case PSD_CS_GRAYSCALE: |
| | 750 | { |
| | 751 | gdouble gray = ps_color.gray.gray / 10000.0; |
| | 752 | |
| | 753 | /* TODO: which space? */ |
| | 754 | gegl_color_set_pixel (color, babl_format_with_space ("Y' double", NULL), &gray); |
| | 755 | } |
| | 756 | break; |
| | 757 | |
| | 758 | case PSD_CS_FOCOLTONE: |
| | 759 | case PSD_CS_TRUMATCH: |
| | 760 | case PSD_CS_HKS: |
| | 761 | case PSD_CS_LAB: |
| | 762 | case PSD_CS_PANTONE: |
| | 763 | case PSD_CS_TOYO: |
| | 764 | case PSD_CS_DIC: |
| | 765 | case PSD_CS_ANPA: |
| | 766 | default: |
| | 767 | if (CONVERSION_WARNINGS) |
| | 768 | g_message ("Unsupported color space: %d", |
| | 769 | dsp_info.colorSpace); |
| | 770 | } |
| | 771 | |
| | 772 | IFDBG(2) g_debug ("PS cSpace: %d, col: %d %d %d %d, opacity: %d, kind: %d", |
| | 773 | dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta, |
| | 774 | ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity, |
| | 775 | dsp_info.kind); |
| | 776 | |
| | 777 | IFDBG(2) g_debug ("cSpace: %d, opacity: %d, kind: %d", |
| | 778 | dsp_info.colorSpace, dsp_info.opacity, dsp_info.kind); |
| | 779 | |
| | 780 | img_a->alpha_display_info[cidx] = g_malloc0 (sizeof (PSDchanneldata)); |
| | 781 | img_a->alpha_display_info[cidx]->gimp_color = color; |
| | 782 | img_a->alpha_display_info[cidx]->opacity = dsp_info.opacity; |
| | 783 | img_a->alpha_display_info[cidx]->ps_kind = dsp_info.kind; |
| | 784 | img_a->alpha_display_info[cidx]->ps_cspace = dsp_info.colorSpace; |
| | 785 | img_a->alpha_display_info[cidx]->ps_color = ps_color; |
| | 786 | } |
| | 787 | |
| | 788 | return 0; |
| | 789 | } |
| | 790 | |
| | 791 | static gint |
| | 792 | load_resource_1008 (const PSDimageres *res_a, |
| | 793 | GimpImage *image, |
| | 794 | GInputStream *input, |
| | 795 | GError **error) |
| | 796 | { |
| | 797 | /* Load image caption */ |
| | 798 | GimpParasite *parasite; |
| | 799 | gchar *caption; |
| | 800 | gint32 read_len; |
| | 801 | gint32 write_len; |
| | 802 | |
| | 803 | IFDBG(2) g_debug ("Process image resource block: 1008: Caption"); |
| | 804 | caption = fread_pascal_string (&read_len, &write_len, 1, input, error); |
| | 805 | if (*error) |
| | 806 | return -1; |
| | 807 | |
| | 808 | IFDBG(3) g_debug ("Caption: %s", caption); |
| | 809 | parasite = gimp_parasite_new (GIMP_PARASITE_COMMENT, GIMP_PARASITE_PERSISTENT, |
| | 810 | write_len, caption); |
| | 811 | gimp_image_attach_parasite (image, parasite); |
| | 812 | gimp_parasite_free (parasite); |
| | 813 | g_free (caption); |
| | 814 | |
| | 815 | return 0; |
| | 816 | } |
| | 817 | |
| | 818 | static gint |
| | 819 | load_resource_1022 (const PSDimageres *res_a, |
| | 820 | GimpImage *image, |
| | 821 | PSDimage *img_a, |
| | 822 | GInputStream *input, |
| | 823 | GError **error) |
| | 824 | { |
| | 825 | /* Load quick mask info */ |
| | 826 | gboolean quick_mask_empty = TRUE; /* Quick mask initially empty */ |
| | 827 | |
| | 828 | IFDBG(2) g_debug ("Process image resource block: 1022: Quick Mask"); |
| | 829 | |
| | 830 | if (psd_read (input, &img_a->quick_mask_id, 2, error) < 2 || |
| | 831 | psd_read (input, &quick_mask_empty, 1, error) < 1) |
| | 832 | { |
| | 833 | psd_set_error (error); |
| | 834 | return -1; |
| | 835 | } |
| | 836 | img_a->quick_mask_id = GUINT16_FROM_BE (img_a->quick_mask_id); |
| | 837 | |
| | 838 | IFDBG(3) g_debug ("Quick mask channel: %d, empty: %d", |
| | 839 | img_a->quick_mask_id, |
| | 840 | quick_mask_empty); |
| | 841 | |
| | 842 | return 0; |
| | 843 | } |
| | 844 | |
| | 845 | static gint |
| | 846 | load_resource_1024 (const PSDimageres *res_a, |
| | 847 | GimpImage *image, |
| | 848 | PSDimage *img_a, |
| | 849 | GInputStream *input, |
| | 850 | GError **error) |
| | 851 | { |
| | 852 | /* Load image layer state - current active layer counting from bottom up */ |
| | 853 | IFDBG(2) g_debug ("Process image resource block: 1024: Layer State"); |
| | 854 | |
| | 855 | if (psd_read (input, &img_a->layer_state, 2, error) < 2) |
| | 856 | { |
| | 857 | psd_set_error (error); |
| | 858 | return -1; |
| | 859 | } |
| | 860 | img_a->layer_state = GUINT16_FROM_BE (img_a->layer_state); |
| | 861 | |
| | 862 | return 0; |
| | 863 | } |
| | 864 | |
| | 865 | static gint |
| | 866 | load_resource_1028 (const PSDimageres *res_a, |
| | 867 | GimpImage *image, |
| | 868 | GInputStream *input, |
| | 869 | GError **error) |
| | 870 | { |
| | 871 | /* Load IPTC data block */ |
| | 872 | |
| | 873 | #ifdef HAVE_IPTCDATA |
| | 874 | IptcData *iptc_data; |
| | 875 | guchar *iptc_buf; |
| | 876 | guint iptc_buf_len; |
| | 877 | #else |
| | 878 | gchar *name; |
| | 879 | #endif /* HAVE_IPTCDATA */ |
| | 880 | |
| | 881 | GimpParasite *parasite; |
| | 882 | gchar *res_data; |
| | 883 | |
| | 884 | IFDBG(2) g_debug ("Process image resource block: 1028: IPTC data"); |
| | 885 | |
| | 886 | res_data = g_malloc (res_a->data_len); |
| | 887 | if (psd_read (input, res_data, res_a->data_len, error) < res_a->data_len) |
| | 888 | { |
| | 889 | psd_set_error (error); |
| | 890 | g_free (res_data); |
| | 891 | return -1; |
| | 892 | } |
| | 893 | |
| | 894 | #ifdef HAVE_IPTCDATA |
| | 895 | /* Load IPTC data structure */ |
| | 896 | iptc_data = iptc_data_new_from_data (res_data, res_a->data_len); |
| | 897 | IFDBG (3) iptc_data_dump (iptc_data, 0); |
| | 898 | |
| | 899 | /* Store resource data as a GIMP IPTC parasite */ |
| | 900 | IFDBG (2) g_debug ("Processing IPTC data as GIMP IPTC parasite"); |
| | 901 | /* Serialize IPTC data */ |
| | 902 | iptc_data_save (iptc_data, &iptc_buf, &iptc_buf_len); |
| | 903 | if (iptc_buf_len > 0) |
| | 904 | { |
| | 905 | parasite = gimp_parasite_new (GIMP_PARASITE_IPTC, |
| | 906 | GIMP_PARASITE_PERSISTENT, |
| | 907 | iptc_buf_len, iptc_buf); |
| | 908 | gimp_image_attach_parasite (image, parasite); |
| | 909 | gimp_parasite_free (parasite); |
| | 910 | } |
| | 911 | |
| | 912 | iptc_data_unref (iptc_data); |
| | 913 | g_free (iptc_buf); |
| | 914 | |
| | 915 | #else |
| | 916 | /* Store resource data as a standard psd parasite */ |
| | 917 | IFDBG (2) g_debug ("Processing IPTC data as psd parasite"); |
| | 918 | name = g_strdup_printf ("psd-image-resource-%.4s-%.4x", |
| | 919 | res_a->type, res_a->id); |
| | 920 | IFDBG(3) g_debug ("Parasite name: %s", name); |
| | 921 | |
| | 922 | parasite = gimp_parasite_new (name, 0, res_a->data_len, res_data); |
| | 923 | gimp_image_attach_parasite (image, parasite); |
| | 924 | gimp_parasite_free (parasite); |
| | 925 | g_free (name); |
| | 926 | |
| | 927 | #endif /* HAVE_IPTCDATA */ |
| | 928 | |
| | 929 | g_free (res_data); |
| | 930 | return 0; |
| | 931 | } |
| | 932 | |
| | 933 | static gint |
| | 934 | load_resource_1032 (const PSDimageres *res_a, |
| | 935 | GimpImage *image, |
| | 936 | GInputStream *input, |
| | 937 | GError **error) |
| | 938 | { |
| | 939 | /* Load grid and guides */ |
| | 940 | |
| | 941 | /* Grid info is not used (CS2 or earlier) */ |
| | 942 | |
| | 943 | GuideHeader hdr; |
| | 944 | GuideResource guide; |
| | 945 | gint i; |
| | 946 | |
| | 947 | IFDBG(2) g_debug ("Process image resource block 1032: Grid and Guide Info"); |
| | 948 | |
| | 949 | if (psd_read (input, &hdr.fVersion, 4, error) < 4 || |
| | 950 | psd_read (input, &hdr.fGridCycleV, 4, error) < 4 || |
| | 951 | psd_read (input, &hdr.fGridCycleH, 4, error) < 4 || |
| | 952 | psd_read (input, &hdr.fGuideCount, 4, error) < 4) |
| | 953 | { |
| | 954 | psd_set_error (error); |
| | 955 | return -1; |
| | 956 | } |
| | 957 | hdr.fVersion = GUINT32_FROM_BE (hdr.fVersion); |
| | 958 | hdr.fGridCycleV = GUINT32_FROM_BE (hdr.fGridCycleV); |
| | 959 | hdr.fGridCycleH = GUINT32_FROM_BE (hdr.fGridCycleH); |
| | 960 | hdr.fGuideCount = GUINT32_FROM_BE (hdr.fGuideCount); |
| | 961 | |
| | 962 | IFDBG(3) g_debug ("Grids & Guides: %d, %d, %d, %d", |
| | 963 | hdr.fVersion, |
| | 964 | hdr.fGridCycleV, |
| | 965 | hdr.fGridCycleH, |
| | 966 | hdr.fGuideCount); |
| | 967 | |
| | 968 | for (i = 0; i < hdr.fGuideCount; ++i) |
| | 969 | { |
| | 970 | if (psd_read (input, &guide.fLocation, 4, error) < 4 || |
| | 971 | psd_read (input, &guide.fDirection, 1, error) < 1) |
| | 972 | { |
| | 973 | psd_set_error (error); |
| | 974 | return -1; |
| | 975 | } |
| | 976 | guide.fLocation = GUINT32_FROM_BE (guide.fLocation); |
| | 977 | guide.fLocation /= 32; |
| | 978 | |
| | 979 | IFDBG(3) g_debug ("Guide: %d px, %d", |
| | 980 | guide.fLocation, |
| | 981 | guide.fDirection); |
| | 982 | |
| | 983 | if (guide.fDirection == PSD_VERTICAL) |
| | 984 | gimp_image_add_vguide (image, guide.fLocation); |
| | 985 | else |
| | 986 | gimp_image_add_hguide (image, guide.fLocation); |
| | 987 | } |
| | 988 | |
| | 989 | return 0; |
| | 990 | } |
| | 991 | |
| | 992 | static gint |
| | 993 | load_resource_1033 (const PSDimageres *res_a, |
| | 994 | GimpImage *image, |
| | 995 | GFile *file, |
| | 996 | GInputStream *input, |
| | 997 | GError **error) |
| | 998 | { |
| | 999 | /* Load thumbnail image */ |
| | 1000 | |
| | 1001 | struct jpeg_decompress_struct cinfo; |
| | 1002 | struct jpeg_error_mgr jerr; |
| | 1003 | |
| | 1004 | FILE *f; |
| | 1005 | ThumbnailInfo thumb_info; |
| | 1006 | GeglBuffer *buffer; |
| | 1007 | const Babl *format; |
| | 1008 | GimpLayer *layer; |
| | 1009 | guchar *buf; |
| | 1010 | guchar *rgb_buf; |
| | 1011 | guchar **rowbuf; |
| | 1012 | gint i; |
| | 1013 | |
| | 1014 | IFDBG(2) g_debug ("Process image resource block %d: Thumbnail Image", res_a->id); |
| | 1015 | |
| | 1016 | /* Read thumbnail resource header info */ |
| | 1017 | if (psd_read (input, &thumb_info.format, 4, error) < 4 || |
| | 1018 | psd_read (input, &thumb_info.width, 4, error) < 4 || |
| | 1019 | psd_read (input, &thumb_info.height, 4, error) < 4 || |
| | 1020 | psd_read (input, &thumb_info.widthbytes, 4, error) < 4 || |
| | 1021 | psd_read (input, &thumb_info.size, 4, error) < 4 || |
| | 1022 | psd_read (input, &thumb_info.compressedsize, 4, error) < 4 || |
| | 1023 | psd_read (input, &thumb_info.bitspixel, 2, error) < 2 || |
| | 1024 | psd_read (input, &thumb_info.planes, 2, error) < 2) |
| | 1025 | { |
| | 1026 | psd_set_error (error); |
| | 1027 | return -1; |
| | 1028 | } |
| | 1029 | thumb_info.format = GINT32_FROM_BE (thumb_info.format); |
| | 1030 | thumb_info.width = GINT32_FROM_BE (thumb_info.width); |
| | 1031 | thumb_info.height = GINT32_FROM_BE (thumb_info.height); |
| | 1032 | thumb_info.widthbytes = GINT32_FROM_BE (thumb_info.widthbytes); |
| | 1033 | thumb_info.size = GINT32_FROM_BE (thumb_info.size); |
| | 1034 | thumb_info.compressedsize = GINT32_FROM_BE (thumb_info.compressedsize); |
| | 1035 | thumb_info.bitspixel = GINT16_FROM_BE (thumb_info.bitspixel); |
| | 1036 | thumb_info.planes = GINT16_FROM_BE (thumb_info.planes); |
| | 1037 | |
| | 1038 | IFDBG(2) g_debug ("\nThumbnail:\n" |
| | 1039 | "\tFormat: %d\n" |
| | 1040 | "\tDimensions: %d x %d\n", |
| | 1041 | thumb_info.format, |
| | 1042 | thumb_info.width, |
| | 1043 | thumb_info.height); |
| | 1044 | |
| | 1045 | if (thumb_info.format != 1) |
| | 1046 | { |
| | 1047 | IFDBG(1) g_debug ("Unknown thumbnail format %d", thumb_info.format); |
| | 1048 | return -1; |
| | 1049 | } |
| | 1050 | |
| | 1051 | /* Load Jpeg RGB thumbnail info */ |
| | 1052 | |
| | 1053 | /* Open input also as a FILE. */ |
| | 1054 | f = g_fopen (g_file_peek_path (file), "rb"); |
| | 1055 | |
| | 1056 | if (! f) |
| | 1057 | return -1; |
| | 1058 | |
| | 1059 | /* Now seek to the same position as we have in input. */ |
| | 1060 | fseek(f, g_seekable_tell (G_SEEKABLE (input)), SEEK_SET); |
| | 1061 | |
| | 1062 | /* Step 1: Allocate and initialize JPEG decompression object */ |
| | 1063 | cinfo.err = jpeg_std_error (&jerr); |
| | 1064 | jpeg_create_decompress (&cinfo); |
| | 1065 | |
| | 1066 | /* Step 2: specify data source (eg, a file) */ |
| | 1067 | jpeg_stdio_src(&cinfo, f); |
| | 1068 | |
| | 1069 | /* Step 3: read file parameters with jpeg_read_header() */ |
| | 1070 | jpeg_read_header (&cinfo, TRUE); |
| | 1071 | |
| | 1072 | /* Step 4: set parameters for decompression */ |
| | 1073 | |
| | 1074 | |
| | 1075 | /* Step 5: Start decompressor */ |
| | 1076 | jpeg_start_decompress (&cinfo); |
| | 1077 | |
| | 1078 | /* temporary buffers */ |
| | 1079 | buf = g_new (guchar, cinfo.output_height * cinfo.output_width |
| | 1080 | * cinfo.output_components); |
| | 1081 | if (res_a->id == PSD_THUMB_RES) |
| | 1082 | rgb_buf = g_new (guchar, cinfo.output_height * cinfo.output_width |
| | 1083 | * cinfo.output_components); |
| | 1084 | else |
| | 1085 | rgb_buf = NULL; |
| | 1086 | rowbuf = g_new (guchar *, cinfo.output_height); |
| | 1087 | |
| | 1088 | for (i = 0; i < cinfo.output_height; ++i) |
| | 1089 | rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i; |
| | 1090 | |
| | 1091 | /* Create image layer */ |
| | 1092 | gimp_image_resize (image, cinfo.output_width, cinfo.output_height, 0, 0); |
| | 1093 | layer = gimp_layer_new (image, _("Background"), |
| | 1094 | cinfo.output_width, |
| | 1095 | cinfo.output_height, |
| | 1096 | GIMP_RGB_IMAGE, |
| | 1097 | 100, |
| | 1098 | gimp_image_get_default_new_layer_mode (image)); |
| | 1099 | buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)); |
| | 1100 | format = babl_format ("R'G'B' u8"); |
| | 1101 | |
| | 1102 | /* Step 6: while (scan lines remain to be read) */ |
| | 1103 | /* jpeg_read_scanlines(...); */ |
| | 1104 | while (cinfo.output_scanline < cinfo.output_height) |
| | 1105 | { |
| | 1106 | jpeg_read_scanlines (&cinfo, |
| | 1107 | (JSAMPARRAY) &rowbuf[cinfo.output_scanline], 1); |
| | 1108 | } |
| | 1109 | |
| | 1110 | if (res_a->id == PSD_THUMB_RES) /* Order is BGR for resource 1033 */ |
| | 1111 | { |
| | 1112 | guchar *dst = rgb_buf; |
| | 1113 | guchar *src = buf; |
| | 1114 | |
| | 1115 | for (i = 0; i < gegl_buffer_get_width (buffer) * gegl_buffer_get_height (buffer); ++i) |
| | 1116 | { |
| | 1117 | guchar r, g, b; |
| | 1118 | |
| | 1119 | r = *(src++); |
| | 1120 | g = *(src++); |
| | 1121 | b = *(src++); |
| | 1122 | *(dst++) = b; |
| | 1123 | *(dst++) = g; |
| | 1124 | *(dst++) = r; |
| | 1125 | } |
| | 1126 | } |
| | 1127 | |
| | 1128 | gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, |
| | 1129 | gegl_buffer_get_width (buffer), |
| | 1130 | gegl_buffer_get_height (buffer)), |
| | 1131 | 0, format, rgb_buf ? rgb_buf : buf, GEGL_AUTO_ROWSTRIDE); |
| | 1132 | |
| | 1133 | /* Step 7: Finish decompression */ |
| | 1134 | jpeg_finish_decompress (&cinfo); |
| | 1135 | /* We can ignore the return value since suspension is not possible |
| | 1136 | * with the stdio data source. |
| | 1137 | */ |
| | 1138 | |
| | 1139 | /* Step 8: Release JPEG decompression object */ |
| | 1140 | jpeg_destroy_decompress (&cinfo); |
| | 1141 | |
| | 1142 | /* free up the temporary buffers */ |
| | 1143 | g_free (rowbuf); |
| | 1144 | g_free (buf); |
| | 1145 | g_free (rgb_buf); |
| | 1146 | |
| | 1147 | /* Close FILE */ |
| | 1148 | fclose (f); |
| | 1149 | |
| | 1150 | /* At this point you may want to check to see whether any |
| | 1151 | * corrupt-data warnings occurred (test whether |
| | 1152 | * jerr.num_warnings is nonzero). |
| | 1153 | */ |
| | 1154 | gimp_image_insert_layer (image, layer, NULL, 0); |
| | 1155 | g_object_unref (buffer); |
| | 1156 | |
| | 1157 | return 0; |
| | 1158 | } |
| | 1159 | |
| | 1160 | static gint |
| | 1161 | load_resource_1039 (const PSDimageres *res_a, |
| | 1162 | PSDimage *img_a, |
| | 1163 | GimpImage *image, |
| | 1164 | GInputStream *input, |
| | 1165 | GError **error) |
| | 1166 | { |
| | 1167 | /* Load ICC profile */ |
| | 1168 | GimpColorProfile *profile; |
| | 1169 | gchar *icc_profile; |
| | 1170 | |
| | 1171 | IFDBG(2) g_debug ("Process image resource block: 1039: ICC Profile"); |
| | 1172 | |
| | 1173 | icc_profile = g_malloc (res_a->data_len); |
| | 1174 | if (psd_read (input, icc_profile, res_a->data_len, error) < res_a->data_len) |
| | 1175 | { |
| | 1176 | psd_set_error (error); |
| | 1177 | g_free (icc_profile); |
| | 1178 | return -1; |
| | 1179 | } |
| | 1180 | |
| | 1181 | profile = gimp_color_profile_new_from_icc_profile ((guint8 *) icc_profile, |
| | 1182 | res_a->data_len, |
| | 1183 | NULL); |
| | 1184 | if (profile) |
| | 1185 | { |
| | 1186 | if (img_a->color_mode == PSD_CMYK && |
| | 1187 | gimp_color_profile_is_cmyk (profile)) |
| | 1188 | { |
| | 1189 | img_a->cmyk_profile = profile; |
| | 1190 | /* Store CMYK profile in GimpImage if attached */ |
| | 1191 | gimp_image_set_simulation_profile (image, img_a->cmyk_profile); |
| | 1192 | } |
| | 1193 | else if (img_a->color_mode == PSD_LAB) |
| | 1194 | { |
| | 1195 | g_debug ("LAB color profile ignored."); |
| | 1196 | g_object_unref (profile); |
| | 1197 | } |
| | 1198 | else |
| | 1199 | { |
| | 1200 | gimp_image_set_color_profile (image, profile); |
| | 1201 | g_object_unref (profile); |
| | 1202 | } |
| | 1203 | } |
| | 1204 | |
| | 1205 | g_free (icc_profile); |
| | 1206 | |
| | 1207 | return 0; |
| | 1208 | } |
| | 1209 | |
| | 1210 | static gint |
| | 1211 | load_resource_1045 (const PSDimageres *res_a, |
| | 1212 | GimpImage *image, |
| | 1213 | PSDimage *img_a, |
| | 1214 | GInputStream *input, |
| | 1215 | GError **error) |
| | 1216 | { |
| | 1217 | /* Load alpha channel names stored as a series of unicode strings |
| | 1218 | in a GPtrArray */ |
| | 1219 | |
| | 1220 | gchar *str; |
| | 1221 | gint32 block_rem; |
| | 1222 | gint32 read_len; |
| | 1223 | gint32 write_len; |
| | 1224 | |
| | 1225 | IFDBG(2) g_debug ("Process image resource block 1045: Unicode Alpha Channel Names"); |
| | 1226 | |
| | 1227 | if (img_a->alpha_names) |
| | 1228 | { |
| | 1229 | gint i; |
| | 1230 | IFDBG(3) g_debug ("Deleting localised alpha channel names"); |
| | 1231 | for (i = 0; i < img_a->alpha_names->len; ++i) |
| | 1232 | { |
| | 1233 | str = g_ptr_array_index (img_a->alpha_names, i); |
| | 1234 | g_free (str); |
| | 1235 | } |
| | 1236 | g_ptr_array_free (img_a->alpha_names, TRUE); |
| | 1237 | } |
| | 1238 | |
| | 1239 | img_a->alpha_names = g_ptr_array_new (); |
| | 1240 | |
| | 1241 | block_rem = res_a->data_len; |
| | 1242 | while (block_rem > 1) |
| | 1243 | { |
| | 1244 | str = fread_unicode_string (&read_len, &write_len, 1, FALSE, input, |
| | 1245 | error); |
| | 1246 | if (*error) |
| | 1247 | return -1; |
| | 1248 | |
| | 1249 | IFDBG(3) g_debug ("String: %s, %d, %d", str, read_len, write_len); |
| | 1250 | if (write_len >= 0) |
| | 1251 | { |
| | 1252 | g_ptr_array_add (img_a->alpha_names, (gpointer) str); |
| | 1253 | } |
| | 1254 | block_rem -= read_len; |
| | 1255 | } |
| | 1256 | |
| | 1257 | return 0; |
| | 1258 | } |
| | 1259 | |
| | 1260 | static gint |
| | 1261 | load_resource_1046 (const PSDimageres *res_a, |
| | 1262 | GimpImage *image, |
| | 1263 | GInputStream *input, |
| | 1264 | GError **error) |
| | 1265 | { |
| | 1266 | /* Load indexed color table count */ |
| | 1267 | gint16 index_count = 0; |
| | 1268 | |
| | 1269 | IFDBG(2) g_debug ("Process image resource block: 1046: Indexed Color Table Count"); |
| | 1270 | |
| | 1271 | if (psd_read (input, &index_count, 2, error) < 2) |
| | 1272 | { |
| | 1273 | psd_set_error (error); |
| | 1274 | return -1; |
| | 1275 | } |
| | 1276 | index_count = GINT16_FROM_BE (index_count); |
| | 1277 | |
| | 1278 | IFDBG(3) g_debug ("Indexed color table count: %d", index_count); |
| | 1279 | /* FIXME - check that we have indexed image */ |
| | 1280 | if (index_count && index_count < 256) |
| | 1281 | { |
| | 1282 | GimpPalette *palette; |
| | 1283 | |
| | 1284 | palette = gimp_image_get_palette (image); |
| | 1285 | if (palette) |
| | 1286 | while (index_count < gimp_palette_get_color_count (palette)) |
| | 1287 | gimp_palette_delete_entry (palette, index_count); |
| | 1288 | } |
| | 1289 | return 0; |
| | 1290 | } |
| | 1291 | |
| | 1292 | static gint |
| | 1293 | load_resource_1053 (const PSDimageres *res_a, |
| | 1294 | GimpImage *image, |
| | 1295 | PSDimage *img_a, |
| | 1296 | GInputStream *input, |
| | 1297 | GError **error) |
| | 1298 | { |
| | 1299 | /* Load image alpha channel ids (tattoos) */ |
| | 1300 | gint16 tot_rec; |
| | 1301 | gint16 cidx; |
| | 1302 | |
| | 1303 | IFDBG(2) g_debug ("Process image resource block: 1053: Channel ID"); |
| | 1304 | |
| | 1305 | tot_rec = res_a->data_len / 4; |
| | 1306 | if (tot_rec ==0) |
| | 1307 | return 0; |
| | 1308 | |
| | 1309 | img_a->alpha_id = g_malloc (sizeof (img_a->alpha_id) * tot_rec); |
| | 1310 | img_a->alpha_id_count = tot_rec; |
| | 1311 | for (cidx = 0; cidx < tot_rec; ++cidx) |
| | 1312 | { |
| | 1313 | if (psd_read (input, &img_a->alpha_id[cidx], 4, error) < 4) |
| | 1314 | { |
| | 1315 | psd_set_error (error); |
| | 1316 | return -1; |
| | 1317 | } |
| | 1318 | img_a->alpha_id[cidx] = GUINT32_FROM_BE (img_a->alpha_id[cidx]); |
| | 1319 | |
| | 1320 | IFDBG(3) g_debug ("Channel id: %d", img_a->alpha_id[cidx]); |
| | 1321 | } |
| | 1322 | |
| | 1323 | return 0; |
| | 1324 | } |
| | 1325 | |
| | 1326 | static gint |
| | 1327 | load_resource_1058 (const PSDimageres *res_a, |
| | 1328 | GimpImage *image, |
| | 1329 | GInputStream *input, |
| | 1330 | GError **error) |
| | 1331 | { |
| | 1332 | gchar *name; |
| | 1333 | |
| | 1334 | GimpParasite *parasite; |
| | 1335 | gchar *res_data; |
| | 1336 | |
| | 1337 | IFDBG(2) g_debug ("Process image resource block: 1058: Exif data"); |
| | 1338 | |
| | 1339 | res_data = g_malloc (res_a->data_len); |
| | 1340 | if (psd_read (input, res_data, res_a->data_len, error) < res_a->data_len) |
| | 1341 | { |
| | 1342 | psd_set_error (error); |
| | 1343 | g_free (res_data); |
| | 1344 | return -1; |
| | 1345 | } |
| | 1346 | |
| | 1347 | /* Store resource data as a standard psd parasite */ |
| | 1348 | IFDBG (2) g_debug ("Processing exif data as psd parasite"); |
| | 1349 | name = g_strdup_printf ("psd-image-resource-%.4s-%.4x", |
| | 1350 | res_a->type, res_a->id); |
| | 1351 | IFDBG(3) g_debug ("Parasite name: %s", name); |
| | 1352 | |
| | 1353 | parasite = gimp_parasite_new (name, 0, res_a->data_len, res_data); |
| | 1354 | gimp_image_attach_parasite (image, parasite); |
| | 1355 | gimp_parasite_free (parasite); |
| | 1356 | g_free (name); |
| | 1357 | |
| | 1358 | g_free (res_data); |
| | 1359 | return 0; |
| | 1360 | } |
| | 1361 | |
| | 1362 | static gint |
| | 1363 | load_resource_1069 (const PSDimageres *res_a, |
| | 1364 | GimpImage *image, |
| | 1365 | PSDimage *img_a, |
| | 1366 | GInputStream *input, |
| | 1367 | GError **error) |
| | 1368 | { |
| | 1369 | guint16 layer_count = 0; |
| | 1370 | gint i; |
| | 1371 | |
| | 1372 | IFDBG(2) g_debug ("Process image resource block: 1069: Layer Selection ID(s)"); |
| | 1373 | |
| | 1374 | if (psd_read (input, &layer_count, 2, error) < 2) |
| | 1375 | { |
| | 1376 | psd_set_error (error); |
| | 1377 | return -1; |
| | 1378 | } |
| | 1379 | layer_count = GUINT16_FROM_BE (layer_count); |
| | 1380 | |
| | 1381 | /* This should probably not happen, but just in case the block is |
| | 1382 | * duplicated, let's just free the previous selection. |
| | 1383 | */ |
| | 1384 | g_list_free (img_a->layer_selection); |
| | 1385 | img_a->layer_selection = NULL; |
| | 1386 | |
| | 1387 | for (i = 0; i < layer_count; i++) |
| | 1388 | { |
| | 1389 | guint32 layer_id = 0; |
| | 1390 | |
| | 1391 | if (psd_read (input, &layer_id, 4, error) < 4) |
| | 1392 | { |
| | 1393 | psd_set_error (error); |
| | 1394 | return -1; |
| | 1395 | } |
| | 1396 | layer_id = GUINT32_FROM_BE (layer_id); |
| | 1397 | img_a->layer_selection = g_list_prepend (img_a->layer_selection, GINT_TO_POINTER (layer_id)); |
| | 1398 | } |
| | 1399 | |
| | 1400 | return 0; |
| | 1401 | } |
| | 1402 | |
| | 1403 | static gint |
| | 1404 | load_resource_1077 (const PSDimageres *res_a, |
| | 1405 | GimpImage *image, |
| | 1406 | PSDimage *img_a, |
| | 1407 | GInputStream *input, |
| | 1408 | GError **error) |
| | 1409 | { |
| | 1410 | /* Load alpha channel display info */ |
| | 1411 | |
| | 1412 | DisplayInfoNew dsp_info; |
| | 1413 | CMColor ps_color; |
| | 1414 | gint16 tot_rec; |
| | 1415 | gint cidx; |
| | 1416 | |
| | 1417 | IFDBG(2) g_debug ("Process image resource block 1077: Display Info New"); |
| | 1418 | |
| | 1419 | /* For now, skip first 4 bytes since intention is unclear. Seems to be |
| | 1420 | a version number that is always one, but who knows. */ |
| | 1421 | if (! psd_seek (input, 4, G_SEEK_CUR, error)) |
| | 1422 | return -1; |
| | 1423 | |
| | 1424 | tot_rec = res_a->data_len / 13; |
| | 1425 | if (tot_rec == 0) |
| | 1426 | return 0; |
| | 1427 | |
| | 1428 | img_a->alpha_display_info = g_new (PSDchanneldata *, tot_rec); |
| | 1429 | img_a->alpha_display_count = tot_rec; |
| | 1430 | for (cidx = 0; cidx < tot_rec; ++cidx) |
| | 1431 | { |
| | 1432 | GeglColor *color; |
| | 1433 | |
| | 1434 | if (psd_read (input, &dsp_info.colorSpace, 2, error) < 2 || |
| | 1435 | psd_read (input, &dsp_info.color, 8, error) < 8 || |
| | 1436 | psd_read (input, &dsp_info.opacity, 2, error) < 2 || |
| | 1437 | psd_read (input, &dsp_info.mode, 1, error) < 1) |
| | 1438 | { |
| | 1439 | psd_set_error (error); |
| | 1440 | return -1; |
| | 1441 | } |
| | 1442 | dsp_info.colorSpace = GINT16_FROM_BE (dsp_info.colorSpace); |
| | 1443 | ps_color.cmyk.cyan = GUINT16_FROM_BE (dsp_info.color[0]); |
| | 1444 | ps_color.cmyk.magenta = GUINT16_FROM_BE (dsp_info.color[1]); |
| | 1445 | ps_color.cmyk.yellow = GUINT16_FROM_BE (dsp_info.color[2]); |
| | 1446 | ps_color.cmyk.black = GUINT16_FROM_BE (dsp_info.color[3]); |
| | 1447 | dsp_info.opacity = GINT16_FROM_BE (dsp_info.opacity); |
| | 1448 | |
| | 1449 | color = gegl_color_new ("red"); |
| | 1450 | |
| | 1451 | switch (dsp_info.colorSpace) |
| | 1452 | { |
| | 1453 | case PSD_CS_RGB: |
| | 1454 | /* TODO: which space? */ |
| | 1455 | gegl_color_set_rgba_with_space (color, |
| | 1456 | ps_color.rgb.red / 65535.0, |
| | 1457 | ps_color.rgb.green / 65535.0, |
| | 1458 | ps_color.rgb.blue / 65535.0, |
| | 1459 | 1.0, NULL); |
| | 1460 | break; |
| | 1461 | |
| | 1462 | case PSD_CS_HSB: |
| | 1463 | { |
| | 1464 | gfloat hsv[3] = |
| | 1465 | { |
| | 1466 | ps_color.hsv.hue / 65535.0f, |
| | 1467 | ps_color.hsv.saturation / 65535.0f, |
| | 1468 | ps_color.hsv.value / 65535.0f |
| | 1469 | }; |
| | 1470 | |
| | 1471 | gegl_color_set_pixel (color, babl_format ("HSV float"), hsv); |
| | 1472 | } |
| | 1473 | break; |
| | 1474 | |
| | 1475 | case PSD_CS_CMYK: |
| | 1476 | /* TODO: which space? */ |
| | 1477 | gegl_color_set_cmyk (color, |
| | 1478 | 1.0 - ps_color.cmyk.cyan / 65535.0, |
| | 1479 | 1.0 - ps_color.cmyk.magenta / 65535.0, |
| | 1480 | 1.0 - ps_color.cmyk.yellow / 65535.0, |
| | 1481 | 1.0 - ps_color.cmyk.black / 65535.0, |
| | 1482 | 1.0, NULL); |
| | 1483 | break; |
| | 1484 | |
| | 1485 | case PSD_CS_GRAYSCALE: |
| | 1486 | { |
| | 1487 | gdouble gray = ps_color.gray.gray / 10000.0; |
| | 1488 | |
| | 1489 | /* TODO: which space? */ |
| | 1490 | gegl_color_set_pixel (color, babl_format_with_space ("Y' double", NULL), &gray); |
| | 1491 | } |
| | 1492 | break; |
| | 1493 | |
| | 1494 | case PSD_CS_FOCOLTONE: |
| | 1495 | case PSD_CS_TRUMATCH: |
| | 1496 | case PSD_CS_HKS: |
| | 1497 | case PSD_CS_LAB: |
| | 1498 | case PSD_CS_PANTONE: |
| | 1499 | case PSD_CS_TOYO: |
| | 1500 | case PSD_CS_DIC: |
| | 1501 | case PSD_CS_ANPA: |
| | 1502 | default: |
| | 1503 | if (CONVERSION_WARNINGS) |
| | 1504 | g_message ("Unsupported color space: %d", |
| | 1505 | dsp_info.colorSpace); |
| | 1506 | } |
| | 1507 | |
| | 1508 | IFDBG(2) g_debug ("PS cSpace: %d, col: %d %d %d %d, opacity: %d, mode: %d", |
| | 1509 | dsp_info.colorSpace, ps_color.cmyk.cyan, ps_color.cmyk.magenta, |
| | 1510 | ps_color.cmyk.yellow, ps_color.cmyk.black, dsp_info.opacity, |
| | 1511 | dsp_info.mode); |
| | 1512 | |
| | 1513 | IFDBG(2) g_debug ("cSpace: %d, opacity: %d, mode: %d", |
| | 1514 | dsp_info.colorSpace, dsp_info.opacity, dsp_info.mode); |
| | 1515 | |
| | 1516 | img_a->alpha_display_info[cidx] = g_malloc0 (sizeof (PSDchanneldata)); |
| | 1517 | img_a->alpha_display_info[cidx]->gimp_color = color; |
| | 1518 | img_a->alpha_display_info[cidx]->opacity = dsp_info.opacity; |
| | 1519 | img_a->alpha_display_info[cidx]->ps_mode = dsp_info.mode; |
| | 1520 | img_a->alpha_display_info[cidx]->ps_cspace = dsp_info.colorSpace; |
| | 1521 | img_a->alpha_display_info[cidx]->ps_color = ps_color; |
| | 1522 | } |
| | 1523 | |
| | 1524 | return 0; |
| | 1525 | } |
| | 1526 | |
| | 1527 | static gint |
| | 1528 | load_resource_2000 (const PSDimageres *res_a, |
| | 1529 | GimpImage *image, |
| | 1530 | GInputStream *input, |
| | 1531 | GError **error) |
| | 1532 | { |
| | 1533 | gdouble *controlpoints; |
| | 1534 | gint32 x[3]; |
| | 1535 | gint32 y[3]; |
| | 1536 | GimpPath *path = NULL; |
| | 1537 | gint16 type = 0; |
| | 1538 | gint16 init_fill; |
| | 1539 | gint16 num_rec; |
| | 1540 | gint16 path_rec; |
| | 1541 | gint16 cntr; |
| | 1542 | gint image_width; |
| | 1543 | gint image_height; |
| | 1544 | gint i; |
| | 1545 | gboolean closed; |
| | 1546 | |
| | 1547 | /* Load path data from image resources 2000-2998 */ |
| | 1548 | |
| | 1549 | IFDBG(2) g_debug ("Process image resource block: %d :Path data", res_a->id); |
| | 1550 | path_rec = res_a->data_len / 26; |
| | 1551 | if (path_rec ==0) |
| | 1552 | return 0; |
| | 1553 | |
| | 1554 | if (psd_read (input, &type, 2, error) < 2) |
| | 1555 | { |
| | 1556 | psd_set_error (error); |
| | 1557 | return -1; |
| | 1558 | } |
| | 1559 | type = GINT16_FROM_BE (type); |
| | 1560 | if (type != PSD_PATH_FILL_RULE) |
| | 1561 | { |
| | 1562 | IFDBG(1) g_debug ("Unexpected path record type: %d", type); |
| | 1563 | return -1; |
| | 1564 | } |
| | 1565 | |
| | 1566 | if (! psd_seek (input, 24, G_SEEK_CUR, error)) |
| | 1567 | { |
| | 1568 | psd_set_error (error); |
| | 1569 | return -1; |
| | 1570 | } |
| | 1571 | |
| | 1572 | path_rec--; |
| | 1573 | if (path_rec ==0) |
| | 1574 | return 0; |
| | 1575 | |
| | 1576 | image_width = gimp_image_get_width (image); |
| | 1577 | image_height = gimp_image_get_height (image); |
| | 1578 | |
| | 1579 | /* Create path */ |
| | 1580 | if (res_a->id == PSD_WORKING_PATH) |
| | 1581 | { |
| | 1582 | /* use "Working Path" for the path name to match the Photoshop display */ |
| | 1583 | path = gimp_path_new (image, "Working Path"); |
| | 1584 | } |
| | 1585 | else |
| | 1586 | { |
| | 1587 | /* Use the name stored in the PSD to name the path */ |
| | 1588 | path = gimp_path_new (image, res_a->name); |
| | 1589 | } |
| | 1590 | |
| | 1591 | gimp_image_insert_path (image, path, NULL, -1); |
| | 1592 | |
| | 1593 | while (path_rec > 0) |
| | 1594 | { |
| | 1595 | if (psd_read (input, &type, 2, error) < 2) |
| | 1596 | { |
| | 1597 | psd_set_error (error); |
| | 1598 | return -1; |
| | 1599 | } |
| | 1600 | type = GINT16_FROM_BE (type); |
| | 1601 | IFDBG(3) g_debug ("Path record type %d", type); |
| | 1602 | |
| | 1603 | if (type == PSD_PATH_FILL_RULE) |
| | 1604 | { |
| | 1605 | if (! psd_seek (input, 24, G_SEEK_CUR, error)) |
| | 1606 | { |
| | 1607 | psd_set_error (error); |
| | 1608 | return -1; |
| | 1609 | } |
| | 1610 | } |
| | 1611 | |
| | 1612 | else if (type == PSD_PATH_FILL_INIT) |
| | 1613 | { |
| | 1614 | if (psd_read (input, &init_fill, 2, error) < 2) |
| | 1615 | { |
| | 1616 | psd_set_error (error); |
| | 1617 | return -1; |
| | 1618 | } |
| | 1619 | |
| | 1620 | if (! psd_seek (input, 22, G_SEEK_CUR, error)) |
| | 1621 | { |
| | 1622 | psd_set_error (error); |
| | 1623 | return -1; |
| | 1624 | } |
| | 1625 | } |
| | 1626 | |
| | 1627 | else if (type == PSD_PATH_CL_LEN |
| | 1628 | || type == PSD_PATH_OP_LEN) |
| | 1629 | { |
| | 1630 | if (psd_read (input, &num_rec, 2, error) < 2) |
| | 1631 | { |
| | 1632 | psd_set_error (error); |
| | 1633 | return -1; |
| | 1634 | } |
| | 1635 | num_rec = GINT16_FROM_BE (num_rec); |
| | 1636 | IFDBG(3) g_debug ("Num path records %d", num_rec); |
| | 1637 | if (num_rec > path_rec) |
| | 1638 | { |
| | 1639 | psd_set_error (error); |
| | 1640 | return - 1; |
| | 1641 | } |
| | 1642 | |
| | 1643 | if (type == PSD_PATH_CL_LEN) |
| | 1644 | closed = TRUE; |
| | 1645 | else |
| | 1646 | closed = FALSE; |
| | 1647 | cntr = 0; |
| | 1648 | controlpoints = g_malloc (sizeof (gdouble) * num_rec * 6); |
| | 1649 | if (! psd_seek (input, 22, G_SEEK_CUR, error)) |
| | 1650 | { |
| | 1651 | psd_set_error (error); |
| | 1652 | g_free (controlpoints); |
| | 1653 | return -1; |
| | 1654 | } |
| | 1655 | |
| | 1656 | while (num_rec > 0) |
| | 1657 | { |
| | 1658 | if (psd_read (input, &type, 2, error) < 2) |
| | 1659 | { |
| | 1660 | psd_set_error (error); |
| | 1661 | return -1; |
| | 1662 | } |
| | 1663 | type = GINT16_FROM_BE (type); |
| | 1664 | IFDBG(3) g_debug ("Path record type %d", type); |
| | 1665 | |
| | 1666 | if (type == PSD_PATH_CL_LNK |
| | 1667 | || type == PSD_PATH_CL_UNLNK |
| | 1668 | || type == PSD_PATH_OP_LNK |
| | 1669 | || type == PSD_PATH_OP_UNLNK) |
| | 1670 | { |
| | 1671 | if (psd_read (input, &y[0], 4, error) < 4 || |
| | 1672 | psd_read (input, &x[0], 4, error) < 4 || |
| | 1673 | psd_read (input, &y[1], 4, error) < 4 || |
| | 1674 | psd_read (input, &x[1], 4, error) < 4 || |
| | 1675 | psd_read (input, &y[2], 4, error) < 4 || |
| | 1676 | psd_read (input, &x[2], 4, error) < 4) |
| | 1677 | { |
| | 1678 | psd_set_error (error); |
| | 1679 | return -1; |
| | 1680 | } |
| | 1681 | for (i = 0; i < 3; ++i) |
| | 1682 | { |
| | 1683 | x[i] = GINT32_FROM_BE (x[i]); |
| | 1684 | controlpoints[cntr] = x[i] / 16777216.0 * image_width; |
| | 1685 | cntr++; |
| | 1686 | y[i] = GINT32_FROM_BE (y[i]); |
| | 1687 | controlpoints[cntr] = y[i] / 16777216.0 * image_height; |
| | 1688 | cntr++; |
| | 1689 | } |
| | 1690 | IFDBG(3) g_debug ("Path points (%d,%d), (%d,%d), (%d,%d)", |
| | 1691 | x[0], y[0], x[1], y[1], x[2], y[2]); |
| | 1692 | } |
| | 1693 | else |
| | 1694 | { |
| | 1695 | IFDBG(1) g_debug ("Unexpected path type record %d", type); |
| | 1696 | if (! psd_seek (input, 24, G_SEEK_CUR, error)) |
| | 1697 | { |
| | 1698 | psd_set_error (error); |
| | 1699 | return -1; |
| | 1700 | } |
| | 1701 | } |
| | 1702 | path_rec--; |
| | 1703 | num_rec--; |
| | 1704 | } |
| | 1705 | /* Add sub-path */ |
| | 1706 | gimp_path_stroke_new_from_points (path, |
| | 1707 | GIMP_PATH_STROKE_TYPE_BEZIER, |
| | 1708 | cntr, controlpoints, closed); |
| | 1709 | g_free (controlpoints); |
| | 1710 | } |
| | 1711 | |
| | 1712 | else |
| | 1713 | { |
| | 1714 | if (! psd_seek (input, 24, G_SEEK_CUR, error)) |
| | 1715 | { |
| | 1716 | psd_set_error (error); |
| | 1717 | return -1; |
| | 1718 | } |
| | 1719 | } |
| | 1720 | |
| | 1721 | path_rec--; |
| | 1722 | } |
| | 1723 | |
| | 1724 | return 0; |
| | 1725 | } |
| | 1726 | |
| | 1727 | static gint |
| | 1728 | load_resource_2999 (const PSDimageres *res_a, |
| | 1729 | GimpImage *image, |
| | 1730 | GInputStream *input, |
| | 1731 | GError **error) |
| | 1732 | { |
| | 1733 | gchar *path_name; |
| | 1734 | gint16 path_flatness_int = 0; |
| | 1735 | gint16 path_flatness_fixed = 0; |
| | 1736 | gfloat path_flatness; |
| | 1737 | GimpParasite *parasite; |
| | 1738 | gint32 read_len; |
| | 1739 | gint32 write_len; |
| | 1740 | |
| | 1741 | path_name = fread_pascal_string (&read_len, &write_len, 2, input, error); |
| | 1742 | if (*error || ! path_name) |
| | 1743 | { |
| | 1744 | g_printerr ("psd-load: Unable to read clipping path name."); |
| | 1745 | return -1; |
| | 1746 | } |
| | 1747 | |
| | 1748 | /* Convert from fixed to floating point */ |
| | 1749 | if (psd_read (input, &path_flatness_int, 2, error) < 2 || |
| | 1750 | psd_read (input, &path_flatness_fixed, 2, error) < 2) |
| | 1751 | { |
| | 1752 | psd_set_error (error); |
| | 1753 | return -1; |
| | 1754 | } |
| | 1755 | path_flatness_fixed = GINT16_FROM_BE (path_flatness_fixed); |
| | 1756 | path_flatness_int = GINT16_FROM_BE (path_flatness_int); |
| | 1757 | |
| | 1758 | /* Converting from Adobe fixed point value to float */ |
| | 1759 | path_flatness = (path_flatness_fixed - 0.5f) / 65536.0; |
| | 1760 | path_flatness += path_flatness_int; |
| | 1761 | |
| | 1762 | /* Adobe path flatness range is 0.2 to 100.0 */ |
| | 1763 | path_flatness = CLAMP (path_flatness, 0.2f, 100.0f); |
| | 1764 | |
| | 1765 | /* Save to image parasite */ |
| | 1766 | parasite = gimp_parasite_new (PSD_PARASITE_CLIPPING_PATH, 0, |
| | 1767 | read_len, path_name); |
| | 1768 | gimp_image_attach_parasite (image, parasite); |
| | 1769 | gimp_parasite_free (parasite); |
| | 1770 | |
| | 1771 | parasite = gimp_parasite_new (PSD_PARASITE_PATH_FLATNESS, 0, |
| | 1772 | sizeof (gfloat), &path_flatness); |
| | 1773 | gimp_image_attach_parasite (image, parasite); |
| | 1774 | gimp_parasite_free (parasite); |
| | 1775 | |
| | 1776 | /* Adobe says they ignore the last two bytes, the fill rule */ |
| | 1777 | if (psd_read (input, &path_flatness_fixed, 2, error) < 2) |
| | 1778 | { |
| | 1779 | psd_set_error (error); |
| | 1780 | return -1; |
| | 1781 | } |
| | 1782 | |
| | 1783 | g_free (path_name); |
| | 1784 | |
| | 1785 | return 0; |
| | 1786 | } |