1 // This file is part of Deark.
2 // Copyright (C) 2016 Jason Summers
3 // See the file COPYING for terms of use.
5 // * Photoshop PSD and PSB format
6 // * PSD "image resources"
7 // * PSD "series of tagged blocks"
8 // * Photoshop Action file format (.atn)
9 // * Photoshop Gradient file format (.grd)
10 // * Photoshop Styles (.asl)
11 // * Photoshop Brush (.abr)
12 // * Photoshop Custom Shape (.csh)
13 // * Photoshop Pattern file (.pat)
15 #include <deark-config.h>
16 #include <deark-private.h>
17 #include <deark-fmtutil.h>
18 DE_DECLARE_MODULE(de_module_psd
);
19 DE_DECLARE_MODULE(de_module_ps_action
);
20 DE_DECLARE_MODULE(de_module_ps_gradient
);
21 DE_DECLARE_MODULE(de_module_ps_styles
);
22 DE_DECLARE_MODULE(de_module_ps_brush
);
23 DE_DECLARE_MODULE(de_module_ps_csh
);
24 DE_DECLARE_MODULE(de_module_ps_pattern
);
26 #define CODE_8B64 0x38423634U
27 #define CODE_8BIM 0x3842494dU
28 #define CODE_AgHg 0x41674867U
29 #define CODE_Alph 0x416c7068U
30 #define CODE_AnDs 0x416e4473U
31 #define CODE_CgEd 0x43674564U
32 #define CODE_Clss 0x436c7373U
33 #define CODE_DCSR 0x44435352U
34 #define CODE_Enmr 0x456e6d72U
35 #define CODE_FEid 0x46456964U
36 #define CODE_FMsk 0x464d736bU
37 #define CODE_FXid 0x46586964U
38 #define CODE_GdFl 0x4764466cU
39 #define CODE_GlbC 0x476c6243U
40 #define CODE_GlbO 0x476c624fU
41 #define CODE_IRFR 0x49524652U
42 #define CODE_LMsk 0x4c4d736bU
43 #define CODE_Layr 0x4c617972U
44 #define CODE_Lr16 0x4c723136U
45 #define CODE_Lr32 0x4c723332U
46 #define CODE_MeSa 0x4d655361U
47 #define CODE_Mt16 0x4d743136U
48 #define CODE_Mt32 0x4d743332U
49 #define CODE_Mtrn 0x4d74726eU
50 #define CODE_ObAr 0x4f624172U
51 #define CODE_Objc 0x4f626a63U
52 #define CODE_PHUT 0x50485554U
53 #define CODE_Pat2 0x50617432U
54 #define CODE_Pat3 0x50617433U
55 #define CODE_Patt 0x50617474U
56 #define CODE_PtFl 0x5074466cU
57 #define CODE_PxSD 0x50785344U
58 #define CODE_PxSc 0x50785363U
59 #define CODE_SoCo 0x536f436fU
60 #define CODE_SoLd 0x536f4c64U
61 #define CODE_TEXT 0x54455854U
62 #define CODE_Txt2 0x54787432U
63 #define CODE_TySh 0x54795368U
64 #define CODE_UnFl 0x556e466cU
65 #define CODE_UntF 0x556e7446U
66 #define CODE_VlLs 0x566c4c73U
67 #define CODE_abdd 0x61626464U
68 #define CODE_alis 0x616c6973U
69 #define CODE_anFX 0x616e4658U
70 #define CODE_artb 0x61727462U
71 #define CODE_artd 0x61727464U
72 #define CODE_blwh 0x626c7768U
73 #define CODE_bool 0x626f6f6cU
74 #define CODE_clbl 0x636c626cU
75 #define CODE_comp 0x636f6d70U
76 #define CODE_cust 0x63757374U
77 #define CODE_desc 0x64657363U
78 #define CODE_doub 0x646f7562U
79 #define CODE_enum 0x656e756dU
80 #define CODE_fxrp 0x66787270U
81 #define CODE_indx 0x696e6478U
82 #define CODE_infx 0x696e6678U
83 #define CODE_knko 0x6b6e6b6fU
84 #define CODE_lfx2 0x6c667832U
85 #define CODE_liFD 0x6c694644U
86 #define CODE_lnk2 0x6c6e6b32U
87 #define CODE_lnk3 0x6c6e6b33U
88 #define CODE_lnkD 0x6c6e6b44U
89 #define CODE_lnsr 0x6c6e7372U
90 #define CODE_long 0x6c6f6e67U
91 #define CODE_lrFX 0x6c724658U
92 #define CODE_lsct 0x6c736374U
93 #define CODE_lspf 0x6c737066U
94 #define CODE_luni 0x6c756e69U
95 #define CODE_lyid 0x6c796964U
96 #define CODE_mani 0x6d616e69U
97 #define CODE_mlst 0x6d6c7374U
98 #define CODE_mopt 0x6d6f7074U
99 #define CODE_mset 0x6d736574U
100 #define CODE_name 0x6e616d65U
101 #define CODE_obj 0x6f626a20U
102 #define CODE_patt 0x70617474U
103 #define CODE_prop 0x70726f70U
104 #define CODE_pths 0x70746873U
105 #define CODE_rele 0x72656c65U
106 #define CODE_samp 0x73616d70U
107 #define CODE_shmd 0x73686d64U
108 #define CODE_tdta 0x74647461U
109 #define CODE_tySh 0x74795368U
110 #define CODE_type 0x74797065U
111 #define CODE_vibA 0x76696241U
112 #define CODE_vmsk 0x766d736bU
113 #define CODE_vogk 0x766f676bU
114 #define CODE_vscg 0x76736367U
115 #define CODE_vsms 0x76736d73U
116 #define CODE_vstk 0x7673746bU
118 #define PSD_CM_BITMAP 0
119 #define PSD_CM_GRAY 1
120 #define PSD_CM_PALETTE 2
123 // (I can't think of a good name for this struct, and the corresponding variables.
124 // It's used so much that the name needs to be short, distinct, and easy to type.)
125 // PSD format involves so many nested data elements with implicit lengths that
126 // it's worth developing a way to handle this with a maximum of convenience.
127 // This struct helps to do that.
128 // A function that processes an element has an instance of it (named zz) that it
129 // got from its parent (caller). It often creates new zz structs to pass to its
131 // The struct is used for both input and output.
132 // A function updates the 'pos' field as it consumes the data, but 'startpos' and
133 // 'endpos' never change.
135 // Some functions assume that the zz passed to them was created just for them, and
136 // thus .pos should be equal to .startpos, and .endpos should be exactly the size of
137 // that data element, if known. The code is more robust if a function can't directly
138 // modify its parent's zz, and this lets the child use the .startpos field.
139 // However, for convenience, some functions are designed such that they can use
140 // their parent's zz.
142 // Note that the struct has no way to indicate an error. It is expected that the
143 // functions' return values will be used, when error handling is necessary.
144 typedef struct zz_struct
{
145 // Represents a segment of the input file, and a position within that segment.
146 // All fields are byte offsets from the beginning of c->infile.
147 i64 pos
; // The "current position". Also used to calculate the number of bytes consumed.
148 i64 startpos
; // Offset of the first byte in the segment.
149 i64 endpos
; // Offset of first byte *after* the segment.
152 // The PSD spec calls this data structure a
153 // "4 bytes (length), followed either by string or (if length is zero) 4-byte ID",
154 // but that's too unwieldy for me, so I'll call it a "flexible_id".
157 struct de_fourcc fourcc
;
158 char *sz
; // Present if !is_fourcc. Raw bytes (+NUL), used for matching.
159 de_ucstring
*s
; // Present if !is_fourcc. Text form of sz.
167 i64 bits_per_channel
;
168 struct de_density_info density
;
174 typedef struct localctx_struct
{
175 int version
; // 1=PSD, 2=PSB
178 int tagged_blocks_only
;
179 #define MAX_NESTING_LEVEL 50
185 int abr_major_ver
, abr_minor_ver
;
187 struct de_density_info density
;
189 struct image_info
*main_iinfo
;
194 typedef void (*rsrc_handler_fn
)(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
);
199 // 0x0004 = Item consists of a version number, followed by a "Descriptor structure".
200 // 0x0010 = Do not include ASCII in hexdumps.
207 #define DECLARE_HRSRC(x) static void x(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
209 DECLARE_HRSRC(hrsrc_resolutioninfo
);
210 DECLARE_HRSRC(hrsrc_namesofalphachannels
);
211 DECLARE_HRSRC(hrsrc_printflags
);
212 DECLARE_HRSRC(hrsrc_iptc
);
213 DECLARE_HRSRC(hrsrc_exif
);
214 DECLARE_HRSRC(hrsrc_xmp
);
215 DECLARE_HRSRC(hrsrc_iccprofile
);
216 DECLARE_HRSRC(hrsrc_slices
);
217 DECLARE_HRSRC(hrsrc_thumbnail
);
218 DECLARE_HRSRC(hrsrc_byte
);
219 DECLARE_HRSRC(hrsrc_uint16
);
220 DECLARE_HRSRC(hrsrc_uint32
);
221 DECLARE_HRSRC(hrsrc_unicodestring
);
222 DECLARE_HRSRC(hrsrc_unicodestring_multi
);
223 DECLARE_HRSRC(hrsrc_pascalstring
);
224 DECLARE_HRSRC(hrsrc_plaintext
);
225 DECLARE_HRSRC(hrsrc_urllist
);
226 DECLARE_HRSRC(hrsrc_versioninfo
);
227 DECLARE_HRSRC(hrsrc_printscale
);
228 DECLARE_HRSRC(hrsrc_pixelaspectratio
);
229 DECLARE_HRSRC(hrsrc_layerselectionids
);
230 DECLARE_HRSRC(hrsrc_pathinfo
);
231 DECLARE_HRSRC(hrsrc_printflagsinfo
);
232 DECLARE_HRSRC(hrsrc_pluginresource
);
234 static const struct rsrc_info rsrc_info_arr
[] = {
235 { 0x03e8, 0, "channels/rows/columns/depth/mode", NULL
},
236 { 0x03e9, 0, "Macintosh print manager print info", NULL
},
237 { 0x03ea, 0, "Macintosh page format information", NULL
},
238 { 0x03eb, 0, "Indexed color table", NULL
},
239 { 0x03ed, 0, "Resolution info", hrsrc_resolutioninfo
},
240 { 0x03ee, 0, "Names of the alpha channels", hrsrc_namesofalphachannels
},
241 { 0x03ef, 0, "Display information", NULL
},
242 { 0x03f0, 0, "Caption", NULL
},
243 { 0x03f1, 0, "Border information", NULL
},
244 { 0x03f2, 0, "Background color", NULL
},
245 { 0x03f3, 0, "Print flags", hrsrc_printflags
},
246 { 0x03f4, 0, "Grayscale and multichannel halftoning information", NULL
},
247 { 0x03f5, 0, "Color halftoning info", NULL
},
248 { 0x03f6, 0, "Duotone halftoning information", NULL
},
249 { 0x03f7, 0, "Grayscale and multichannel transfer function", NULL
},
250 { 0x03f8, 0x0010, "Color transfer functions", NULL
},
251 { 0x03f9, 0, "Duotone transfer functions", NULL
},
252 { 0x03fa, 0, "Duotone image information", NULL
},
253 { 0x03fb, 0, "Effective black and white values", NULL
},
254 //{ 0x03fc, 0, "(Obsolete)", NULL },
255 { 0x03fd, 0, "EPS options", NULL
},
256 { 0x03fe, 0, "Quick Mask information", NULL
},
257 //{ 0x03ff, 0, "(Obsolete)", NULL },
258 { 0x0400, 0, "Layer state information", hrsrc_uint16
},
259 { 0x0401, 0, "Working path", hrsrc_pathinfo
},
260 { 0x0402, 0x0010, "Layers group information", NULL
},
261 //{ 0x0403, 0, "(Obsolete)", NULL },
262 { 0x0404, 0, "IPTC-NAA", hrsrc_iptc
},
263 { 0x0405, 0, "Image mode for raw format files", NULL
},
264 { 0x0406, 0x0010, "JPEG quality", NULL
},
265 { 0x0408, 0x0010, "Grid and guides info", NULL
},
266 { 0x0409, 0, "Thumbnail - Photoshop 4.0", hrsrc_thumbnail
},
267 { 0x040a, 0, "Copyright flag", hrsrc_byte
},
268 { 0x040b, 0, "URL", hrsrc_plaintext
},
269 { 0x040c, 0, "Thumbnail", hrsrc_thumbnail
},
270 { 0x040d, 0, "Global Angle", hrsrc_uint32
},
271 { 0x040e, 0, "Color samplers resource (Photoshop 5.0)", NULL
},
272 { 0x040f, 0, "ICC Profile", hrsrc_iccprofile
},
273 { 0x0410, 0, "Watermark", hrsrc_byte
},
274 { 0x0411, 0, "ICC Untagged Profile", hrsrc_byte
},
275 { 0x0412, 0, "Effects visible", hrsrc_byte
},
276 { 0x0413, 0, "Spot Halftone", NULL
},
277 { 0x0414, 0, "Document-specific IDs seed number", hrsrc_uint32
},
278 { 0x0415, 0, "Unicode Alpha Names", hrsrc_unicodestring_multi
},
279 { 0x0416, 0, "Indexed Color Table Count", NULL
},
280 { 0x0417, 0, "Transparency Index", NULL
},
281 { 0x0419, 0, "Global Altitude", hrsrc_uint32
},
282 { 0x041a, 0, "Slices", hrsrc_slices
},
283 { 0x041b, 0, "Workflow URL", hrsrc_unicodestring
},
284 { 0x041c, 0, "Jump To XPEP", NULL
},
285 { 0x041d, 0, "Alpha Identifiers", NULL
},
286 { 0x041e, 0, "URL List", hrsrc_urllist
},
287 { 0x0421, 0, "Version Info", hrsrc_versioninfo
},
288 { 0x0422, 0, "EXIF data 1", hrsrc_exif
},
289 { 0x0423, 0, "EXIF data 3", NULL
},
290 { 0x0424, 0, "XMP metadata", hrsrc_xmp
},
291 { 0x0425, 0x0010, "Caption digest", NULL
},
292 { 0x0426, 0, "Print scale", hrsrc_printscale
},
293 { 0x0428, 0, "Pixel Aspect Ratio", hrsrc_pixelaspectratio
},
294 { 0x0429, 0x0004, "Layer Comps", NULL
},
295 { 0x042a, 0, "Alternate Duotone Colors", NULL
},
296 { 0x042b, 0, "Alternate Spot Colors", NULL
},
297 { 0x042d, 0, "Layer Selection ID(s)", hrsrc_layerselectionids
},
298 { 0x042e, 0, "HDR Toning information", NULL
},
299 { 0x042f, 0, "Auto Save Format", NULL
},
300 { 0x0430, 0x0010, "Layer Group(s) Enabled ID", NULL
},
301 { 0x0431, 0, "Color samplers resource (Photoshop CS3)", NULL
},
302 { 0x0432, 0x0004, "Measurement Scale", NULL
},
303 { 0x0433, 0x0004, "Timeline Information", NULL
},
304 { 0x0434, 0x0004, "Sheet Disclosure", NULL
},
305 { 0x0435, 0, "DisplayInfo", NULL
},
306 { 0x0436, 0x0004, "Onion Skins", NULL
},
307 { 0x0438, 0x0004, "Count Information", NULL
},
308 { 0x043a, 0x0004, "Print Information", NULL
},
309 { 0x043b, 0x0004, "Print Style", NULL
},
310 { 0x043c, 0, "Macintosh NSPrintInfo", NULL
},
311 { 0x043d, 0, "Windows DEVMODE", NULL
},
312 { 0x043e, 0, "Auto Save File Path", hrsrc_unicodestring
},
313 { 0x043f, 0, "Auto Save Format", hrsrc_unicodestring
},
314 { 0x0440, 0x0004, "Path Selection State", NULL
},
315 // 0x07d0 to 0x0bb6: See lookup_rsrc() below
316 { 0x0bb7, 0, "Name of clipping path", hrsrc_pascalstring
},
317 { 0x0bb8, 0x0004, "Origin Path Info", NULL
},
318 // 0x0fa0 to 0x1387: See lookup_rsrc() below
319 { 0x1b58, 0, "Image Ready variables", NULL
},
320 { 0x1b59, 0, "Image Ready data sets", NULL
},
321 { 0x1b5a, 0x0004, "Image Ready default selected state", NULL
},
322 { 0x1b5b, 0, "Image Ready 7 rollover expanded state", NULL
},
323 { 0x1b5c, 0, "Image Ready rollover expanded state", NULL
},
324 { 0x1b5d, 0x0004, "Image Ready save layer settings", NULL
},
325 { 0x1b5e, 0, "Image Ready version", NULL
},
326 { 0x1f40, 0, "Lightroom workflow", NULL
},
327 { 0x2710, 0, "Print flags info", hrsrc_printflagsinfo
}
330 // Forward declarations
331 static int read_descriptor(deark
*c
, lctx
*d
, zztype
*zz
, int has_version
, const char *dscrname
);
332 static void do_tagged_blocks(deark
*c
, lctx
*d
, zztype
*zz
, int tbnamespace
);
333 static int do_descriptor_item_ostype_and_data(deark
*c
, lctx
*d
,
334 const struct flexible_id
*key_flid
, zztype
*zz
, i64 itempos
);
336 #define psd_getu16(p) dbuf_getu16x(c->infile,p,d->is_le)
337 #define psd_geti16(p) dbuf_geti16x(c->infile,p,d->is_le)
338 #define psd_getu32(p) dbuf_getu32x(c->infile,p,d->is_le)
339 #define psd_geti32(p) dbuf_geti32x(c->infile,p,d->is_le)
340 #define psd_geti64(p) dbuf_geti64x(c->infile,p,d->is_le)
342 // Initialize a zz, from known start and end positions.
343 static void zz_init_absolute(zztype
*zz
, i64 startpos
, i64 endpos
)
345 zz
->startpos
= startpos
;
350 // Initialize zz such that its startpos is parentzz's *current* pos,
351 // and its endpos is the same as parentzz's.
352 static void zz_init(zztype
*zz
, const zztype
*parentzz
)
354 zz_init_absolute(zz
, parentzz
->pos
, parentzz
->endpos
);
357 // Initialize zz such that its startpos is parentzz's *current* pos.
358 static void zz_init_with_len(zztype
*zz
, const zztype
*parentzz
, i64 len
)
360 i64 startpos
, endpos
;
363 startpos
= parentzz
->pos
;
364 endpos
= startpos
+ len
;
365 if(endpos
> parentzz
->endpos
) endpos
= parentzz
->endpos
;
367 zz_init_absolute(zz
, startpos
, endpos
);
370 // Number of bytes consumed so far.
371 // I.e. number of bytes from startpos to the current position.
372 static i64
zz_used(zztype
*zz
)
374 if(zz
->endpos
<= zz
->startpos
) return 0;
375 if(zz
->pos
<= zz
->endpos
) return zz
->pos
- zz
->startpos
;
376 return zz
->endpos
- zz
->startpos
;
379 // Number of bytes remaining / still available.
380 // I.e. number of bytes from the current position to endpos.
381 static i64
zz_avail(zztype
*zz
)
383 if(zz
->pos
>= zz
->endpos
) return 0;
384 if(zz
->pos
>= zz
->startpos
) return zz
->endpos
- zz
->pos
;
385 return zz
->endpos
- zz
->startpos
;
388 // Functions that modify a shared "current file position" variable are
389 // discouraged in Deark, but PSD format practically forces us to use them
391 // May as well go all the way, and even do it for simple get_int functions.
393 static u8
psd_dbuf_getbyte_zz(dbuf
*f
, zztype
*zz
)
395 u8 val
= dbuf_getbyte(f
, zz
->pos
);
400 static i64
psd_dbuf_getu16_zz(dbuf
*f
, zztype
*zz
, int is_le
)
402 i64 val
= dbuf_getu16x(f
, zz
->pos
, is_le
);
407 static i64
psd_dbuf_geti16_zz(dbuf
*f
, zztype
*zz
, int is_le
)
409 i64 val
= dbuf_geti16x(f
, zz
->pos
, is_le
);
414 static i64
psd_dbuf_getu32_zz(dbuf
*f
, zztype
*zz
, int is_le
)
416 i64 val
= dbuf_getu32x(f
, zz
->pos
, is_le
);
421 static i64
psd_dbuf_geti32_zz(dbuf
*f
, zztype
*zz
, int is_le
)
423 i64 val
= dbuf_geti32x(f
, zz
->pos
, is_le
);
428 static i64
psd_dbuf_geti64_zz(dbuf
*f
, zztype
*zz
, int is_le
)
430 i64 val
= dbuf_geti64x(f
, zz
->pos
, is_le
);
435 #define psd_getbytezz(z) psd_dbuf_getbyte_zz(c->infile,z)
436 #define psd_getu16zz(z) psd_dbuf_getu16_zz(c->infile,z,d->is_le)
437 #define psd_geti16zz(z) psd_dbuf_geti16_zz(c->infile,z,d->is_le)
438 #define psd_getu32zz(z) psd_dbuf_getu32_zz(c->infile,z,d->is_le)
439 #define psd_geti32zz(z) psd_dbuf_geti32_zz(c->infile,z,d->is_le)
440 #define psd_geti64zz(z) psd_dbuf_geti64_zz(c->infile,z,d->is_le)
442 // Read a 32-bit (if d->intsize_4or8==4) or 64-bit int from c->infile.
443 // This function is used to help support PSB format.
444 static i64
psd_getu32or64zz(deark
*c
, lctx
*d
, zztype
*zz
)
446 if(d
->intsize_4or8
>4)
447 return psd_geti64zz(zz
);
448 return psd_getu32zz(zz
);
451 static const char *get_colormode_name(i64 n
)
453 const char *name
= "?";
455 case PSD_CM_BITMAP
: name
="bitmap"; break;
456 case PSD_CM_GRAY
: name
="grayscale"; break;
457 case PSD_CM_PALETTE
: name
="indexed"; break;
458 case PSD_CM_RGB
: name
="RGB"; break;
459 case 4: name
="CMYK"; break;
460 case 7: name
="multichannel"; break;
461 case 8: name
="duotone"; break;
462 case 9: name
="Lab"; break;
467 static void dbg_print_compression_method(deark
*c
, lctx
*d
, i64 cmpr
)
469 const char *name
= "?";
472 case 0: name
="uncompressed"; break;
473 // (At one point the PSD spec says that "1 is zip", but I think that's a
474 // clerical error. My best guess is that all the compression fields use
475 // the same compression codes.)
476 case 1: name
="PackBits"; break;
477 case 2: name
="ZIP without prediction"; break;
478 case 3: name
="ZIP with prediction"; break;
480 de_dbg(c
, "compression method: %d (%s)", (int)cmpr
, name
);
483 // The PSD module's version of dbuf_read_fourcc()
484 static void psd_read_fourcc_zz(deark
*c
, lctx
*d
, zztype
*zz
, struct de_fourcc
*fourcc
)
486 dbuf_read_fourcc(c
->infile
, zz
->pos
, fourcc
, 4, d
->is_le
? DE_4CCFLAG_REVERSED
: 0);
490 // For rectangles in top-left-bottom-right order
491 static void read_rectangle_tlbr(deark
*c
, lctx
*d
, zztype
*zz
, const char *name
)
496 n
[k
] = psd_geti32zz(zz
);
498 de_dbg(c
, "%s: (%d,%d)-(%d,%d)", name
, (int)n
[1], (int)n
[0], (int)n
[3], (int)n
[2]);
501 // For rectangles in left-top-right-bottom order
502 static void read_rectangle_ltrb(deark
*c
, lctx
*d
, zztype
*zz
, const char *name
)
507 n
[k
] = psd_geti32zz(zz
);
509 de_dbg(c
, "%s: (%d,%d)-(%d,%d)", name
, (int)n
[0], (int)n
[1], (int)n
[2], (int)n
[3]);
512 // (Okay to use a shared zz.)
513 static void read_pascal_string_to_ucstring(deark
*c
, lctx
*d
, de_ucstring
*s
, zztype
*zz
)
517 if(zz_avail(zz
)<1) return;
519 // First byte is the string length
520 dlen
= (i64
)psd_getbytezz(zz
);
522 if(zz
->pos
+ dlen
> zz
->endpos
) { // error
523 zz
->pos
= zz
->endpos
;
527 dbuf_read_to_ucstring(c
->infile
, zz
->pos
, dlen
, s
, 0, d
->input_encoding
);
531 // Like a Pascal string, but with a 4-byte prefix
532 // (Okay to use a shared zz.)
533 static void read_prefixed_string_to_ucstring(deark
*c
, lctx
*d
, de_ucstring
*s
, zztype
*zz
)
538 zz
->pos
= zz
->endpos
;
542 dlen
= psd_getu32zz(zz
);
544 if(zz
->pos
+ dlen
> zz
->endpos
) { // error
545 zz
->pos
= zz
->endpos
;
549 dbuf_read_to_ucstring(c
->infile
, zz
->pos
, dlen
, s
, 0, d
->input_encoding
);
553 // Caller supplies ri_dst. This function will set its fields.
554 static int lookup_rsrc(u32 sig_id
, u16 n
, struct rsrc_info
*ri_dst
)
559 de_zeromem(ri_dst
, sizeof(struct rsrc_info
));
561 if(sig_id
==CODE_PHUT
) { // PhotoDeluxe resources seem to use incompatible formats.
563 ri_dst
->idname
= "?";
567 for(i
=0; i
<(i64
)DE_ARRAYCOUNT(rsrc_info_arr
); i
++) {
568 if(rsrc_info_arr
[i
].id
== n
) {
569 *ri_dst
= rsrc_info_arr
[i
]; // struct copy
570 if(!ri_dst
->idname
) ri_dst
->idname
= "?";
576 ri_dst
->idname
= "?";
578 // Handle pattern-based resources that don't fit nicely in our table.
580 if(n
>=0x07d0 && n
<=0x0bb6) {
582 ri_dst
->idname
= "Path Information";
583 ri_dst
->hfn
= hrsrc_pathinfo
;
585 else if(n
>=0x0fa0 && n
<=0x1387) {
587 ri_dst
->idname
= "Plug-In resource";
588 ri_dst
->hfn
= hrsrc_pluginresource
;
594 static const char* units_name(i64 u
)
597 case 1: return "pixels/inch";
598 case 2: return "pixels/cm";
603 static void hrsrc_resolutioninfo(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
605 i64 xres_int
, yres_int
;
607 i64 xres_unit
, yres_unit
;
609 if(zz_avail(zz
)!=16) return;
610 xres_int
= psd_getu32(zz
->pos
);
611 xres
= ((double)xres_int
)/65536.0;
612 de_dbg(c
, "xres=%.2f dpi", xres
);
613 xres_unit
= psd_getu16(zz
->pos
+4);
614 de_dbg(c
, "xres display unit: %d (%s)", (int)xres_unit
, units_name(xres_unit
));
615 //width_unit = psd_getu16(pos+6);
617 yres_int
= psd_getu32(zz
->pos
+8);
618 yres
= ((double)yres_int
)/65536.0;
619 de_dbg(c
, "yres=%.2f dpi", yres
);
620 yres_unit
= psd_getu16(zz
->pos
+12);
621 de_dbg(c
, "yres display unit: %d (%s)", (int)yres_unit
, units_name(yres_unit
));
622 //height_unit = psd_getu16(pos+14);
624 d
->density
.code
= DE_DENSITY_DPI
;
625 d
->density
.xdens
= xres
;
626 d
->density
.ydens
= yres
;
629 static void hrsrc_namesofalphachannels(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
631 de_ucstring
*s
= NULL
;
634 // This is a "series of Pascal strings", whatever that is.
636 s
= ucstring_create(c
);
637 while(zz
->pos
< (zz
->endpos
-1)) {
639 read_pascal_string_to_ucstring(c
, d
, s
, zz
);
640 de_dbg(c
, "%s[%d]: \"%s\"", ri
->idname
, idx
, ucstring_getpsz_d(s
));
646 static void hrsrc_printflags(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
649 if(zz_avail(zz
)!=9) return;
650 de_read(fl
, zz
->pos
, 9);
651 de_dbg(c
, "%s: labels=%d, crop marks=%d, color bars=%d, registration marks=%d, "
652 "negative=%d, flip=%d, interpolate=%d, caption=%d, print flags=%d",
653 ri
->idname
, (int)fl
[0], (int)fl
[1], (int)fl
[2], (int)fl
[3],
654 (int)fl
[4], (int)fl
[5], (int)fl
[6], (int)fl
[7], (int)fl
[8]);
657 static void do_pathinfo(deark
*c
, lctx
*d
, zztype
*zz
)
662 num_records
= zz_avail(zz
) / 26;
663 de_dbg(c
, "calculated number of records: %d", (int)num_records
);
664 for(i
=0; i
<num_records
; i
++) {
670 de_dbg(c
, "path data record[%d] at %d", (int)i
, (int)zz
->pos
);
671 zz_init_with_len(&czz
, zz
, 26);
674 t
= psd_getu16zz(&czz
);
676 case 0: name
="Closed subpath length"; break;
677 case 1: name
="Closed subpath Bezier knot, linked"; break;
678 case 2: name
="Closed subpath Bezier knot, unlinked"; break;
679 case 3: name
="Open subpath length"; break;
680 case 4: name
="Open subpath Bezier knot, linked"; break;
681 case 5: name
="Open subpath Bezier knot, unlinked"; break;
682 case 6: name
="Path fill rule"; break;
683 case 7: name
="Clipboard"; break;
684 case 8: name
="Initial fill rule"; break;
685 default: name
="?"; break;
687 de_dbg(c
, "path record type: %d (%s)", (int)t
, name
);
691 x
= psd_getu16zz(&czz
);
692 de_dbg(c
, "number of Bezier knot records: %d", (int)x
);
695 x
= psd_getu16zz(&czz
);
696 de_dbg(c
, "value: %d", (int)x
);
701 de_dbg_indent(c
, -1);
705 static void hrsrc_pathinfo(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
707 do_pathinfo(c
, d
, zz
);
710 static void hrsrc_printflagsinfo(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
712 i64 version
, bleed_width_value
, bleed_width_scale
;
715 if(zz_avail(zz
)!=10) return;
716 version
= psd_getu16zz(zz
);
717 crop_marks
= psd_getbytezz(zz
);
719 bleed_width_value
= psd_getu32zz(zz
);
720 bleed_width_scale
= psd_getu16zz(zz
);
721 de_dbg(c
, "%s: version=%d, crop marks=%d, bleed width value=%d, bleed width scale=%d",
722 ri
->idname
, (int)version
, (int)crop_marks
,
723 (int)bleed_width_value
, (int)bleed_width_scale
);
726 static void hrsrc_exif(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
728 fmtutil_handle_exif(c
, zz
->pos
, zz_avail(zz
));
731 static void hrsrc_iptc(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
734 fmtutil_handle_iptc(c
, c
->infile
, zz
->pos
, zz_avail(zz
), 0x0);
737 static void hrsrc_xmp(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
739 dbuf_create_file_from_slice(c
->infile
, zz
->pos
, zz_avail(zz
), "xmp", NULL
, DE_CREATEFLAG_IS_AUX
);
742 static void hrsrc_iccprofile(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
744 dbuf_create_file_from_slice(c
->infile
, zz
->pos
, zz_avail(zz
), "icc", NULL
, DE_CREATEFLAG_IS_AUX
);
747 static void do_pluginrsrc_mani(deark
*c
, lctx
*d
, zztype
*zz
)
749 struct de_fourcc fourcc
;
753 // This function is based on reverse engineering, and may not be correct.
755 if(zz_avail(zz
)<4) goto done
;
756 psd_read_fourcc_zz(c
, d
, zz
, &fourcc
);
757 de_dbg(c
, "id: '%s'", fourcc
.id_dbgstr
);
759 if(fourcc
.id
==CODE_IRFR
) { // Most likely related to Image Ready
760 if(zz_avail(zz
)<4) goto done
;
761 len
= psd_getu32zz(zz
);
762 de_dbg(c
, "length: %d", (int)len
);
763 if(zz_avail(zz
)<12) goto done
;
764 zz_init_with_len(&czz
, zz
, len
);
765 // This data seems to have the same structure as a "series of tagged
766 // blocks", but with different "keys". I don't know whether the keys are
767 // in a different namespace, or what.
768 do_tagged_blocks(c
, d
, zz
, 1);
775 static void do_pluginrsrc_mopt(deark
*c
, lctx
*d
, zztype
*zz
)
780 int saved_indent_level
;
783 // This function is based on reverse engineering, and may not be correct.
785 de_dbg_indent_save(c
, &saved_indent_level
);
787 x
= psd_getu32zz(zz
);
788 de_dbg(c
, "unknown int: %d", (int)x
);
789 num_items
= psd_getu32zz(zz
);
790 de_dbg(c
, "number of mopt items: %d", (int)num_items
);
792 for(i
=0; i
<num_items
; i
++) {
796 something_len
= 1138;
797 if(zz_avail(zz
)<something_len
) break;
798 de_dbg(c
, "mopt item[%d] at %d", (int)i
, (int)zz
->pos
);
801 de_dbg(c
, "[%d bytes of data at %d]", (int)something_len
, (int)zz
->pos
);
802 if(c
->debug_level
>=2) {
804 de_dbg_hexdump(c
, c
->infile
, zz
->pos
, something_len
, 256, NULL
, 0x1);
805 de_dbg_indent(c
, -1);
807 zz
->pos
+= something_len
;
809 if(zz_avail(zz
)<4) break;
811 dlen
= psd_getu32zz(zz
);
812 de_dbg(c
, "descriptor length: %d", (int)dlen
);
814 if(dlen
>0 && zz_avail(zz
)>0) {
815 zz_init_with_len(&czz
, zz
, dlen
);
816 read_descriptor(c
, d
, &czz
, 1, "");
820 de_dbg_indent(c
, -1);
823 de_dbg_indent_restore(c
, saved_indent_level
);
826 // Any plugin resource containing just a descriptor (after the ID code)
827 static void do_pluginrsrc_descriptor(deark
*c
, lctx
*d
, zztype
*zz
)
831 read_descriptor(c
, d
, &czz
, 1, "");
834 static void hrsrc_pluginresource(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
836 struct de_fourcc fourcc
;
839 // Plug-in resources seem to start with a fourcc.
840 if(zz_avail(zz
)<4) return;
841 psd_read_fourcc_zz(c
, d
, zz
, &fourcc
);
842 de_dbg(c
, "id: '%s'", fourcc
.id_dbgstr
);
846 do_pluginrsrc_mani(c
, d
, &czz
);
849 do_pluginrsrc_mopt(c
, d
, &czz
);
852 do_pluginrsrc_descriptor(c
, d
, &czz
);
855 if(zz_avail(&czz
)>0) {
856 de_dbg(c
, "[%d more bytes of plug-in resource data at %d]",
857 (int)zz_avail(&czz
), (int)czz
.startpos
);
858 if(c
->debug_level
>=2) {
860 de_dbg_hexdump(c
, c
->infile
, czz
.startpos
, zz_avail(&czz
), 256, NULL
, 0x1);
861 de_dbg_indent(c
, -1);
867 // Read a Photoshop-style "Unicode string" structure, and append it to s.
868 // (Okay to use a shared zz.)
869 static void read_unicode_string(deark
*c
, lctx
*d
, de_ucstring
*s
, zztype
*zz
)
873 if(zz_avail(zz
)<4) { // error
874 zz
->pos
= zz
->endpos
;
878 num_code_units
= psd_getu32zz(zz
);
879 if(zz
->pos
+ num_code_units
*2 > zz
->endpos
) { // error
880 zz
->pos
= zz
->endpos
;
884 // Use DE_DBG_MAX_STRLEN, because we assume the string is being read for
885 // the purposes of printing it in the debug info.
886 dbuf_read_to_ucstring_n(c
->infile
, zz
->pos
, num_code_units
*2, DE_DBG_MAX_STRLEN
*2, s
, 0,
887 d
->is_le
? DE_ENCODING_UTF16LE
: DE_ENCODING_UTF16BE
);
888 zz
->pos
+= num_code_units
*2;
890 // For no apparent reason, a fair number of these strings have been observed
891 // to end with an extraneous U+0000 character.
892 ucstring_strip_trailing_NUL(s
);
895 static void flexible_id_free_contents(deark
*c
, struct flexible_id
*flid
)
898 ucstring_destroy(flid
->s
);
902 de_free(c
, flid
->sz
);
907 // Caller allocates flid, and must free flid->s
908 static void read_flexible_id(deark
*c
, lctx
*d
, i64 pos
,
909 struct flexible_id
*flid
)
913 de_zeromem(flid
, sizeof(struct flexible_id
));
915 length
= psd_getu32(pos
);
918 dbuf_read_fourcc(c
->infile
, pos
+4, &flid
->fourcc
, 4, d
->is_le
? DE_4CCFLAG_REVERSED
: 0);
919 flid
->bytes_consumed
= 4 + 4;
924 // I don't know what the maximum length of an identifier is.
925 // I'll pretend it's 100 bytes.
926 adjusted_length
= length
;
927 if(adjusted_length
>100) adjusted_length
=100;
928 flid
->sz
= de_malloc(c
, adjusted_length
+1);
929 dbuf_read(c
->infile
, (unsigned char*)flid
->sz
, pos
+4, adjusted_length
);
930 flid
->sz
[adjusted_length
] = '\0';
932 flid
->s
= ucstring_create(c
);
933 ucstring_append_bytes(flid
->s
, (unsigned char*)flid
->sz
, adjusted_length
, 0, DE_ENCODING_ASCII
);
935 flid
->bytes_consumed
= 4 + length
;
939 static void read_flexible_id_zz(deark
*c
, lctx
*d
, zztype
*zz
, struct flexible_id
*flid
)
941 read_flexible_id(c
, d
, zz
->pos
, flid
);
942 zz
->pos
+= flid
->bytes_consumed
;
945 static void dbg_print_flexible_id(deark
*c
, lctx
*d
,
946 const struct flexible_id
*flid
, const char *name
)
948 if(flid
->is_fourcc
) {
949 de_dbg(c
, "%s: fourcc('%s')", name
, flid
->fourcc
.id_dbgstr
);
952 de_dbg(c
, "%s: string(\"%s\")", name
, ucstring_getpsz(flid
->s
));
955 // The PSD spec calls this type "Boolean" (or "Boolean structure").
956 static void do_item_type_bool(deark
*c
, lctx
*d
, zztype
*zz
)
959 b
= psd_getbytezz(zz
);
960 de_dbg(c
, "value: %d", (int)b
);
963 // The PSD spec calls this type "Integer".
964 static void do_item_type_long(deark
*c
, lctx
*d
, zztype
*zz
)
967 // No idea if this is signed or unsigned.
968 n
= psd_geti32zz(zz
);
969 de_dbg(c
, "value: %d", (int)n
);
973 static void do_item_type_doub(deark
*c
, lctx
*d
, zztype
*zz
)
976 v
= dbuf_getfloat64x(c
->infile
, zz
->pos
, d
->is_le
);
977 de_dbg(c
, "value: %f", v
);
982 static void do_item_type_UntF(deark
*c
, lctx
*d
, zztype
*zz
)
985 struct de_fourcc unit4cc
;
987 psd_read_fourcc_zz(c
, d
, zz
, &unit4cc
);
988 de_dbg(c
, "units code: '%s'", unit4cc
.id_dbgstr
);
990 v
= dbuf_getfloat64x(c
->infile
, zz
->pos
, d
->is_le
);
991 de_dbg(c
, "value: %f", v
);
995 static int do_item_type_class(deark
*c
, lctx
*d
, zztype
*zz
)
997 de_ucstring
*tmps
= NULL
;
998 struct flexible_id flid
;
1000 tmps
= ucstring_create(c
);
1001 read_unicode_string(c
, d
, tmps
, zz
);
1002 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1004 read_flexible_id_zz(c
, d
, zz
, &flid
);
1005 dbg_print_flexible_id(c
, d
, &flid
, "classID");
1006 flexible_id_free_contents(c
, &flid
);
1008 ucstring_destroy(tmps
);
1012 static int do_item_type_alis(deark
*c
, lctx
*d
, zztype
*zz
)
1016 x
= psd_getu32zz(zz
);
1017 de_dbg(c
, "alias length: %d", (int)x
);
1022 // Undocumented UnFl descriptor item type
1023 static void do_item_type_UnFl(deark
*c
, lctx
*d
, zztype
*zz
)
1026 struct de_fourcc unit4cc
;
1028 psd_read_fourcc_zz(c
, d
, zz
, &unit4cc
);
1029 de_dbg(c
, "units code: '%s'", unit4cc
.id_dbgstr
);
1031 count
= psd_getu32zz(zz
);
1032 de_dbg(c
, "count: %d", (int)count
);
1034 zz
->pos
+= count
*8; // TODO: [what we assume is a] float array
1037 static void do_text_engine_data(deark
*c
, lctx
*d
, i64 pos
, i64 len
)
1040 de_dbg(c
, "text engine data at %d, len=%d", (int)pos
, (int)len
);
1041 if(c
->extract_level
<2) return;
1042 dbuf_create_file_from_slice(c
->infile
, pos
, len
, "enginedata", NULL
, DE_CREATEFLAG_IS_AUX
);
1045 // The PSD spec calls this type "String" (or "String structure").
1046 static void do_item_type_TEXT(deark
*c
, lctx
*d
, zztype
*zz
)
1048 de_ucstring
*s
= NULL
;
1050 s
= ucstring_create(c
);
1051 read_unicode_string(c
, d
, s
, zz
);
1052 de_dbg(c
, "value: \"%s\"", ucstring_getpsz_d(s
));
1053 ucstring_destroy(s
);
1056 // "tdta" / "Raw Data"
1057 static int do_item_type_tdta(deark
*c
, lctx
*d
,
1058 const struct flexible_id
*key_flid
, zztype
*zz
)
1062 // The public PSD spec does not reveal how to calculate the length of a 'tdata'
1063 // item. Evidence suggests it starts with a 4-byte length field.
1064 dlen
= psd_getu32zz(zz
);
1065 de_dbg(c
, "raw data at %d, dlen=%d", (int)zz
->pos
, (int)dlen
);
1066 if(zz
->pos
+dlen
> zz
->endpos
) {
1071 if(!de_strcmp(key_flid
->sz
, "EngineData")) {
1072 do_text_engine_data(c
, d
, zz
->pos
, dlen
);
1080 // The PSD spec calls this type "Enumerated", and also "Enumerated descriptor"
1081 // (but not "Enumerated reference"!)
1082 static void do_item_type_enum(deark
*c
, lctx
*d
, zztype
*zz
)
1084 struct flexible_id flid
;
1086 read_flexible_id_zz(c
, d
, zz
, &flid
); // "type"
1087 dbg_print_flexible_id(c
, d
, &flid
, "enum type");
1088 flexible_id_free_contents(c
, &flid
);
1090 read_flexible_id_zz(c
, d
, zz
, &flid
); // "enum"
1091 dbg_print_flexible_id(c
, d
, &flid
, "enum value");
1092 flexible_id_free_contents(c
, &flid
);
1096 static int do_item_type_VlLs(deark
*c
, lctx
*d
,
1097 const struct flexible_id
*key_flid
, zztype
*zz
, i64 outer_itempos
)
1105 num_items
= psd_getu32zz(zz
);
1106 de_dbg(c
, "number of items in list: %d", (int)num_items
);
1107 if(num_items
>5000) {
1108 de_warn(c
, "Excessively large VlLs item (%d)", (int)num_items
);
1112 if(d
->nesting_level
>MAX_NESTING_LEVEL
) goto done
;
1114 for(i
=0; i
<num_items
; i
++) {
1116 inner_itempos
= zz
->pos
;
1117 de_dbg(c
, "item[%d] at %d (for list@%d)", (int)i
,
1118 (int)inner_itempos
, (int)outer_itempos
);
1119 de_dbg_indent(c
, 1);
1122 ret
= do_descriptor_item_ostype_and_data(c
, d
, key_flid
, &czz
, inner_itempos
);
1124 de_dbg_indent(c
, -1);
1126 zz
->pos
+= zz_used(&czz
);
1134 static int do_item_type_descriptor(deark
*c
, lctx
*d
, zztype
*zz
, int has_version
)
1139 if(d
->nesting_level
>MAX_NESTING_LEVEL
) goto done
;
1141 // This descriptor contains a descriptor. We have to go deeper.
1142 retval
= read_descriptor(c
, d
, zz
, has_version
, "");
1149 static int do_Enmr_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1151 de_ucstring
*tmps
= NULL
;
1152 struct flexible_id flid
;
1154 tmps
= ucstring_create(c
);
1155 read_unicode_string(c
, d
, tmps
, zz
);
1156 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1158 read_flexible_id_zz(c
, d
, zz
, &flid
);
1159 dbg_print_flexible_id(c
, d
, &flid
, "classID");
1160 flexible_id_free_contents(c
, &flid
);
1162 read_flexible_id_zz(c
, d
, zz
, &flid
);
1163 dbg_print_flexible_id(c
, d
, &flid
, "typeID");
1164 flexible_id_free_contents(c
, &flid
);
1166 read_flexible_id_zz(c
, d
, zz
, &flid
);
1167 dbg_print_flexible_id(c
, d
, &flid
, "enum");
1168 flexible_id_free_contents(c
, &flid
);
1170 ucstring_destroy(tmps
);
1174 static int do_prop_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1176 de_ucstring
*tmps
= NULL
;
1177 struct flexible_id flid
;
1179 tmps
= ucstring_create(c
);
1180 read_unicode_string(c
, d
, tmps
, zz
);
1181 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1183 read_flexible_id_zz(c
, d
, zz
, &flid
);
1184 dbg_print_flexible_id(c
, d
, &flid
, "classID");
1185 flexible_id_free_contents(c
, &flid
);
1187 read_flexible_id_zz(c
, d
, zz
, &flid
);
1188 dbg_print_flexible_id(c
, d
, &flid
, "keyID");
1189 flexible_id_free_contents(c
, &flid
);
1191 ucstring_destroy(tmps
);
1195 static int do_Clss_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1197 return do_item_type_class(c
, d
, zz
);
1200 static int do_name_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1202 de_ucstring
*tmps
= NULL
;
1203 struct flexible_id flid
;
1205 // I can't find any credible documentation of the 'name' reference format.
1206 // This code is based on reverse engineering, and may not be correct.
1208 tmps
= ucstring_create(c
);
1210 read_unicode_string(c
, d
, tmps
, zz
);
1211 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1212 ucstring_empty(tmps
);
1214 read_flexible_id_zz(c
, d
, zz
, &flid
);
1215 dbg_print_flexible_id(c
, d
, &flid
, "undocumented id");
1216 flexible_id_free_contents(c
, &flid
);
1218 read_unicode_string(c
, d
, tmps
, zz
);
1219 de_dbg(c
, "undocumented unicode string: \"%s\"", ucstring_getpsz_d(tmps
));
1221 ucstring_destroy(tmps
);
1225 static int do_rele_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1227 de_ucstring
*tmps
= NULL
;
1228 struct flexible_id flid
;
1231 tmps
= ucstring_create(c
);
1233 read_unicode_string(c
, d
, tmps
, zz
);
1234 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1235 ucstring_empty(tmps
);
1237 read_flexible_id_zz(c
, d
, zz
, &flid
);
1238 dbg_print_flexible_id(c
, d
, &flid
, "classID");
1239 flexible_id_free_contents(c
, &flid
);
1241 offs
= psd_geti32zz(zz
);
1242 de_dbg(c
, "offset: %d", (int)offs
);
1244 ucstring_destroy(tmps
);
1248 static int do_indx_reference(deark
*c
, lctx
*d
, zztype
*zz
)
1250 de_ucstring
*tmps
= NULL
;
1251 struct flexible_id flid
;
1254 // I can't find any official documentation of the 'indx' reference format.
1255 // This code may not be correct.
1257 tmps
= ucstring_create(c
);
1259 read_unicode_string(c
, d
, tmps
, zz
);
1260 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(tmps
));
1261 ucstring_empty(tmps
);
1263 read_flexible_id_zz(c
, d
, zz
, &flid
);
1264 dbg_print_flexible_id(c
, d
, &flid
, "undocumented id");
1265 flexible_id_free_contents(c
, &flid
);
1267 x
= psd_geti32zz(zz
);
1268 de_dbg(c
, "undocumented int: %d", (int)x
);
1270 ucstring_destroy(tmps
);
1274 // "Reference structure"
1275 static int do_item_type_obj(deark
*c
, lctx
*d
, zztype
*zz
)
1280 int saved_indent_level
;
1283 de_dbg_indent_save(c
, &saved_indent_level
);
1285 num_items
= psd_getu32zz(zz
);
1286 de_dbg(c
, "number of items in reference: %d", (int)num_items
);
1288 for(i
=0; i
<num_items
; i
++) {
1289 struct de_fourcc type4cc
;
1293 if(itempos
>= zz
->endpos
) goto done
;
1294 psd_read_fourcc_zz(c
, d
, zz
, &type4cc
);
1295 de_dbg(c
, "reference item[%d] '%s' at %d", (int)i
, type4cc
.id_dbgstr
, (int)itempos
);
1297 de_dbg_indent(c
, 1);
1300 switch(type4cc
.id
) {
1302 if(!do_Enmr_reference(c
, d
, &czz
)) goto done
;
1303 zz
->pos
+= zz_used(&czz
);
1306 if(!do_prop_reference(c
, d
, &czz
)) goto done
;
1307 zz
->pos
+= zz_used(&czz
);
1310 if(!do_name_reference(c
, d
, &czz
)) goto done
;
1311 zz
->pos
+= zz_used(&czz
);
1314 if(!do_Clss_reference(c
, d
, &czz
)) goto done
;
1315 zz
->pos
+= zz_used(&czz
);
1318 if(!do_rele_reference(c
, d
, &czz
)) goto done
;
1319 zz
->pos
+= zz_used(&czz
);
1322 if(!do_indx_reference(c
, d
, &czz
)) goto done
;
1323 zz
->pos
+= zz_used(&czz
);
1330 de_dbg_indent(c
, -1);
1335 de_dbg_indent_restore(c
, saved_indent_level
);
1339 // key_flid is relevant "key" identifier.
1340 static int do_descriptor_item_ostype_and_data(deark
*c
, lctx
*d
,
1341 const struct flexible_id
*key_flid
, zztype
*zz
, i64 itempos
)
1345 struct de_fourcc type4cc
;
1348 psd_read_fourcc_zz(c
, d
, zz
, &type4cc
);
1349 de_dbg(c
, "item OSType: '%s'", type4cc
.id_dbgstr
);
1353 switch(type4cc
.id
) {
1355 do_item_type_bool(c
, d
, &czz
);
1356 zz
->pos
+= zz_used(&czz
);
1359 do_item_type_long(c
, d
, &czz
);
1360 zz
->pos
+= zz_used(&czz
);
1363 do_item_type_doub(c
, d
, &czz
);
1364 zz
->pos
+= zz_used(&czz
);
1371 do_item_type_UntF(c
, d
, &czz
);
1372 zz
->pos
+= zz_used(&czz
);
1375 do_item_type_UnFl(c
, d
, &czz
);
1376 zz
->pos
+= zz_used(&czz
);
1379 do_item_type_TEXT(c
, d
, &czz
);
1380 zz
->pos
+= zz_used(&czz
);
1383 do_item_type_enum(c
, d
, &czz
);
1384 zz
->pos
+= zz_used(&czz
);
1387 ret
= do_item_type_VlLs(c
, d
, key_flid
, &czz
, itempos
);
1388 zz
->pos
+= zz_used(&czz
);
1393 ret
= do_item_type_descriptor(c
, d
, &czz
, 0);
1394 zz
->pos
+= zz_used(&czz
);
1398 // Undocumented type. Appears to contain a versioned descriptor.
1399 ret
= do_item_type_descriptor(c
, d
, zz
, 1);
1400 zz
->pos
+= zz_used(&czz
);
1404 ret
= do_item_type_obj(c
, d
, &czz
);
1405 zz
->pos
+= zz_used(&czz
);
1409 ret
= do_item_type_tdta(c
, d
, key_flid
, &czz
);
1410 zz
->pos
+= zz_used(&czz
);
1415 ret
= do_item_type_class(c
, d
, &czz
);
1416 zz
->pos
+= zz_used(&czz
);
1420 ret
= do_item_type_alis(c
, d
, &czz
);
1421 zz
->pos
+= zz_used(&czz
);
1424 // TODO: 'Pth ' (undocumented type)
1434 static int do_descriptor_item(deark
*c
, lctx
*d
, zztype
*zz
)
1436 struct flexible_id key
;
1443 read_flexible_id_zz(c
, d
, zz
, &key
);
1444 dbg_print_flexible_id(c
, d
, &key
, "key");
1447 ret
= do_descriptor_item_ostype_and_data(c
, d
, &key
, &czz
, itempos
);
1448 flexible_id_free_contents(c
, &key
);
1450 zz
->pos
+= zz_used(&czz
);
1455 // Read a "Descriptor" structure.
1456 // If has_version==1, the data begins with a 4-byte Descriptor Version field.
1457 // dscrname is extra debug text that will appear after the word "descriptor".
1458 // (Okay to use a shared zz, but use caution.)
1459 static int read_descriptor(deark
*c
, lctx
*d
, zztype
*zz
, int has_version
, const char *dscrname
)
1461 de_ucstring
*name_from_classid
= NULL
;
1462 struct flexible_id classid
;
1471 int saved_indent_level
;
1473 de_dbg_indent_save(c
, &saved_indent_level
);
1477 dv
= psd_getu32zz(zz
);
1483 de_dbg(c
, "descriptor%s at %d (version# at %d)", dscrname
, (int)dscr_pos
, (int)ver_pos
);
1486 de_dbg(c
, "descriptor%s at %d", dscrname
, (int)dscr_pos
);
1490 de_warn(c
, "Unsupported descriptor version: %d", (int)dv
);
1494 de_dbg_indent(c
, 1);
1496 name_from_classid
= ucstring_create(c
);
1497 read_unicode_string(c
, d
, name_from_classid
, zz
);
1498 if(name_from_classid
->len
> 0) {
1499 de_dbg(c
, "name from classID: \"%s\"", ucstring_getpsz_d(name_from_classid
));
1502 read_flexible_id_zz(c
, d
, zz
, &classid
);
1503 dbg_print_flexible_id(c
, d
, &classid
, "classID");
1504 flexible_id_free_contents(c
, &classid
);
1506 num_items
= psd_getu32zz(zz
);
1507 de_dbg(c
, "number of items in descriptor: %d", (int)num_items
);
1510 for(i
=0; i
<num_items
; i
++) {
1511 if(zz
->pos
>= zz
->endpos
) {
1512 de_dbg(c
, "[Expected %d descriptor items, only found %d.]", (int)num_items
, (int)i
);
1515 de_dbg(c
, "item[%d] at %d (for descriptor@%d)", (int)i
, (int)zz
->pos
, (int)dscr_pos
);
1516 de_dbg_indent(c
, 1);
1518 ret
= do_descriptor_item(c
, d
, &czz
);
1520 de_dbg(c
, "[Failed to fully decode descriptor item.]");
1522 de_dbg_indent(c
, -1);
1524 zz
->pos
+= zz_used(&czz
);
1530 de_dbg_indent_restore(c
, saved_indent_level
);
1531 ucstring_destroy(name_from_classid
);
1535 static void hrsrc_descriptor_with_version(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1537 read_descriptor(c
, d
, zz
, 1, "");
1540 static int do_slices_resource_block(deark
*c
, lctx
*d
, i64 slice_idx
, zztype
*zz
)
1542 de_ucstring
*s
= NULL
;
1543 i64 id
, group_id
, origin
, slice_type
;
1546 s
= ucstring_create(c
);
1548 id
= psd_getu32zz(zz
);
1549 de_dbg(c
, "id: %d", (int)id
);
1551 group_id
= psd_getu32zz(zz
);
1552 de_dbg(c
, "group id: %d", (int)group_id
);
1554 origin
= psd_getu32zz(zz
);
1555 de_dbg(c
, "origin: %d", (int)origin
);
1559 layer_id
= psd_getu32zz(zz
);
1560 de_dbg(c
, "associated layer id: %d", (int)layer_id
);
1563 read_unicode_string(c
, d
, s
, zz
); // Name
1565 de_dbg(c
, "name: \"%s\"", ucstring_getpsz(s
));
1569 slice_type
= psd_getu32zz(zz
);
1570 de_dbg(c
, "type: %d", (int)slice_type
);
1572 read_rectangle_ltrb(c
, d
, zz
, "position");
1574 read_unicode_string(c
, d
, s
, zz
); // URL
1577 read_unicode_string(c
, d
, s
, zz
); // Target
1580 read_unicode_string(c
, d
, s
, zz
); // Message
1583 read_unicode_string(c
, d
, s
, zz
); // Alt Tag
1586 zz
->pos
+= 1; // Flag: Cell text is HTML
1588 read_unicode_string(c
, d
, s
, zz
); // Cell text
1591 zz
->pos
+= 4; // Horizontal alignment
1592 zz
->pos
+= 4; // Horizontal alignment
1593 zz
->pos
+= 4; // Alpha color, Red, Green, Blue
1595 if(zz
->pos
> zz
->endpos
) goto done
;
1599 ucstring_destroy(s
);
1603 static void do_slices_v6(deark
*c
, lctx
*d
, zztype
*zz
)
1607 de_ucstring
*name_of_group_of_slices
= NULL
;
1611 zz
->pos
+= 4; // version (already read)
1612 read_rectangle_tlbr(c
, d
, zz
, "bounding rectangle");
1613 if(zz
->pos
>= zz
->endpos
) goto done
;
1615 name_of_group_of_slices
= ucstring_create(c
);
1616 read_unicode_string(c
, d
, name_of_group_of_slices
, zz
);
1617 de_dbg(c
, "name of group of slices: \"%s\"",
1618 ucstring_getpsz_d(name_of_group_of_slices
));
1619 if(zz
->pos
>= zz
->endpos
) goto done
;
1621 num_slices
= psd_getu32zz(zz
);
1622 de_dbg(c
, "number of slices: %d", (int)num_slices
);
1624 for(i
=0; i
<num_slices
; i
++) {
1625 if(zz
->pos
>= zz
->endpos
) {
1626 de_dbg(c
, "[Expected %d slices, only found %d]", (int)num_slices
, (int)i
);
1629 de_dbg(c
, "slice[%d] at %d", (int)i
, (int)zz
->pos
);
1630 de_dbg_indent(c
, 1);
1632 do_slices_resource_block(c
, d
, i
, &czz
);
1633 de_dbg_indent(c
, -1);
1634 zz
->pos
+= zz_used(&czz
);
1637 // The PSD spec seems to show that a Descriptor can (optionally) appear after
1638 // every slice resource block.
1639 // But if that were true, there would seem to be no way to tell whether a slice
1640 // is followed by a descriptor, or immediately by the next slice.
1641 // Fortunately, evidence suggests that a Descriptor can only appear after the
1642 // last slice in the array.
1644 if(zz
->pos
>= zz
->endpos
) goto done
;
1646 ret
= read_descriptor(c
, d
, zz
, 1, " (for slices)");
1650 ucstring_destroy(name_of_group_of_slices
);
1653 static void do_slices_v7_8(deark
*c
, lctx
*d
, zztype
*zz
)
1655 zz
->pos
+= 4; // Skip version number (7 or 8), already read.
1656 read_descriptor(c
, d
, zz
, 1, "");
1659 static void hrsrc_slices(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1663 if(zz_avail(zz
)<4) return;
1664 sver
= psd_getu32(zz
->pos
);
1665 de_dbg(c
, "slices resource format version: %d", (int)sver
);
1668 do_slices_v6(c
, d
, zz
);
1670 else if(sver
==7 || sver
==8) {
1671 do_slices_v7_8(c
, d
, zz
);
1675 static void hrsrc_thumbnail(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1683 if(zz_avail(zz
)<=28) goto done
;
1685 fmt
= psd_getu32(zz
->pos
);
1688 de_dbg(c
, "thumbnail in unsupported format (%d) found", (int)fmt
);
1694 dlen
= zz_avail(zz
);
1696 if(ri
->id
==0x0409) {
1697 ext
= "psdthumb_rbswap.jpg";
1698 if(c
->extract_policy
!=DE_EXTRACTPOLICY_MAINONLY
) {
1699 de_info(c
, "Note: This Photoshop thumbnail uses nonstandard colors, "
1700 "and may not look right.");
1704 ext
= "psdthumb.jpg";
1707 outf
= dbuf_create_output_file(c
, ext
, NULL
, DE_CREATEFLAG_IS_AUX
);
1709 if(ri
->id
==0x0409 && d
->jpeg_rbswap_mode
&& dlen
>=11 &&
1710 !dbuf_memcmp(c
->infile
, dpos
, "\xff\xd8\xff\xe0\x00\x10" "JFIF" "\x00", 11))
1712 // If we were to extract this image as-is, there will be no way to tell
1713 // later that the red/blue channels are swapped. So, we have this feature
1714 // to mark it by inserting a custom segment (after the JFIF segment).
1715 dbuf_copy(c
->infile
, dpos
, 20, outf
);
1716 dbuf_write(outf
, (const u8
*)"\xff\xe1\x00\x10" "Deark_RB_swap\0", 18);
1717 dbuf_copy(c
->infile
, dpos
+20, dlen
-20, outf
);
1720 dbuf_copy(c
->infile
, dpos
, dlen
, outf
);
1727 // Handler for any resource that consists of a 1-byte numeric value
1728 static void hrsrc_byte(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1731 if(zz_avail(zz
)!=1) return;
1732 b
= psd_getbytezz(zz
);
1733 de_dbg(c
, "%s: %d", ri
->idname
, (int)b
);
1736 static void hrsrc_uint16(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1739 if(zz_avail(zz
)!=2) return;
1740 n
= psd_getu16zz(zz
);
1741 de_dbg(c
, "%s: %d", ri
->idname
, (int)n
);
1744 static void hrsrc_uint32(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1747 if(zz_avail(zz
)!=4) return;
1748 n
= psd_getu32zz(zz
);
1749 de_dbg(c
, "%s: %d", ri
->idname
, (int)n
);
1752 // Handler for any resource that consists of a single "Unicode string".
1753 static void hrsrc_unicodestring(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1755 de_ucstring
*s
= NULL
;
1757 s
= ucstring_create(c
);
1758 read_unicode_string(c
, d
, s
, zz
);
1759 de_dbg(c
, "%s: \"%s\"", ri
->idname
, ucstring_getpsz_d(s
));
1760 ucstring_destroy(s
);
1763 // Handler for the "Unicode Alpha Names" resource, which the documentation
1764 // incorrectly says is a single Unicode string.
1765 static void hrsrc_unicodestring_multi(deark
*c
, lctx
*d
, zztype
*zz
,
1766 const struct rsrc_info
*ri
)
1768 de_ucstring
*s
= NULL
;
1771 s
= ucstring_create(c
);
1772 while(zz_avail(zz
)>=4) {
1774 read_unicode_string(c
, d
, s
, zz
);
1775 de_dbg(c
, "%s[%d]: \"%s\"", ri
->idname
, idx
, ucstring_getpsz_d(s
));
1778 ucstring_destroy(s
);
1781 // Handler for any resource that consists of a single "Pascal string".
1782 static void hrsrc_pascalstring(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1784 de_ucstring
*s
= NULL
;
1786 s
= ucstring_create(c
);
1787 read_pascal_string_to_ucstring(c
, d
, s
, zz
);
1788 de_dbg(c
, "%s: \"%s\"", ri
->idname
, ucstring_getpsz(s
));
1789 ucstring_destroy(s
);
1792 // Raw byte-oriented text
1793 static void hrsrc_plaintext(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1795 de_ucstring
*s
= NULL
;
1797 s
= ucstring_create(c
);
1798 dbuf_read_to_ucstring_n(c
->infile
, zz
->pos
, zz_avail(zz
), DE_DBG_MAX_STRLEN
,
1799 s
, 0, d
->input_encoding
);
1800 de_dbg(c
, "%s: \"%s\"", ri
->idname
, ucstring_getpsz(s
));
1801 ucstring_destroy(s
);
1804 static void hrsrc_urllist(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1806 de_ucstring
*s
= NULL
;
1810 count
= psd_getu32zz(zz
);
1811 de_dbg(c
, "URL count: %d", (int)count
);
1813 s
= ucstring_create(c
);
1815 for(i
=0; i
<count
; i
++) {
1816 struct de_fourcc url4cc
;
1819 // undocumented field, seems to be a fourcc
1820 psd_read_fourcc_zz(c
, d
, zz
, &url4cc
);
1822 id
= psd_getu32zz(zz
);
1824 read_unicode_string(c
, d
, s
, zz
);
1825 de_dbg(c
, "URL[%d]: '%s', id=%d, value=\"%s\"", (int)i
,
1826 url4cc
.id_dbgstr
, (int)id
, ucstring_getpsz(s
));
1830 ucstring_destroy(s
);
1833 static void hrsrc_versioninfo(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1837 de_ucstring
*s
= NULL
;
1839 ver
= psd_getu32zz(zz
);
1840 de_dbg(c
, "version: %d", (int)ver
);
1842 b
= psd_getbytezz(zz
);
1843 de_dbg(c
, "hasRealMergedData: %d", (int)b
);
1845 s
= ucstring_create(c
);
1846 read_unicode_string(c
, d
, s
, zz
);
1847 de_dbg(c
, "writer name: \"%s\"", ucstring_getpsz(s
));
1850 read_unicode_string(c
, d
, s
, zz
);
1851 de_dbg(c
, "reader name: \"%s\"", ucstring_getpsz(s
));
1853 file_ver
= psd_getu32zz(zz
);
1854 de_dbg(c
, "file version: %d", (int)file_ver
);
1856 ucstring_destroy(s
);
1859 static void hrsrc_printscale(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1862 double xloc
, yloc
, scale
;
1863 if(zz_avail(zz
)!=14) return;
1864 style
= psd_getu16zz(zz
);
1865 de_dbg(c
, "style: %d", (int)style
);
1866 xloc
= dbuf_getfloat32x(c
->infile
, zz
->pos
, d
->is_le
);
1868 yloc
= dbuf_getfloat32x(c
->infile
, zz
->pos
, d
->is_le
);
1870 de_dbg(c
, "location: (%f,%f)", xloc
, yloc
);
1871 scale
= dbuf_getfloat32x(c
->infile
, zz
->pos
, d
->is_le
);
1873 de_dbg(c
, "scale: %f", scale
);
1876 static void hrsrc_pixelaspectratio(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1880 if(zz_avail(zz
)!=12) return;
1881 version
= psd_getu32zz(zz
);
1882 de_dbg(c
, "version: %d", (int)version
);
1883 ratio
= dbuf_getfloat64x(c
->infile
, zz
->pos
, d
->is_le
);
1885 de_dbg(c
, "x/y: %f", ratio
);
1888 static void hrsrc_layerselectionids(deark
*c
, lctx
*d
, zztype
*zz
, const struct rsrc_info
*ri
)
1893 if(zz_avail(zz
)<2) return;
1894 count
= psd_getu16zz(zz
);
1895 de_dbg(c
, "count: %d", (int)count
);
1896 if(zz_avail(zz
)<4*count
) return;
1897 for(i
=0; i
<count
; i
++) {
1899 lyid
= psd_getu32zz(zz
);
1900 de_dbg(c
, "layer id[%d]: %u", (int)i
, (unsigned int)lyid
);
1904 static int do_image_resource(deark
*c
, lctx
*d
, zztype
*zz
)
1908 struct rsrc_info ri
;
1909 de_ucstring
*blkname
= NULL
;
1910 struct de_fourcc sig4cc
;
1911 const char *signame
= "Photoshop";
1915 // Check the "8BIM" (etc.) signature.
1916 // TODO: Maybe we should allow arbitrary signatures, but restricting it to
1917 // known signatures lets us know if the parser has gone off the rails.
1918 psd_read_fourcc_zz(c
, d
, zz
, &sig4cc
);
1919 if(sig4cc
.id
==CODE_8BIM
) {
1922 else if(sig4cc
.id
==CODE_AgHg
) { // Seen in Photoshop Elements files
1925 else if(sig4cc
.id
==CODE_DCSR
) { // ExifTool says this exists
1928 else if(sig4cc
.id
==CODE_MeSa
) { // Image Ready resource?
1931 else if(sig4cc
.id
==CODE_PHUT
) { // PhotoDeluxe resource?
1935 de_warn(c
, "Bad Photoshop resource block signature '%s' at %d",
1936 sig4cc
.id_sanitized_sz
, (int)zz
->startpos
);
1940 resource_id
= psd_getu16zz(zz
);
1942 // Read resource block name. A "Pascal string" padded to an even number of bytes.
1943 blkname
= ucstring_create(c
);
1945 read_pascal_string_to_ucstring(c
, d
, blkname
, &czz
);
1946 zz
->pos
+= de_pad_to_2(zz_used(&czz
));
1948 block_data_len
= psd_getu32zz(zz
);
1950 // TODO: Are resource_ids "namespaced" based on the block signature?
1951 lookup_rsrc(sig4cc
.id
, (u16
)resource_id
, &ri
);
1953 de_dbg(c
, "%s rsrc 0x%04x (%s) pos=%d blkname=\"%s\" dpos=%d dlen=%d",
1954 signame
, (int)resource_id
, ri
.idname
, (int)zz
->startpos
,
1955 ucstring_getpsz(blkname
), (int)zz
->pos
, (int)block_data_len
);
1957 if(zz
->pos
+block_data_len
> zz
->endpos
) {
1958 de_warn(c
, "PSD rsrc exceeds its parent's bounds. Ends at %"I64_FMT
1959 ", parent ends at %"I64_FMT
".", zz
->pos
+block_data_len
, zz
->endpos
);
1962 de_dbg_indent(c
, 1);
1964 zz_init_with_len(&czz
, zz
, block_data_len
);
1965 ri
.hfn(c
, d
, &czz
, &ri
);
1967 else if(ri
.flags
&0x0004) {
1968 zz_init_with_len(&czz
, zz
, block_data_len
);
1969 hrsrc_descriptor_with_version(c
, d
, &czz
, &ri
);
1971 else if(c
->debug_level
>=2) {
1972 de_dbg_hexdump(c
, c
->infile
, zz
->pos
, block_data_len
, 256, NULL
,
1973 (ri
.flags
&0x0010)?0x0:0x1);
1975 de_dbg_indent(c
, -1);
1977 zz
->pos
+= de_pad_to_2(block_data_len
);
1982 if(blkname
) ucstring_destroy(blkname
);
1986 static void do_image_resource_blocks(deark
*c
, lctx
*d
, zztype
*zz
)
1991 if(zz
->pos
>=zz
->endpos
) break;
1993 if(!do_image_resource(c
, d
, &czz
)) break;
1994 zz
->pos
+= zz_used(&czz
);
1998 // Layer mask / adjustment layer data
1999 static void do_layer_mask_data(deark
*c
, lctx
*d
, zztype
*zz
)
2002 dlen
= psd_getu32zz(zz
);
2003 de_dbg(c
, "layer mask data size: %d", (int)dlen
);
2007 static void do_layer_blending_ranges(deark
*c
, lctx
*d
, zztype
*zz
)
2010 dlen
= psd_getu32zz(zz
);
2011 de_dbg(c
, "layer blending ranges data size: %d", (int)dlen
);
2015 static void do_layer_name(deark
*c
, lctx
*d
, zztype
*zz
)
2017 de_ucstring
*s
= NULL
;
2019 // "Pascal string, padded to a multiple of 4 bytes"
2020 s
= ucstring_create(c
);
2021 read_pascal_string_to_ucstring(c
, d
, s
, zz
);
2022 de_dbg(c
, "layer name: \"%s\"", ucstring_getpsz(s
));
2023 zz
->pos
= zz
->startpos
+ de_pad_to_4(zz_used(zz
));
2024 ucstring_destroy(s
);
2027 struct channel_data
{
2032 static int do_layer_record(deark
*c
, lctx
*d
, zztype
*zz
, struct channel_data
*cd
)
2036 struct de_fourcc tmp4cc
;
2044 read_rectangle_tlbr(c
, d
, zz
, "bounding rectangle");
2046 nchannels
= psd_getu16zz(zz
);
2047 de_dbg(c
, "number of channels: %d", (int)nchannels
);
2049 for(i
=0; i
<nchannels
; i
++) {
2050 ch_id
= psd_geti16zz(zz
);
2051 ch_dlen
= psd_getu32or64zz(c
, d
, zz
);
2052 de_dbg(c
, "channel[%d] id=%d, data len=%"I64_FMT
"", (int)i
, (int)ch_id
, ch_dlen
);
2053 de_sanitize_length(&ch_dlen
);
2055 cd
->total_len
+= ch_dlen
;
2058 psd_read_fourcc_zz(c
, d
, zz
, &tmp4cc
);
2059 if(tmp4cc
.id
!= CODE_8BIM
) {
2060 de_warn(c
, "Expected blend mode signature not found at %d", (int)(zz
->pos
-4));
2064 psd_read_fourcc_zz(c
, d
, zz
, &tmp4cc
);
2065 de_dbg(c
, "blend mode: '%s'", tmp4cc
.id_dbgstr
);
2067 b
= psd_getbytezz(zz
);
2068 de_dbg(c
, "opacity: %d", (int)b
);
2070 b
= psd_getbytezz(zz
);
2071 de_dbg(c
, "clipping: %d", (int)b
);
2073 b
= psd_getbytezz(zz
);
2074 de_dbg(c
, "flags: 0x%02x", (unsigned int)b
);
2076 zz
->pos
+= 1; // filler
2078 extra_data_len
= psd_getu32zz(zz
);
2080 if(zz
->pos
+ extra_data_len
> zz
->endpos
) {
2081 de_warn(c
, "Malformed layer record at %d", (int)zz
->startpos
);
2085 zz_init_with_len(&extradatazz
, zz
, extra_data_len
);
2086 zz
->pos
= extradatazz
.endpos
;
2088 zz_init(&czz
, &extradatazz
);
2089 do_layer_mask_data(c
, d
, &czz
);
2090 extradatazz
.pos
+= zz_used(&czz
);
2092 zz_init(&czz
, &extradatazz
);
2093 do_layer_blending_ranges(c
, d
, &czz
);
2094 extradatazz
.pos
+= zz_used(&czz
);
2096 zz_init(&czz
, &extradatazz
);
2097 do_layer_name(c
, d
, &czz
);
2098 extradatazz
.pos
+= zz_used(&czz
);
2100 if(extradatazz
.pos
< extradatazz
.endpos
) {
2101 // The rest of the layer record data seems to be undocumented,
2102 // or unclearly documented.
2103 de_dbg(c
, "layer record tagged blocks at %d, len=%d",
2104 (int)extradatazz
.pos
, (int)(extradatazz
.endpos
-extradatazz
.pos
));
2105 de_dbg_indent(c
, 1);
2106 zz_init(&czz
, &extradatazz
);
2107 do_tagged_blocks(c
, d
, &czz
, 0);
2108 de_dbg_indent(c
, -1);
2116 static int do_layer_info_section(deark
*c
, lctx
*d
, zztype
*zz
, int has_len_field
)
2120 i64 layer_count_raw
, layer_count
;
2121 int saved_indent_level
;
2122 int merged_result_flag
;
2126 struct channel_data
*cd
= NULL
;
2128 de_dbg_indent_save(c
, &saved_indent_level
);
2129 if(zz_avail(zz
)<4) goto done
;
2131 de_dbg(c
, "layer info section at %d", (int)zz
->pos
);
2132 de_dbg_indent(c
, 1);
2135 layer_info_len
= psd_getu32or64zz(c
, d
, zz
);
2136 de_dbg(c
, "length of layer info section: %d", (int)layer_info_len
);
2137 de_sanitize_length(&layer_info_len
);
2140 layer_info_len
= zz_avail(zz
);
2142 zz_init_with_len(&datazz
, zz
, layer_info_len
);
2143 zz
->pos
+= layer_info_len
;
2146 if(datazz
.pos
>=datazz
.endpos
) {
2147 // If the length field is 0, it's legal for this section to end here.
2151 layer_count_raw
= psd_geti16zz(&datazz
);
2152 if(layer_count_raw
<0) {
2153 merged_result_flag
= 1;
2154 layer_count
= -layer_count_raw
;
2157 merged_result_flag
= 0;
2158 layer_count
= layer_count_raw
;
2160 de_dbg(c
, "layer count: %d", (int)layer_count
);
2161 de_dbg(c
, "merged result flag: %d", (int)merged_result_flag
);
2163 // Due to the recursive possibilities of PSD format, it would probably
2164 // be a bad idea to store this channel information in the 'd' struct.
2165 // Instead, we'll use a local variable.
2166 cd
= de_malloc(c
, sizeof(struct channel_data
));
2167 cd
->num_channels
= 0;
2170 for(layer_idx
=0; layer_idx
<layer_count
; layer_idx
++) {
2171 de_dbg(c
, "layer record[%d] at %d", (int)layer_idx
, (int)datazz
.pos
);
2172 de_dbg_indent(c
, 1);
2173 zz_init(&czz
, &datazz
);
2174 if(!do_layer_record(c
, d
, &czz
, cd
))
2176 datazz
.pos
+= zz_used(&czz
);
2177 de_dbg_indent(c
, -1);
2180 de_dbg(c
, "channel image data records at %d, count=%d, total len=%"I64_FMT
"",
2181 (int)datazz
.pos
, (int)cd
->num_channels
, cd
->total_len
);
2184 de_dbg_indent_restore(c
, saved_indent_level
);
2189 static void do_uint32_block(deark
*c
, lctx
*d
, zztype
*zz
,
2190 const struct de_fourcc
*blk4cc
, const char *name
)
2194 if(zz_avail(zz
)!=4) return;
2195 value
= psd_getu32zz(zz
);
2196 de_dbg(c
, "%s: %d", name
, (int)value
);
2199 static void do_boolean_block(deark
*c
, lctx
*d
, zztype
*zz
,
2200 const struct de_fourcc
*blk4cc
, const char *name
)
2206 if(len
<1 || len
>4) return;
2207 value
= psd_getbytezz(zz
);
2208 de_dbg(c
, "%s: %d", name
, (int)value
);
2211 static void do_fourcc_block(deark
*c
, lctx
*d
, zztype
*zz
,
2212 const struct de_fourcc
*blk4cc
, const char *name
)
2214 struct de_fourcc fourcc
;
2216 if(zz_avail(zz
)!=4) return;
2217 psd_read_fourcc_zz(c
, d
, zz
, &fourcc
);
2218 de_dbg(c
, "%s: '%s'", name
, fourcc
.id_dbgstr
);
2221 static void do_Layr_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2223 // "Layer info" section, but starting with the "Layer count" field
2224 do_layer_info_section(c
, d
, zz
, 0);
2227 static void extract_linked_layer_blob(deark
*c
, lctx
*d
, i64 pos
, i64 len
)
2229 const char *ext
= "layer.bin";
2234 // Sniff the file type.
2235 // (The "File Type" FourCC is not reliable.)
2236 de_read(buf
, pos
, sizeof(buf
));
2237 if(!de_memcmp(buf
, "8BPS\x00\x01", 6)) {
2240 else if(!de_memcmp(buf
, "8BPS\x00\x02", 6)) {
2243 else if(!de_memcmp(buf
, "\x89\x50\x4e\x47", 4)) {
2246 else if(!de_memcmp(buf
, "\xff\xd8\xff", 3)) {
2249 else if(!de_memcmp(buf
, "%PDF", 4)) {
2253 // TODO: Maybe we should try to use the "original filename" field, somehow,
2254 // to construct our filename.
2255 dbuf_create_file_from_slice(c
->infile
, pos
, len
, ext
,
2256 NULL
, DE_CREATEFLAG_IS_AUX
);
2259 static int do_one_linked_layer(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2264 u8 file_open_descr_flag
;
2265 struct de_fourcc type4cc
;
2266 struct de_fourcc tmp4cc
;
2267 de_ucstring
*s
= NULL
;
2270 dlen
= psd_geti64zz(zz
);
2271 de_dbg(c
, "length: %"I64_FMT
"", dlen
);
2272 de_sanitize_length(&dlen
);
2273 if(dlen
<8 || zz
->pos
+dlen
>zz
->endpos
) {
2274 de_warn(c
, "Bad linked layer size %"I64_FMT
" at %"I64_FMT
"", dlen
, zz
->startpos
);
2278 zz_init_with_len(&datazz
, zz
, dlen
);
2280 // Seems to be padded to a multiple of 4 bytes. (The spec says nothing
2282 zz
->pos
+= de_pad_to_4(dlen
);
2285 psd_read_fourcc_zz(c
, d
, &datazz
, &type4cc
);
2286 de_dbg(c
, "type: '%s'", type4cc
.id_dbgstr
);
2288 ver
= psd_getu32zz(&datazz
);
2289 de_dbg(c
, "version: %d", (int)ver
);
2291 s
= ucstring_create(c
);
2292 read_pascal_string_to_ucstring(c
, d
, s
, &datazz
);
2293 de_dbg(c
, "unique id: \"%s\"", ucstring_getpsz(s
));
2296 read_unicode_string(c
, d
, s
, &datazz
);
2297 de_dbg(c
, "original file name: \"%s\"", ucstring_getpsz(s
));
2299 psd_read_fourcc_zz(c
, d
, &datazz
, &tmp4cc
);
2300 de_dbg(c
, "file type: '%s'", tmp4cc
.id_dbgstr
);
2302 psd_read_fourcc_zz(c
, d
, &datazz
, &tmp4cc
);
2303 de_dbg(c
, "file creator: '%s'", tmp4cc
.id_dbgstr
);
2305 dlen2
= psd_geti64zz(&datazz
);
2306 de_dbg(c
, "length2: %"I64_FMT
"", dlen2
);
2307 de_sanitize_length(&dlen2
);
2308 if(dlen2
<0) goto done
;
2310 file_open_descr_flag
= psd_getbytezz(&datazz
);
2311 de_dbg(c
, "has file open descriptor: %d", (int)file_open_descr_flag
);
2313 if(file_open_descr_flag
) {
2314 if(!read_descriptor(c
, d
, &datazz
, 1, " (of open parameters)")) {
2319 if(type4cc
.id
!=CODE_liFD
) {
2320 // TODO: liFA and liFE need special handling.
2321 de_dbg(c
, "[this linked layer type is not supported]");
2325 de_dbg(c
, "raw file bytes at %"I64_FMT
", len=%"I64_FMT
"", datazz
.pos
, dlen2
);
2326 extract_linked_layer_blob(c
, d
, datazz
.pos
, dlen2
);
2328 // TODO: There may be more fields after this, depending on the version.
2331 ucstring_destroy(s
);
2335 static void do_lnk2_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2340 while(zz
->pos
<zz
->endpos
) {
2341 de_dbg(c
, "linked layer data at %"I64_FMT
"", zz
->pos
);
2342 de_dbg_indent(c
, 1);
2344 ret
= do_one_linked_layer(c
, d
, &czz
, blk4cc
);
2345 de_dbg_indent(c
, -1);
2347 zz
->pos
+= zz_used(&czz
);
2351 static void do_vm_array(deark
*c
, lctx
*d
, zztype
*zz
)
2354 i64 dlen
, idata_len
;
2357 zz
->pos
+= 4; // Skip array-is-written flag (already processed)
2359 dlen
= psd_getu32zz(zz
);
2360 de_dbg(c
, "length: %d", (int)dlen
);
2361 if(dlen
==0) goto done
;
2363 saved_pos
= zz
->pos
;
2365 n
= psd_getu32zz(zz
);
2366 de_dbg(c
, "depth: %d", (int)n
);
2368 read_rectangle_tlbr(c
, d
, zz
, "rectangle");
2370 n
= psd_getu16zz(zz
);
2371 de_dbg(c
, "depth: %d", (int)n
);
2373 n
= (i64
)psd_getbytezz(zz
);
2374 dbg_print_compression_method(c
, d
, n
);
2376 idata_len
= saved_pos
+ dlen
- zz
->pos
;
2377 de_dbg(c
, "[%d bytes of data at %d]", (int)idata_len
, (int)zz
->pos
);
2379 zz
->pos
= saved_pos
+ dlen
;
2384 static void do_vm_array_list(deark
*c
, lctx
*d
, zztype
*zz
)
2392 de_dbg(c
, "virtual memory array list at %d, len=%"I64_FMT
"", (int)zz
->pos
,
2394 de_dbg_indent(c
, 1);
2396 ver
= psd_getu32zz(zz
);
2397 de_dbg(c
, "version: %d", (int)ver
);
2399 dlen
= psd_getu32zz(zz
);
2400 de_dbg(c
, "length: %d", (int)dlen
);
2402 read_rectangle_tlbr(c
, d
, zz
, "rectangle");
2404 num_channels
= psd_getu32zz(zz
);
2405 de_dbg(c
, "number of channels: %d", (int)num_channels
);
2407 for(i
=0; i
<num_channels
+2; i
++) {
2410 // Look ahead at the array-is-written flag.
2411 is_written
= psd_getu32(zz
->pos
);
2413 de_dbg(c
, "virtual memory array[%d] at %d%s", (int)i
, (int)zz
->pos
,
2414 is_written
?"":" (empty)");
2417 de_dbg_indent(c
, 1);
2418 do_vm_array(c
, d
, &czz
);
2419 de_dbg_indent(c
, -1);
2420 zz
->pos
+= zz_used(&czz
);
2427 de_dbg_indent(c
, -1);
2430 // The main part of a "pattern" object, starting with the version and
2431 // color_mode[l] fields.
2432 static int do_pattern_internal(deark
*c
, lctx
*d
, zztype
*zz
)
2437 de_ucstring
*s
= NULL
;
2438 zztype vmalzz
; // for virtual memory array list
2441 ver
= psd_getu32zz(zz
);
2442 de_dbg(c
, "version: %d", (int)ver
);
2443 if(ver
!=1) goto done
;
2445 pat_color_mode
= psd_getu32zz(zz
);
2446 de_dbg(c
, "color mode: %d (%s)", (int)pat_color_mode
, get_colormode_name(pat_color_mode
));
2448 h
= psd_getu16zz(zz
);
2449 w
= psd_getu16zz(zz
);
2450 de_dbg_dimensions(c
, w
, h
);
2452 s
= ucstring_create(c
);
2453 read_unicode_string(c
, d
, s
, zz
);
2454 de_dbg(c
, "name: \"%s\"", ucstring_getpsz_d(s
));
2457 read_pascal_string_to_ucstring(c
, d
, s
, zz
);
2458 de_dbg(c
, "id: \"%s\"", ucstring_getpsz_d(s
));
2460 if(pat_color_mode
==PSD_CM_PALETTE
) {
2461 de_dbg(c
, "palette at %d", (int)zz
->pos
);
2465 zz_init(&vmalzz
, zz
);
2466 do_vm_array_list(c
, d
, &vmalzz
);
2467 zz
->pos
+= zz_used(&vmalzz
);
2470 ucstring_destroy(s
);
2474 // Decode a single "pattern" object, starting with the "length" field for this
2476 static int do_pattern(deark
*c
, lctx
*d
, zztype
*zz
, i64 pattern_idx
)
2479 zztype datazz
; // zz for the pattern data (minus the length field)
2482 if(zz_avail(zz
)<16) goto done
;
2484 de_dbg(c
, "pattern[%d] at %d", (int)pattern_idx
, (int)zz
->pos
);
2485 de_dbg_indent(c
, 1);
2487 pat_dlen
= psd_getu32zz(zz
);
2488 de_dbg(c
, "length: %d", (int)pat_dlen
);
2490 zz_init_with_len(&datazz
, zz
, pat_dlen
);
2492 do_pattern_internal(c
, d
, &datazz
);
2494 zz
->pos
+= de_pad_to_4(pat_dlen
);
2496 de_dbg_indent(c
, -1);
2503 static void do_pattern_sequence(deark
*c
, lctx
*d
, zztype
*zz
)
2510 if(zz_avail(zz
)<16) break;
2512 if(!do_pattern(c
, d
, &czz
, pattern_idx
)) {
2515 zz
->pos
+= zz_used(&czz
);
2520 static void do_Patt_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*xblk4cc
)
2522 do_pattern_sequence(c
, d
, zz
);
2525 // Process a v6.1 'samp' block, starting right after the ID.
2526 static void do_samp_block_v61stuff(deark
*c
, lctx
*d
, zztype
*zz
)
2531 // This code is based on guesswork, and may not be correct.
2533 zz
->pos
+= 8; // 8 unknown bytes
2535 // Note the similarity to vm_array.
2537 n
= psd_getu16zz(zz
);
2538 de_dbg(c
, "depth: %d", (int)n
);
2540 read_rectangle_tlbr(c
, d
, zz
, "rectangle");
2542 n
= psd_getu16zz(zz
);
2543 de_dbg(c
, "depth: %d", (int)n
);
2545 n
= (i64
)psd_getbytezz(zz
);
2546 dbg_print_compression_method(c
, d
, n
);
2548 idata_len
= zz_avail(zz
);
2549 de_dbg(c
, "[%d bytes of data at %d]", (int)idata_len
, (int)zz
->pos
);
2553 // Process a v6.2 'samp' block, starting right after the ID.
2554 static void do_samp_block_v62stuff(deark
*c
, lctx
*d
, zztype
*zz
)
2559 // This code is based on guesswork, and may not be correct.
2561 // I don't know what the first 4 bytes are for. Observed to be 00 01 00 00.
2562 x
= psd_getu32zz(zz
);
2563 if(x
!= 0x00010000) {
2568 do_vm_array_list(c
, d
, &czz
);
2571 static void do_samp_block(deark
*c
, lctx
*d
, zztype
*zz
)
2574 int saved_indent_level
;
2575 de_ucstring
*tmps
= NULL
;
2578 // Note: This code is based on guesswork, and may be incorrect.
2580 de_dbg_indent_save(c
, &saved_indent_level
);
2581 tmps
= ucstring_create(c
);
2586 zztype datazz
; // zz for the item data (minus the length field)
2588 if(zz
->pos
+16 > zz
->endpos
) break;
2590 de_dbg(c
, "item[%d] at %d", (int)item_idx
, (int)zz
->pos
);
2591 de_dbg_indent(c
, 1);
2593 item_data_len2
= psd_getu32zz(zz
);
2594 de_dbg(c
, "length: %d", (int)item_data_len2
);
2596 zz_init_with_len(&datazz
, zz
, item_data_len2
);
2598 ucstring_empty(tmps
);
2599 read_pascal_string_to_ucstring(c
, d
, tmps
, &datazz
);
2600 de_dbg(c
, "id: \"%s\"", ucstring_getpsz_d(tmps
));
2602 if(d
->abr_major_ver
==6 && d
->abr_minor_ver
<=1) {
2603 zz_init(&czz
, &datazz
);
2604 do_samp_block_v61stuff(c
, d
, &czz
);
2606 else if(d
->abr_major_ver
>6 || (d
->abr_major_ver
==6 && d
->abr_minor_ver
>=2)) {
2607 zz_init(&czz
, &datazz
);
2608 do_samp_block_v62stuff(c
, d
, &czz
);
2611 zz
->pos
+= de_pad_to_4(item_data_len2
);
2613 de_dbg_indent(c
, -1);
2617 ucstring_destroy(tmps
);
2618 de_dbg_indent_restore(c
, saved_indent_level
);
2621 static void do_lrFX_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2627 struct de_fourcc sig4cc
;
2629 ver
= psd_getu16zz(zz
);
2630 if(ver
!=0) goto done
;
2632 count
= psd_getu16zz(zz
);
2633 de_dbg(c
, "effects count: %d", (int)count
);
2635 for(i
=0; i
<count
; i
++) {
2639 if(zz
->pos
>=zz
->endpos
) goto done
;
2642 sig
= (u32
)psd_getu32zz(zz
);
2643 if(sig
!=CODE_8BIM
) {
2644 de_warn(c
, "Bad 'effects' block signature at %d", (int)zz
->pos
);
2648 psd_read_fourcc_zz(c
, d
, zz
, &sig4cc
);
2650 dlen
= psd_getu32zz(zz
);
2652 de_dbg(c
, "effects[%d] '%s' at %d, dpos=%d, dlen=%d", (int)i
, sig4cc
.id_dbgstr
,
2653 (int)epos
, (int)zz
->pos
, (int)dlen
);
2661 static void do_fxrp_block(deark
*c
, lctx
*d
, zztype
*zz
)
2665 if(zz_avail(zz
)!=16) return;
2666 v
[0] = dbuf_getfloat64x(c
->infile
, zz
->pos
, d
->is_le
);
2668 v
[1] = dbuf_getfloat64x(c
->infile
, zz
->pos
, d
->is_le
);
2670 de_dbg(c
, "reference point: %f, %f", v
[0], v
[1]);
2673 static void do_lsct_block(deark
*c
, lctx
*d
, zztype
*zz
)
2676 struct de_fourcc tmp4cc
;
2678 if(zz_avail(zz
)<4) return;
2679 x
= psd_getu32zz(zz
);
2680 de_dbg(c
, "section divider setting type: %d", (int)x
);
2682 zz
->pos
+= 4; // skip '8BIM' signature
2684 if(zz_avail(zz
)<4) return;
2685 psd_read_fourcc_zz(c
, d
, zz
, &tmp4cc
);
2686 de_dbg(c
, "blend mode key: '%s'", tmp4cc
.id_dbgstr
);
2688 if(zz_avail(zz
)<4) return;
2689 x
= psd_getu32zz(zz
);
2690 de_dbg(c
, "sub type: %d", (int)x
);
2693 static void do_lspf_block(deark
*c
, lctx
*d
, zztype
*zz
)
2696 if(zz_avail(zz
)!=4) return;
2697 x
= (unsigned int)psd_getu32zz(zz
);
2698 de_dbg(c
, "protection flags: transparency=%u, composite=%u, position=%u",
2699 (x
&0x1), (x
&0x2)>>1, (x
&0x4)>>2);
2702 static void do_vmsk_block(deark
*c
, lctx
*d
, zztype
*zz
)
2708 ver
= psd_getu32zz(zz
);
2710 flags
= psd_getu32zz(zz
);
2711 de_dbg(c
, "flags: 0x%08x", (unsigned int)flags
);
2713 de_dbg(c
, "path components at %d", (int)zz
->pos
);
2714 de_dbg_indent(c
, 1);
2716 do_pathinfo(c
, d
, &czz
);
2717 de_dbg_indent(c
, -1);
2720 static void do_vscg_block(deark
*c
, lctx
*d
, zztype
*zz
)
2722 struct de_fourcc key4cc
;
2724 psd_read_fourcc_zz(c
, d
, zz
, &key4cc
);
2725 de_dbg(c
, "key: '%s'", key4cc
.id_dbgstr
);
2726 read_descriptor(c
, d
, zz
, 1, " (for Vector Stroke Content Data)");
2729 static void do_vogk_block(deark
*c
, lctx
*d
, zztype
*zz
)
2733 ver
= psd_getu32zz(zz
);
2735 read_descriptor(c
, d
, zz
, 1, " (for Vector Origination Data)");
2738 static void do_unicodestring_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
,
2741 de_ucstring
*s
= NULL
;
2743 s
= ucstring_create(c
);
2744 read_unicode_string(c
, d
, s
, zz
);
2745 de_dbg(c
, "%s: \"%s\"", name
, ucstring_getpsz(s
));
2746 ucstring_destroy(s
);
2749 static void do_descriptor_block(deark
*c
, lctx
*d
, zztype
*zz
,
2750 const struct de_fourcc
*blk4cc
, const char *name
)
2755 de_snprintf(dscrname
, sizeof(dscrname
), " (for %s)", name
);
2757 de_strlcpy(dscrname
, "", sizeof(dscrname
));
2759 read_descriptor(c
, d
, zz
, 1, dscrname
);
2762 static void do_lfx2_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2767 if(zz_avail(zz
)<8) return;
2768 oe_ver
= psd_getu32zz(zz
);
2769 de_dbg(c
, "object effects version: %d", (int)oe_ver
);
2770 if(oe_ver
!=0) return;
2773 do_descriptor_block(c
, d
, &czz
, blk4cc
, "object-based effects layer info");
2776 // Handles 'TySh' and 'tySh'
2777 static void do_TySh_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2781 ver
= psd_getu16zz(zz
);
2782 de_dbg(c
, "version: %d", (int)ver
);
2783 if(ver
!=1) goto done
;
2785 zz
->pos
+= 6*8; // transform
2787 textver
= psd_getu16zz(zz
);
2788 de_dbg(c
, "text version: %d", (int)textver
);
2789 // For 'tySh', textver should be 6 -- TODO
2790 // For 'TySh', textver should be 50
2791 if(textver
!=50) goto done
;
2793 if(!read_descriptor(c
, d
, zz
, 1, " (for type tool object setting - text)")) {
2797 zz
->pos
+= 2; // warp version
2798 if(!read_descriptor(c
, d
, zz
, 1, " (for type tool object setting - warp)")) {
2802 // TODO: "left, top, right, bottom" (field purpose and data type are undocumented)
2809 static void do_SoLd_block(deark
*c
, lctx
*d
, zztype
*zz
)
2811 struct de_fourcc id4cc
;
2814 psd_read_fourcc_zz(c
, d
, zz
, &id4cc
);
2815 de_dbg(c
, "identifier: '%s'", id4cc
.id_dbgstr
);
2816 ver
= psd_getu32zz(zz
);
2817 de_dbg(c
, "version: %d", (int)ver
);
2819 read_descriptor(c
, d
, zz
, 1, " (of placed layer information)");
2822 static void do_filter_effect_channel(deark
*c
, lctx
*d
, zztype
*zz
)
2828 zz
->pos
+= 4; // Skip array-is-written flag (already processed)
2830 dlen
= psd_geti64zz(zz
);
2831 de_dbg(c
, "length: %"I64_FMT
"", dlen
);
2832 de_sanitize_length(&dlen
);
2833 saved_pos
= zz
->pos
;
2834 if(dlen
<=0) goto done
;
2836 cmpr_mode
= psd_getu16zz(zz
);
2837 dbg_print_compression_method(c
, d
, cmpr_mode
);
2839 de_dbg(c
, "[%d bytes at %d]", (int)(saved_pos
+ dlen
- zz
->pos
), (int)zz
->pos
);
2840 zz
->pos
= saved_pos
+ dlen
;
2845 static void do_filter_effect(deark
*c
, lctx
*d
, zztype
*zz
)
2849 de_ucstring
*s
= NULL
;
2855 int saved_indent_level
;
2856 i64 filter_effects_savedpos
;
2858 de_dbg_indent_save(c
, &saved_indent_level
);
2860 s
= ucstring_create(c
);
2863 read_pascal_string_to_ucstring(c
, d
, s
, zz
);
2864 de_dbg(c
, "identifier: \"%s\"", ucstring_getpsz(s
));
2866 // Note the clear similarites to the "virtual memory array lists" used in
2867 // Pattern data. But it is not the same. Maybe some of the code should be
2870 ver2
= psd_getu32zz(zz
);
2871 de_dbg(c
, "version: %d", (int)ver2
);
2872 if(ver2
!= 1) goto done
;
2874 dlen2
= psd_geti64zz(zz
);
2875 de_dbg(c
, "length: %"I64_FMT
"", dlen2
);
2876 de_sanitize_length(&dlen2
);
2877 filter_effects_savedpos
= zz
->pos
;
2879 read_rectangle_tlbr(c
, d
, zz
, "rectangle");
2881 x
= psd_getu32zz(zz
);
2882 de_dbg(c
, "depth: %d", (int)x
);
2884 max_channels
= psd_getu32zz(zz
);
2885 de_dbg(c
, "max channels: %d", (int)max_channels
);
2887 for(ch
=0; ch
<max_channels
+2; ch
++) {
2890 if(zz
->pos
>= zz
->endpos
) goto done
;
2892 // Look ahead at the array-is-written flag.
2893 is_written
= psd_getu32(zz
->pos
);
2895 de_dbg(c
, "channel[%d] at %d%s", (int)ch
, (int)zz
->pos
,
2896 is_written
?"":" (empty)");
2900 de_dbg_indent(c
, 1);
2901 do_filter_effect_channel(c
, d
, &czz
);
2902 de_dbg_indent(c
, -1);
2903 zz
->pos
+= zz_used(&czz
);
2910 if(zz
->pos
< (filter_effects_savedpos
+ dlen2
)) {
2911 de_dbg(c
, "[%d unknown bytes at %d]", (int)(filter_effects_savedpos
+ dlen2
- zz
->pos
),
2915 zz
->pos
= filter_effects_savedpos
+ dlen2
;
2917 b
= psd_getbytezz(zz
);
2918 de_dbg(c
, "next-items-present: %d", (int)b
);
2921 x
= psd_getu16zz(zz
);
2922 dbg_print_compression_method(c
, d
, x
);
2925 de_dbg(c
, "[%d bytes at %d]", (int)zz_avail(zz
), (int)zz
->pos
);
2926 zz
->pos
= zz
->endpos
;
2929 ucstring_destroy(s
);
2930 de_dbg_indent_restore(c
, saved_indent_level
);
2933 static void do_FXid_block(deark
*c
, lctx
*d
, zztype
*zz
, const struct de_fourcc
*blk4cc
)
2941 ver1
= psd_getu32zz(zz
);
2942 de_dbg(c
, "version: %d", (int)ver1
);
2943 if(ver1
<1 || ver1
>3) goto done
;
2945 // TODO: I suspect that this next "length" field is actually part of each
2946 // individual filter effect, contrary to what the documentation says.
2947 // That way, there can be multiple "filter effects" in the same block.
2948 // Sample files needed.
2950 dlen1
= psd_geti64zz(zz
);
2951 de_dbg(c
, "length: %"I64_FMT
"", dlen1
);
2952 de_sanitize_length(&dlen1
);
2953 main_endpos
= zz
->pos
+ dlen1
;
2958 de_dbg(c
, "filter effect[%d] at %d", (int)idx
, (int)zz
->pos
);
2959 zz_init_with_len(&czz
, zz
, main_endpos
-zz
->pos
);
2960 de_dbg_indent(c
, 1);
2961 do_filter_effect(c
, d
, &czz
);
2962 de_dbg_indent(c
, -1);
2963 zz
->pos
+= zz_used(&czz
);
2967 if(zz
->pos
< main_endpos
) {
2968 de_dbg(c
, "[%d bytes of data at %d]", (int)(main_endpos
-zz
->pos
), (int)zz
->pos
);
2971 zz
->pos
= main_endpos
;
2976 static void do_shmd_block(deark
*c
, lctx
*d
, zztype
*zz
)
2982 if(zz_avail(zz
)<4) return;
2984 count
= psd_getu32zz(zz
);
2985 de_dbg(c
, "number of metadata items: %d", (int)count
);
2987 for(i
=0; i
<count
; i
++) {
2988 i64 itempos
, dpos
, dlen
;
2989 struct de_fourcc key4cc
;
2991 if(zz
->pos
>= zz
->endpos
) break;
2994 zz
->pos
+= 4; // signature ("8BIM", presumably)
2996 psd_read_fourcc_zz(c
, d
, zz
, &key4cc
);
2998 zz
->pos
+= 1; // flag
2999 zz
->pos
+= 3; // padding
3001 dlen
= psd_getu32zz(zz
);
3004 de_dbg(c
, "metadata item[%d] '%s' at %d, dpos=%d, dlen=%d",
3005 (int)i
, key4cc
.id_dbgstr
, (int)itempos
, (int)dpos
, (int)dlen
);
3007 de_dbg_indent(c
, 1);
3010 case CODE_cust
: // Undocumented, but seems to be a versioned Descriptor
3011 case CODE_mlst
: // Undocumented, but seems to be a versioned Descriptor
3012 zz_init_with_len(&czz
, zz
, dlen
);
3013 read_descriptor(c
, d
, &czz
, 1, "");
3017 de_dbg_indent(c
, -1);
3023 static int do_tagged_block(deark
*c
, lctx
*d
, zztype
*zz
, int tbnamespace
)
3026 i64 blklen_len
= 4; // Length of the block length field
3027 struct de_fourcc blk4cc
;
3031 if(zz_avail(zz
)<12) return 0;
3033 sig
= (u32
)psd_getu32zz(zz
);
3034 if(sig
!=CODE_8BIM
&& sig
!=CODE_8B64
) {
3035 de_warn(c
, "Expected tagged block signature not found at %d", (int)zz
->pos
);
3039 psd_read_fourcc_zz(c
, d
, zz
, &blk4cc
);
3041 // Some blocks types have an 8-byte length in PSD format
3042 if(d
->intsize_4or8
==8) {
3044 case CODE_LMsk
: case CODE_Lr16
: case CODE_Lr32
: case CODE_Layr
:
3045 case CODE_Mt16
: case CODE_Mt32
: case CODE_Mtrn
: case CODE_Alph
:
3046 case CODE_FMsk
: case CODE_lnk2
: case CODE_FEid
: case CODE_FXid
:
3053 blklen
= psd_geti64zz(zz
);
3054 de_sanitize_length(&blklen
);
3057 blklen
= psd_getu32zz(zz
);
3060 zz_init_with_len(&czz
, zz
, blklen
);
3062 de_dbg(c
, "tagged block '%s' at %d, dpos=%d, dlen=%d", blk4cc
.id_dbgstr
,
3063 (int)zz
->startpos
, (int)czz
.startpos
, (int)blklen
);
3065 de_dbg_indent(c
, 1);
3068 do_boolean_block(c
, d
, &czz
, &blk4cc
, "blend clipped elements");
3071 do_boolean_block(c
, d
, &czz
, &blk4cc
, "blend interior elements");
3074 do_boolean_block(c
, d
, &czz
, &blk4cc
, "knockout");
3077 do_uint32_block(c
, d
, &czz
, &blk4cc
, "layer ID");
3080 do_fourcc_block(c
, d
, &czz
, &blk4cc
, "layer name ID");
3084 do_Layr_block(c
, d
, &czz
, &blk4cc
);
3089 do_lnk2_block(c
, d
, &czz
, &blk4cc
);
3094 do_Patt_block(c
, d
, &czz
, &blk4cc
);
3097 do_lrFX_block(c
, d
, &czz
, &blk4cc
);
3100 do_unicodestring_block(c
, d
, &czz
, &blk4cc
, "Unicode layer name");
3103 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Gradient fill setting");
3106 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Pattern fill setting");
3109 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Solid color sheet setting");
3112 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Vector Stroke Data");
3115 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Black and White");
3118 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Content Generator Extra Data");
3121 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Vibrance");
3124 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Unicode Path Name");
3127 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Animation Effects");
3130 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Pixel Source Data");
3135 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "Artboard Data");
3139 do_vmsk_block(c
, d
, &czz
);
3142 do_vscg_block(c
, d
, &czz
);
3145 do_vogk_block(c
, d
, &czz
);
3148 do_fxrp_block(c
, d
, &czz
);
3151 do_lsct_block(c
, d
, &czz
);
3154 do_lspf_block(c
, d
, &czz
);
3157 do_lfx2_block(c
, d
, &czz
, &blk4cc
);
3160 do_text_engine_data(c
, d
, czz
.startpos
, blklen
);
3164 do_TySh_block(c
, d
, &czz
, &blk4cc
);
3167 do_SoLd_block(c
, d
, &czz
);
3171 do_FXid_block(c
, d
, &czz
, &blk4cc
);
3174 do_shmd_block(c
, d
, &czz
);
3176 case CODE_AnDs
: // Observed in Plug-in Resources/'mani'/'IRFR'
3177 if(tbnamespace
==1) {
3178 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "");
3182 if(tbnamespace
==2) { // Observed in ABR (brush) files
3183 do_descriptor_block(c
, d
, &czz
, &blk4cc
, "");
3187 if(tbnamespace
==2) {
3188 do_Patt_block(c
, d
, &czz
, &blk4cc
);
3192 if(tbnamespace
==2) {
3193 do_samp_block(c
, d
, &czz
);
3198 if(c
->debug_level
>=2) {
3199 de_dbg_hexdump(c
, c
->infile
, czz
.startpos
, blklen
, 256, NULL
, 0x1);
3202 de_dbg(c
, "[%d bytes of tagged block data at %d]", (int)blklen
, (int)czz
.startpos
);
3206 de_dbg_indent(c
, -1);
3208 // Apparently, the data is padded to the next multiple of 4 bytes.
3209 // (This is not what the PSD spec says.)
3210 zz
->pos
+= de_pad_to_4(blklen
);
3214 // A "Series of tagged blocks" - part of the "Layer and Mask Information" section.
3215 // Or, the payload data from a TIFF "ImageSourceData" tag.
3216 // Or, at the end of a "layer record".
3217 static void do_tagged_blocks(deark
*c
, lctx
*d
, zztype
*zz
, int tbnamespace
)
3222 if(d
->nesting_level
>MAX_NESTING_LEVEL
) goto done
; // Defend against excessive recursion.
3224 if(d
->tagged_blocks_only
&& d
->nesting_level
==1) {
3225 // If we're reading *only* this data structure (e.g. from a TIFF file), the
3226 // byte order may be of interest.
3227 de_dbg(c
, "byte order: %s-endian", d
->is_le
?"little":"big");
3231 if(zz
->pos
+12 > zz
->endpos
) break;
3233 if(!do_tagged_block(c
, d
, &czz
, tbnamespace
)) break;
3234 zz
->pos
+= zz_used(&czz
);
3241 static int do_layer_and_mask_info_section(deark
*c
, lctx
*d
, zztype
*zz
)
3243 i64 layer_and_mask_info_section_len
; // The "Length" field. Whole section is 4 bytes longer.
3244 i64 gl_layer_mask_info_len
;
3247 int saved_indent_level
;
3250 de_dbg_indent_save(c
, &saved_indent_level
);
3252 // The "layer and mask section" contains up to 3 sub-sections:
3254 // 2. global layer mask info
3257 de_dbg(c
, "layer & mask info section at %d", (int)zz
->pos
);
3258 de_dbg_indent(c
, 1);
3260 layer_and_mask_info_section_len
= psd_getu32or64zz(c
, d
, zz
);
3261 de_dbg(c
, "layer & mask info section total data len: %d", (int)layer_and_mask_info_section_len
);
3262 de_sanitize_length(&layer_and_mask_info_section_len
);
3263 if(zz
->pos
+ layer_and_mask_info_section_len
> zz
->endpos
) {
3264 de_err(c
, "Unexpected end of PSD file");
3267 zz_init_with_len(&lmidataczz
, zz
, layer_and_mask_info_section_len
);
3269 // We won't use zz again (we'll use lmidataczz instead), so we can go ahead and
3270 // advance its ->pos field.
3271 zz
->pos
+= layer_and_mask_info_section_len
;
3272 // Now that we know the size of this element, we can treat this function as "successful".
3275 ///// 1. layer info /////
3277 zz_init(&czz
, &lmidataczz
);
3278 if(!do_layer_info_section(c
, d
, &lmidataczz
, 1)) {
3281 if(czz
.endpos
> lmidataczz
.endpos
) {
3282 de_warn(c
, "Oversized Layer Info section");
3285 lmidataczz
.pos
+= zz_used(&czz
);
3289 if(lmidataczz
.pos
>= lmidataczz
.endpos
) {
3293 ///// 2. global layer mask info /////
3295 de_dbg(c
, "global layer mask info at %d", (int)lmidataczz
.pos
);
3296 de_dbg_indent(c
, 1);
3297 gl_layer_mask_info_len
= psd_getu32zz(&lmidataczz
);
3298 de_dbg(c
, "length of global layer mask info section: %"I64_FMT
, gl_layer_mask_info_len
);
3299 de_dbg_indent(c
, -1);
3300 if(lmidataczz
.pos
+gl_layer_mask_info_len
> lmidataczz
.endpos
) {
3301 de_warn(c
, "Oversized Global Layer Mask Info section");
3304 lmidataczz
.pos
+= gl_layer_mask_info_len
;
3308 if(lmidataczz
.pos
>= lmidataczz
.endpos
) {
3312 ///// 3. tagged blocks /////
3314 de_dbg(c
, "tagged blocks at %d", (int)lmidataczz
.pos
);
3315 de_dbg_indent(c
, 1);
3316 de_dbg(c
, "expected length of tagged blocks section: %d", (int)(lmidataczz
.endpos
-lmidataczz
.pos
));
3317 zz_init(&czz
, &lmidataczz
);
3318 do_tagged_blocks(c
, d
, &czz
, 0);
3319 de_dbg_indent(c
, -1);
3322 de_dbg_indent_restore(c
, saved_indent_level
);
3326 static int do_action_item(deark
*c
, lctx
*d
, zztype
*zz
)
3328 struct de_fourcc id4cc
;
3329 de_ucstring
*s
= NULL
;
3333 zz
->pos
+= 1; // action-is-expanded
3334 zz
->pos
+= 1; // action-is-enabled
3335 zz
->pos
+= 1; // dialogs-should-be-displayed
3336 zz
->pos
+= 1; // options for displaying dialogs
3338 s
= ucstring_create(c
);
3340 psd_read_fourcc_zz(c
, d
, zz
, &id4cc
);
3341 de_dbg(c
, "identifier type: '%s'", id4cc
.id_dbgstr
);
3342 if(id4cc
.id
==CODE_TEXT
) {
3343 read_prefixed_string_to_ucstring(c
, d
, s
, zz
);
3344 de_dbg(c
, "id: \"%s\"", ucstring_getpsz_d(s
));
3346 else if(id4cc
.id
==CODE_long
) {
3348 id_long
= psd_getu32zz(zz
);
3349 de_dbg(c
, "itemID: %d", (int)id_long
);
3352 de_err(c
, "Unsupported identifier type: '%s'", id4cc
.id_sanitized_sz
);
3357 read_prefixed_string_to_ucstring(c
, d
, s
, zz
);
3358 de_dbg(c
, "dictionary name: \"%s\"", ucstring_getpsz_d(s
));
3360 dscr_flag
= psd_geti32zz(zz
);
3361 de_dbg(c
, "descriptor flag: %d", (int)dscr_flag
);
3363 if(dscr_flag
== -1) {
3364 if(!read_descriptor(c
, d
, zz
, 0, "")) goto done
;
3366 else if(dscr_flag
==0) {
3370 de_err(c
, "Unsupported descriptor flag: %d", (int)dscr_flag
);
3377 ucstring_destroy(s
);
3381 static int do_one_action(deark
*c
, lctx
*d
, zztype
*zz
)
3387 de_ucstring
*s
= NULL
;
3389 int saved_indent_level
;
3392 de_dbg_indent_save(c
, &saved_indent_level
);
3393 action_pos
= zz
->pos
;
3394 idx
= psd_getu16zz(zz
);
3395 de_dbg(c
, "index: %d", (int)idx
);
3397 zz
->pos
+= 1; // shift key flag
3398 zz
->pos
+= 1; // command key flag
3399 zz
->pos
+= 2; // color index info
3401 s
= ucstring_create(c
);
3402 read_unicode_string(c
, d
, s
, zz
);
3403 de_dbg(c
, "action name: \"%s\"", ucstring_getpsz_d(s
));
3405 zz
->pos
+= 1; // action-is-expanded
3407 num_items
= psd_getu32zz(zz
);
3408 de_dbg(c
, "number of items: %d", (int)num_items
);
3410 for(item_idx
=0; item_idx
<num_items
; item_idx
++) {
3411 if(zz_avail(zz
)<1) goto done
;
3413 de_dbg(c
, "item[%d] at %d (for action @%d)", (int)item_idx
, (int)zz
->pos
, (int)action_pos
);
3414 de_dbg_indent(c
, 1);
3415 if(!do_action_item(c
, d
, &czz
)) goto done
;
3416 zz
->pos
+= zz_used(&czz
);
3417 de_dbg_indent(c
, -1);
3423 de_dbg_indent_restore(c
, saved_indent_level
);
3424 ucstring_destroy(s
);
3428 static void do_action_set(deark
*c
, lctx
*d
, zztype
*zz
)
3433 de_ucstring
*s
= NULL
;
3435 int saved_indent_level
;
3438 de_dbg_indent_save(c
, &saved_indent_level
);
3439 ver
= psd_getu32zz(zz
);
3440 de_dbg(c
, "version: %d", (int)ver
);
3442 de_err(c
, "Unsupported Action format version: %d", (int)ver
);
3446 s
= ucstring_create(c
);
3447 read_unicode_string(c
, d
, s
, zz
);
3448 de_dbg(c
, "action set name: \"%s\"", ucstring_getpsz_d(s
));
3450 b
= psd_getbytezz(zz
);
3451 de_dbg(c
, "set-is-expanded: %d", (int)b
);
3453 num_actions
= psd_getu32zz(zz
);
3454 de_dbg(c
, "number of actions: %d", (int)num_actions
);
3456 for(action_idx
=0; action_idx
<num_actions
; action_idx
++) {
3457 if(zz_avail(zz
)<1) goto done
;
3459 de_dbg(c
, "action[%d] at %d", (int)action_idx
, (int)zz
->pos
);
3460 de_dbg_indent(c
, 1);
3461 if(!do_one_action(c
, d
, &czz
)) goto done
;
3462 zz
->pos
+= zz_used(&czz
);
3463 de_dbg_indent(c
, -1);
3467 de_dbg_indent_restore(c
, saved_indent_level
);
3468 ucstring_destroy(s
);
3471 // Call this after setting d->version.
3472 static void init_version_specific_info(deark
*c
, lctx
*d
)
3474 if(d
->version
==2) { // PSB format
3475 d
->intsize_2or4
= 4;
3476 d
->intsize_4or8
= 8;
3478 else { // Regular PSD format
3479 d
->intsize_2or4
= 2;
3480 d
->intsize_4or8
= 4;
3483 // The PSD spec does not say what encoding these strings use.
3484 // Some sources say they use MacRoman, and *some* PSD files do use MacRoman.
3485 // But other PSD files use other encodings, and I don't know how to know what
3486 // encoding they use.
3487 d
->input_encoding
= de_get_input_encoding(c
, NULL
, DE_ENCODING_MACROMAN
);
3489 d
->jpeg_rbswap_mode
= 1;
3492 static int do_psd_header(deark
*c
, lctx
*d
, i64 pos
)
3496 de_dbg(c
, "header at %d", (int)pos
);
3497 de_dbg_indent(c
, 1);
3498 d
->version
= (int)psd_getu16(pos
+4);
3499 de_dbg(c
, "PSD version: %d", d
->version
);
3500 init_version_specific_info(c
, d
);
3503 de_declare_fmt(c
, "PSD");
3505 else if(d
->version
==2) {
3506 de_declare_fmt(c
, "PSB");
3509 de_err(c
, "Unsupported PSD version: %d", (int)d
->version
);
3513 d
->main_iinfo
->num_channels
= psd_getu16(pos
+12);
3514 de_dbg(c
, "number of channels: %d", (int)d
->main_iinfo
->num_channels
);
3516 d
->main_iinfo
->height
= psd_getu32(pos
+14);
3517 d
->main_iinfo
->width
= psd_getu32(pos
+18);
3518 de_dbg_dimensions(c
, d
->main_iinfo
->width
, d
->main_iinfo
->height
);
3520 d
->main_iinfo
->bits_per_channel
= psd_getu16(pos
+22);
3521 de_dbg(c
, "bits/channel: %d", (int)d
->main_iinfo
->bits_per_channel
);
3523 d
->main_iinfo
->color_mode
= psd_getu16(pos
+24);
3524 de_dbg(c
, "color mode: %d (%s)", (int)d
->main_iinfo
->color_mode
,
3525 get_colormode_name(d
->main_iinfo
->color_mode
));
3530 de_dbg_indent(c
, -1);
3534 static void do_external_tagged_blocks(deark
*c
, lctx
*d
, zztype
*zz
)
3538 d
->tagged_blocks_only
= 1;
3539 if(zz_avail(zz
)<4) return;
3541 // Evidently, it is possible for this to use little-endian byte order. Weird.
3543 // Peek at the first 4 bytes
3544 code
= (u32
)de_getu32le(0);
3545 if(code
==CODE_8BIM
|| code
==CODE_8B64
) {
3549 do_tagged_blocks(c
, d
, zz
, 0);
3552 static void do_psd_color_mode_data(deark
*c
, lctx
*d
, zztype
*zz
)
3557 struct image_info
*iinfo
= d
->main_iinfo
;
3560 de_dbg(c
, "color data at %d, len=%d", (int)zz
->pos
, (int)len
);
3561 iinfo
->pal_entries
= len
/3;
3562 if(iinfo
->pal_entries
<1) return;
3563 if(iinfo
->pal_entries
>256) iinfo
->pal_entries
=256;
3565 de_dbg_indent(c
, 1);
3566 for(k
=0; k
<iinfo
->pal_entries
; k
++) {
3567 r
= de_getbyte(zz
->pos
+ k
);
3568 g
= de_getbyte(zz
->pos
+ iinfo
->pal_entries
+ k
);
3569 b
= de_getbyte(zz
->pos
+ 2*iinfo
->pal_entries
+ k
);
3570 iinfo
->pal
[k
] = DE_MAKE_RGB(r
, g
, b
);
3571 de_dbg_pal_entry(c
, k
, iinfo
->pal
[k
]);
3573 de_dbg_indent(c
, -1);
3576 static u8
scale_float_to_255(double x
)
3578 if(x
<=0.0) return 0;
3579 if(x
>=1.0) return 255;
3580 return (u8
)(0.5+x
*255.0);
3583 // Extract the primary image
3584 static void do_bitmap(deark
*c
, lctx
*d
, const struct image_info
*iinfo
, dbuf
*f
,
3587 de_bitmap
*img
= NULL
;
3588 de_finfo
*fi
= NULL
;
3590 i64 nplanes
= 0; // Number of planes to read. May be less than d->num_channels.
3591 i64 planespan
, rowspan
, samplespan
;
3594 if(!de_good_image_dimensions(c
, iinfo
->width
, iinfo
->height
)) goto done
;
3596 if(iinfo
->color_mode
==PSD_CM_BITMAP
&& iinfo
->bits_per_channel
==1 &&
3597 iinfo
->num_channels
==1)
3599 de_convert_and_write_image_bilevel2(f
, 0, iinfo
->width
, iinfo
->height
,
3600 (iinfo
->width
+7)/8, DE_CVTF_WHITEISZERO
, NULL
, 0);
3604 if(iinfo
->bits_per_channel
!=8 && iinfo
->bits_per_channel
!=16 &&
3605 iinfo
->bits_per_channel
!=32)
3607 de_err(c
, "Unsupported bits/channel: %d", (int)iinfo
->bits_per_channel
);
3611 if(iinfo
->color_mode
==PSD_CM_GRAY
&& iinfo
->num_channels
>=1) {
3614 else if(iinfo
->color_mode
==PSD_CM_PALETTE
&& iinfo
->num_channels
>=1 && iinfo
->bits_per_channel
==8) {
3617 else if(iinfo
->color_mode
==PSD_CM_RGB
&& iinfo
->num_channels
>=3) {
3621 de_err(c
, "This type of image is not supported (color=%d, "
3622 "num channels=%d, bits/channel=%d)",
3623 (int)iinfo
->color_mode
, (int)iinfo
->num_channels
, (int)iinfo
->bits_per_channel
);
3627 img
= de_bitmap_create(c
, iinfo
->width
, iinfo
->height
,
3628 iinfo
->color_mode
==PSD_CM_GRAY
? 1 : 3);
3630 fi
= de_finfo_create(c
);
3632 if(iinfo
->density
.code
!=DE_DENSITY_UNKNOWN
) {
3633 fi
->density
= iinfo
->density
;
3636 samplespan
= iinfo
->bits_per_channel
/8;
3637 rowspan
= iinfo
->width
* samplespan
;
3638 planespan
= iinfo
->height
* rowspan
;
3640 for(plane
=0; plane
<nplanes
; plane
++) {
3641 for(j
=0; j
<iinfo
->height
; j
++) {
3642 for(i
=0; i
<iinfo
->width
; i
++) {
3643 if(iinfo
->bits_per_channel
==32) {
3644 // TODO: The format of 32-bit samples does not seem to be documented.
3645 // This is little more than a guess.
3647 tmpd
= dbuf_getfloat32x(f
, pos
+ plane
*planespan
+ j
*rowspan
+ i
*samplespan
, d
->is_le
);
3648 b
= scale_float_to_255(tmpd
);
3651 b
= dbuf_getbyte(f
, pos
+ plane
*planespan
+ j
*rowspan
+ i
*samplespan
);
3653 if(iinfo
->color_mode
==PSD_CM_RGB
) {
3654 de_bitmap_setsample(img
, i
, j
, plane
, b
);
3656 else if(iinfo
->color_mode
==PSD_CM_GRAY
) {
3657 de_bitmap_setpixel_gray(img
, i
, j
, b
);
3659 else if(iinfo
->color_mode
==PSD_CM_PALETTE
) {
3660 de_bitmap_setpixel_rgb(img
, i
, j
, iinfo
->pal
[(unsigned int)b
]);
3666 de_bitmap_write_to_file_finfo(img
, fi
, 0);
3668 de_bitmap_destroy(img
);
3669 de_finfo_destroy(c
, fi
);
3672 static void do_bitmap_packbits(deark
*c
, lctx
*d
, zztype
*zz
, const struct image_info
*iinfo
)
3674 dbuf
*unc_pixels
= NULL
;
3675 i64 cmpr_data_size
= 0;
3678 // Data begins with a table of row byte counts.
3679 de_dbg(c
, "row sizes table at %"I64_FMT
", len=%d", zz
->pos
,
3680 (int)(iinfo
->num_channels
* iinfo
->height
* d
->intsize_2or4
));
3682 for(k
=0; k
< iinfo
->num_channels
* iinfo
->height
; k
++) {
3683 if(d
->intsize_2or4
==4) {
3684 cmpr_data_size
+= psd_getu32zz(zz
);
3687 cmpr_data_size
+= psd_getu16zz(zz
);
3691 de_dbg(c
, "compressed data at %"I64_FMT
", len=%"I64_FMT
"", zz
->pos
, cmpr_data_size
);
3692 if(zz
->pos
+ cmpr_data_size
>c
->infile
->len
) {
3693 de_err(c
, "Unexpected end of file");
3697 unc_pixels
= dbuf_create_membuf(c
, 1024, 0);
3698 dbuf_enable_wbuffer(unc_pixels
);
3699 fmtutil_decompress_packbits(c
->infile
, zz
->pos
, cmpr_data_size
, unc_pixels
, NULL
);
3700 dbuf_flush(unc_pixels
);
3701 zz
->pos
+= cmpr_data_size
;
3702 de_dbg_indent(c
, 1);
3703 de_dbg(c
, "decompressed %"I64_FMT
" bytes to %"I64_FMT
"", cmpr_data_size
, unc_pixels
->len
);
3704 de_dbg_indent(c
, -1);
3705 do_bitmap(c
, d
, iinfo
, unc_pixels
, 0, unc_pixels
->len
);
3708 dbuf_close(unc_pixels
);
3711 static void do_image_data(deark
*c
, lctx
*d
, zztype
*zz
)
3715 i64 image_data_size
;
3720 de_dbg(c
, "image data section at %d, expected len=%d", (int)zz
->pos
, (int)len
);
3721 de_dbg_indent(c
, 1);
3722 cmpr
= psd_getu16zz(zz
);
3723 dbg_print_compression_method(c
, d
, cmpr
);
3725 image_data_size
= zz_avail(zz
);
3727 if(c
->extract_policy
== DE_EXTRACTPOLICY_AUXONLY
) goto done
;
3729 // Copy the global density info (from Resources section, presumably) to the image info
3730 d
->main_iinfo
->density
= d
->density
;
3732 if(cmpr
==0) { // Uncompressed
3733 do_bitmap(c
, d
, d
->main_iinfo
, c
->infile
, zz
->pos
, image_data_size
);
3735 else if(cmpr
==1) { // PackBits
3737 do_bitmap_packbits(c
, d
, &czz
, d
->main_iinfo
);
3738 zz
->pos
+= zz_used(&czz
);
3741 de_err(c
, "Compression method not supported: %d", (int)cmpr
);
3745 de_dbg_indent(c
, -1);
3748 static void de_run_psd(deark
*c
, de_module_params
*mparams
)
3756 d
= de_malloc(c
, sizeof(lctx
));
3757 zz
= de_malloc(c
, sizeof(zztype
));
3758 zz_init_absolute(zz
, 0, c
->infile
->len
);
3760 if(de_havemodcode(c
, mparams
, 'R')) {
3763 else if(de_havemodcode(c
, mparams
, 'T')) {
3766 else if(de_havemodcode(c
, mparams
, 'B')) {
3769 else if(!dbuf_memcmp(c
->infile
, 0, "8BIM", 4)) {
3770 // Assume this is a raw resources file (maybe extracted from an
3775 if(whattodo
=='R') { // Image resources
3776 de_declare_fmt(c
, "Photoshop resources");
3778 init_version_specific_info(c
, d
);
3779 do_image_resource_blocks(c
, d
, zz
);
3781 // .out_params.flags: 0x02: has_iptc
3782 mparams
->out_params
.flags
= 0;
3783 if(d
->has_iptc
) mparams
->out_params
.flags
|= 0x02;
3787 else if(whattodo
=='T') { // Tagged blocks
3789 init_version_specific_info(c
, d
);
3790 do_external_tagged_blocks(c
, d
, zz
);
3793 else if(whattodo
=='B') { // Tagged blocks, PSB-format
3795 init_version_specific_info(c
, d
);
3796 do_external_tagged_blocks(c
, d
, zz
);
3800 d
->main_iinfo
= de_malloc(c
, sizeof(struct image_info
));
3802 if(!do_psd_header(c
, d
, zz
->pos
)) goto done
;
3805 de_dbg(c
, "color mode data section at %d", (int)zz
->pos
);
3806 de_dbg_indent(c
, 1);
3807 x
= psd_getu32zz(zz
);
3808 zz_init_with_len(&czz
, zz
, x
);
3809 do_psd_color_mode_data(c
, d
, &czz
);
3811 de_dbg_indent(c
, -1);
3813 de_dbg(c
, "image resources section at %d", (int)zz
->pos
);
3814 de_dbg_indent(c
, 1);
3815 x
= psd_getu32zz(zz
); // Length of Image Resources
3816 // The PSD spec is ambiguous, but in practice the "length" field's value
3817 // does not include the size of the "length" field itself.
3818 de_dbg(c
, "image resources data at %d, len=%d", (int)zz
->pos
, (int)x
);
3821 if(de_get_ext_option_bool(c
, "extract8bim", 0)) {
3822 fmtutil_handle_photoshop_rsrc(c
, c
->infile
, zz
->pos
, x
, 0x1);
3825 de_dbg_indent(c
, 1);
3826 zz_init_with_len(&czz
, zz
, x
);
3827 do_image_resource_blocks(c
, d
, &czz
);
3828 de_dbg_indent(c
, -1);
3832 de_dbg_indent(c
, -1);
3835 if(!do_layer_and_mask_info_section(c
, d
, &czz
)) goto done
;
3836 zz
->pos
+= zz_used(&czz
);
3839 do_image_data(c
, d
, &czz
);
3844 de_free(c
, d
->main_iinfo
);
3849 static void de_run_ps_action(deark
*c
, de_module_params
*mparams
)
3854 de_declare_fmt(c
, "Photoshop Action");
3856 d
= de_malloc(c
, sizeof(lctx
));
3858 init_version_specific_info(c
, d
);
3860 zz
= de_malloc(c
, sizeof(zztype
));
3861 zz_init_absolute(zz
, 0, c
->infile
->len
);
3863 do_action_set(c
, d
, zz
);
3869 static void de_run_ps_gradient(deark
*c
, de_module_params
*mparams
)
3875 de_declare_fmt(c
, "Photoshop Gradient");
3877 d
= de_malloc(c
, sizeof(lctx
));
3879 init_version_specific_info(c
, d
);
3881 zz
= de_malloc(c
, sizeof(zztype
));
3882 zz_init_absolute(zz
, 0, c
->infile
->len
);
3884 zz
->pos
+= 4; // 8BGR signature
3885 grd_ver
= psd_getu16zz(zz
);
3886 de_dbg(c
, "file version: %d", (int)grd_ver
);
3889 read_descriptor(c
, d
, zz
, 1, "");
3892 de_err(c
, "Unsupported Photoshop Gradient file version: %d", (int)grd_ver
);
3899 // .asl format, "Patterns" object
3900 static void do_asl_patterns(deark
*c
, lctx
*d
, zztype
*zz
)
3906 de_dbg(c
, "patterns at %d", (int)zz
->pos
);
3907 de_dbg_indent(c
, 1);
3908 pat_ver
= psd_getu16zz(zz
);
3909 de_dbg(c
, "patterns version: %d", (int)pat_ver
);
3910 patseq_len
= psd_getu32zz(zz
);
3911 de_dbg(c
, "patterns total length: %d", (int)patseq_len
);
3913 // Sequence of patterns
3914 zz_init_with_len(&czz_patseq
, zz
, patseq_len
);
3916 do_pattern_sequence(c
, d
, &czz_patseq
);
3918 zz
->pos
+= patseq_len
;
3920 de_dbg_indent(c
, -1);
3923 // .asl format, "Styles" object
3924 static void do_asl_patterns_and_styles(deark
*c
, lctx
*d
, zztype
*zz
)
3931 zz
->pos
+= 4; // 8BSL signature
3934 do_asl_patterns(c
, d
, &czz
);
3935 zz
->pos
+= zz_used(&czz
);
3937 de_dbg(c
, "styles at %d", (int)zz
->pos
);
3938 de_dbg_indent(c
, 1);
3940 num_styles
= psd_getu32zz(zz
);
3941 de_dbg(c
, "number of styles: %d", (int)num_styles
);
3943 for(style_idx
=0; style_idx
<=num_styles
; style_idx
++) {
3944 if(zz_avail(zz
)<4) break;
3946 de_dbg(c
, "style[%d] at %d", (int)style_idx
, (int)zz
->pos
);
3947 de_dbg_indent(c
, 1);
3949 style_len
= psd_getu32zz(zz
);
3950 de_dbg(c
, "style length: %d", (int)style_len
);
3952 zz_init_with_len(&czz
, zz
, style_len
);
3953 read_descriptor(c
, d
, &czz
, 1, " (for style identification)");
3954 read_descriptor(c
, d
, &czz
, 1, " (for style information)");
3956 zz
->pos
+= style_len
;
3957 de_dbg_indent(c
, -1);
3960 de_dbg_indent(c
, -1);
3963 static void de_run_ps_styles(deark
*c
, de_module_params
*mparams
)
3969 de_declare_fmt(c
, "Photoshop Styles");
3971 d
= de_malloc(c
, sizeof(lctx
));
3973 init_version_specific_info(c
, d
);
3975 zz
= de_malloc(c
, sizeof(zztype
));
3976 zz_init_absolute(zz
, 0, c
->infile
->len
);
3978 asl_ver
= psd_getu16zz(zz
);
3979 de_dbg(c
, "file version: %d", (int)asl_ver
);
3981 de_err(c
, "Unsupported Photoshop Styles file version: %d", (int)asl_ver
);
3985 do_asl_patterns_and_styles(c
, d
, zz
);
3992 static void do_abr_v1(deark
*c
, lctx
*d
, zztype
*zz
)
3998 num_brushes
= psd_getu16zz(zz
);
3999 de_dbg(c
, "number of brushes: %d", (int)num_brushes
);
4001 for(i
=0; i
<num_brushes
; i
++) {
4005 if(zz
->pos
>= zz
->endpos
) break;
4007 de_dbg(c
, "brush definition[%d] at %d", (int)i
, (int)zz
->pos
);
4008 de_dbg_indent(c
, 1);
4010 brushtype
= psd_getu16zz(zz
);
4011 de_dbg(c
, "brush type: %d", (int)brushtype
);
4012 bdeflen
= psd_getu32zz(zz
);
4013 de_dbg(c
, "brush definition data dpos=%d, dlen=%d", (int)zz
->pos
, (int)bdeflen
);
4017 de_dbg_indent(c
, -1);
4022 static void do_abr_v6(deark
*c
, lctx
*d
, zztype
*zz
)
4027 zz
->pos
+= 4; // Version numbers(?), already read
4028 sig
= (u32
)psd_getu32(zz
->pos
);
4029 if(sig
!=CODE_8BIM
) {
4030 de_err(c
, "Bad signature or unsupported Brush format");
4035 do_tagged_blocks(c
, d
, &czz
, 2);
4041 static void de_run_ps_brush(deark
*c
, de_module_params
*mparams
)
4047 d
= de_malloc(c
, sizeof(lctx
));
4049 init_version_specific_info(c
, d
);
4051 zz
= de_malloc(c
, sizeof(zztype
));
4052 zz_init_absolute(zz
, 0, c
->infile
->len
);
4054 d
->abr_major_ver
= (int)psd_getu16(0);
4055 de_dbg(c
, "file version: %d", (int)d
->abr_major_ver
);
4057 has_8bim_sig
= (psd_getu32(4) == CODE_8BIM
);
4059 if(has_8bim_sig
&& d
->abr_major_ver
>=3) {
4060 d
->abr_minor_ver
= (int)psd_getu16(2);
4061 de_declare_fmt(c
, "Photoshop Brush (new format)");
4062 do_abr_v6(c
, d
, zz
);
4064 else if(d
->abr_major_ver
<=5) {
4065 de_declare_fmt(c
, "Photoshop Brush (old format)");
4066 do_abr_v1(c
, d
, zz
);
4069 de_err(c
, "Unsupported Photoshop Brush format (version=%d)", (int)d
->abr_major_ver
);
4078 static void do_custom_shape(deark
*c
, lctx
*d
, zztype
*zz
)
4080 de_ucstring
*s
= NULL
;
4086 s
= ucstring_create(c
);
4087 saved_pos
= zz
->pos
;
4088 read_unicode_string(c
, d
, s
, zz
);
4089 de_dbg(c
, "name: \"%s\"", ucstring_getpsz_d(s
));
4090 // This Unicode String is padded to a multiple of 4 bytes, unlike pretty much
4091 // every other Unicode String in every Photoshop format.
4092 zz
->pos
= saved_pos
+ de_pad_to_4(zz
->pos
- saved_pos
);
4094 zz
->pos
+= 4; // Unknown field
4096 dlen
= psd_getu32zz(zz
);
4097 de_dbg(c
, "shape data length: %d", (int)dlen
);
4099 zz_init_with_len(&datazz
, zz
, dlen
);
4100 // We expect this length to be a multiple of 4. I don't know what to do if
4105 read_pascal_string_to_ucstring(c
, d
, s
, &datazz
);
4106 de_dbg(c
, "id: \"%s\"", ucstring_getpsz(s
));
4108 read_rectangle_tlbr(c
, d
, &datazz
, "bounds");
4110 de_dbg(c
, "path records at %d", (int)datazz
.pos
);
4111 zz_init(&pathinfozz
, &datazz
);
4112 de_dbg_indent(c
, 1);
4113 do_pathinfo(c
, d
, &pathinfozz
);
4114 de_dbg_indent(c
, -1);
4116 ucstring_destroy(s
);
4119 static void de_run_ps_csh(deark
*c
, de_module_params
*mparams
)
4128 d
= de_malloc(c
, sizeof(lctx
));
4130 init_version_specific_info(c
, d
);
4132 zz
= de_malloc(c
, sizeof(zztype
));
4133 zz_init_absolute(zz
, 0, c
->infile
->len
);
4135 zz
->pos
+= 4; // Skip over 'cush' signature
4137 csh_ver
= psd_getu32zz(zz
);
4138 de_dbg(c
, "file version: %d", (int)csh_ver
);
4141 de_warn(c
, "CSH v%d format might not be supported correctly", (int)csh_ver
);
4144 num_shapes
= psd_getu32zz(zz
);
4145 de_dbg(c
, "number of shapes: %d", (int)num_shapes
);
4147 for(i
=0; i
<num_shapes
; i
++) {
4148 if(zz_avail(zz
)<28) break;
4149 de_dbg(c
, "shape[%d] at %d", (int)i
, (int)zz
->pos
);
4151 de_dbg_indent(c
, 1);
4152 do_custom_shape(c
, d
, &czz
);
4153 de_dbg_indent(c
, -1);
4154 zz
->pos
+= zz_used(&czz
);
4161 static void de_run_ps_pattern(deark
*c
, de_module_params
*mparams
)
4170 d
= de_malloc(c
, sizeof(lctx
));
4172 init_version_specific_info(c
, d
);
4174 zz
= de_malloc(c
, sizeof(zztype
));
4175 zz_init_absolute(zz
, 0, c
->infile
->len
);
4177 zz
->pos
+= 4; // Skip over '8BPT' signature
4179 pat_ver
= psd_getu16zz(zz
);
4180 de_dbg(c
, "file version: %d", (int)pat_ver
);
4183 de_warn(c
, "PAT v%d format might not be supported correctly", (int)pat_ver
);
4186 num_patterns
= psd_getu32zz(zz
);
4187 de_dbg(c
, "number of patterns: %d", (int)num_patterns
);
4189 for(i
=0; i
<num_patterns
; i
++) {
4190 if(zz_avail(zz
)<4) break;
4191 de_dbg(c
, "pattern[%d] at %d", (int)i
, (int)zz
->pos
);
4193 de_dbg_indent(c
, 1);
4194 if(!do_pattern_internal(c
, d
, &czz
)) break;
4195 de_dbg_indent(c
, -1);
4196 zz
->pos
+= zz_used(&czz
);
4203 static int de_identify_psd(deark
*c
)
4208 if(!de_memcmp(buf
, "8BPS", 4)) return 100;
4209 if(!de_memcmp(buf
, "8BIM", 4)) {
4210 // We sometimes write .8bim files, so we want to identify them.
4211 // This is not necessarily a standard file format.
4212 if(de_input_file_has_ext(c
, "8bim")) return 100;
4218 void de_module_psd(deark
*c
, struct deark_module_info
*mi
)
4221 mi
->desc
= "Photoshop PSD";
4222 mi
->run_fn
= de_run_psd
;
4223 mi
->identify_fn
= de_identify_psd
;
4226 static int de_identify_ps_action(deark
*c
)
4230 if(!dbuf_memcmp(c
->infile
, 0, "\x00\x00\x00\x10\x00\x00", 6)) {
4233 else if(!dbuf_memcmp(c
->infile
, 0, "\x00\x00\x00\x0c", 4)) {
4236 if(ver
==0) return 0;
4237 if(!de_input_file_has_ext(c
, "atn")) return 0;
4238 if(ver
==16) return 100;
4239 return 5; // A version we don't support
4242 void de_module_ps_action(deark
*c
, struct deark_module_info
*mi
)
4244 mi
->id
= "ps_action";
4245 mi
->desc
= "Photoshop Action";
4246 mi
->run_fn
= de_run_ps_action
;
4247 mi
->identify_fn
= de_identify_ps_action
;
4250 static int de_identify_ps_gradient(deark
*c
)
4252 if(!dbuf_memcmp(c
->infile
, 0, "8BGR", 4)) {
4253 if(de_input_file_has_ext(c
, "grd")) return 100;
4259 void de_module_ps_gradient(deark
*c
, struct deark_module_info
*mi
)
4261 mi
->id
= "ps_gradient";
4262 mi
->desc
= "Photoshop Gradient";
4263 mi
->run_fn
= de_run_ps_gradient
;
4264 mi
->identify_fn
= de_identify_ps_gradient
;
4267 static int de_identify_ps_styles(deark
*c
)
4269 if(!dbuf_memcmp(c
->infile
, 2, "8BSL", 4)) {
4270 if(de_input_file_has_ext(c
, "asl")) return 100;
4276 void de_module_ps_styles(deark
*c
, struct deark_module_info
*mi
)
4278 mi
->id
= "ps_styles";
4279 mi
->desc
= "Photoshop Styles";
4280 mi
->run_fn
= de_run_ps_styles
;
4281 mi
->identify_fn
= de_identify_ps_styles
;
4284 static int de_identify_ps_brush(deark
*c
)
4288 ver
= de_getu16be(0);
4289 if(ver
==1 || ver
==2 || ver
==6 || ver
==7) {
4290 if(de_input_file_has_ext(c
, "abr")) return 80;
4295 void de_module_ps_brush(deark
*c
, struct deark_module_info
*mi
)
4297 mi
->id
= "ps_brush";
4298 mi
->desc
= "Photoshop Brush";
4299 mi
->run_fn
= de_run_ps_brush
;
4300 mi
->identify_fn
= de_identify_ps_brush
;
4303 static int de_identify_ps_csh(deark
*c
)
4305 if(!dbuf_memcmp(c
->infile
, 0, "cush", 4)) {
4306 if(de_input_file_has_ext(c
, "csh")) return 100;
4312 void de_module_ps_csh(deark
*c
, struct deark_module_info
*mi
)
4315 mi
->desc
= "Photoshop Custom Shape";
4316 mi
->run_fn
= de_run_ps_csh
;
4317 mi
->identify_fn
= de_identify_ps_csh
;
4320 static int de_identify_ps_pattern(deark
*c
)
4322 if(!dbuf_memcmp(c
->infile
, 0, "8BPT", 4)) {
4323 if(de_input_file_has_ext(c
, "pat")) return 100;
4329 void de_module_ps_pattern(deark
*c
, struct deark_module_info
*mi
)
4331 mi
->id
= "ps_pattern";
4332 mi
->desc
= "Photoshop Pattern";
4333 mi
->run_fn
= de_run_ps_pattern
;
4334 mi
->identify_fn
= de_identify_ps_pattern
;