iccprofile: Refactoring
[deark.git] / modules / psd.c
blob455324158bd0127839e14aa63662f2d9287e8ed3
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
121 #define PSD_CM_RGB 3
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
130 // children.
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.
150 } zztype;
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".
155 struct flexible_id {
156 int is_fourcc;
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.
160 i64 bytes_consumed;
163 struct image_info {
164 i64 width, height;
165 i64 color_mode;
166 i64 num_channels;
167 i64 bits_per_channel;
168 struct de_density_info density;
170 i64 pal_entries;
171 u32 pal[256];
174 typedef struct localctx_struct {
175 int version; // 1=PSD, 2=PSB
176 int is_le;
177 int input_encoding;
178 int tagged_blocks_only;
179 #define MAX_NESTING_LEVEL 50
180 int nesting_level;
181 u8 jpeg_rbswap_mode;
182 i64 intsize_2or4;
183 i64 intsize_4or8;
185 int abr_major_ver, abr_minor_ver;
186 u8 has_iptc;
187 struct de_density_info density;
189 struct image_info *main_iinfo;
190 } lctx;
192 struct rsrc_info;
194 typedef void (*rsrc_handler_fn)(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri);
196 struct rsrc_info {
197 u16 id;
199 // 0x0004 = Item consists of a version number, followed by a "Descriptor structure".
200 // 0x0010 = Do not include ASCII in hexdumps.
201 u32 flags;
203 const char *idname;
204 rsrc_handler_fn hfn;
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;
346 zz->pos = startpos;
347 zz->endpos = endpos;
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;
362 if(len<0) len=0;
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
390 // in many cases.
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);
396 zz->pos++;
397 return val;
400 static i64 psd_dbuf_getu16_zz(dbuf *f, zztype *zz, int is_le)
402 i64 val = dbuf_getu16x(f, zz->pos, is_le);
403 zz->pos += 2;
404 return val;
407 static i64 psd_dbuf_geti16_zz(dbuf *f, zztype *zz, int is_le)
409 i64 val = dbuf_geti16x(f, zz->pos, is_le);
410 zz->pos += 2;
411 return val;
414 static i64 psd_dbuf_getu32_zz(dbuf *f, zztype *zz, int is_le)
416 i64 val = dbuf_getu32x(f, zz->pos, is_le);
417 zz->pos += 4;
418 return val;
421 static i64 psd_dbuf_geti32_zz(dbuf *f, zztype *zz, int is_le)
423 i64 val = dbuf_geti32x(f, zz->pos, is_le);
424 zz->pos += 4;
425 return val;
428 static i64 psd_dbuf_geti64_zz(dbuf *f, zztype *zz, int is_le)
430 i64 val = dbuf_geti64x(f, zz->pos, is_le);
431 zz->pos += 8;
432 return val;
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 = "?";
454 switch(n) {
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;
464 return name;
467 static void dbg_print_compression_method(deark *c, lctx *d, i64 cmpr)
469 const char *name = "?";
471 switch(cmpr) {
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);
487 zz->pos += 4;
490 // For rectangles in top-left-bottom-right order
491 static void read_rectangle_tlbr(deark *c, lctx *d, zztype *zz, const char *name)
493 i64 n[4];
494 i64 k;
495 for(k=0; k<4; k++) {
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)
504 i64 n[4];
505 i64 k;
506 for(k=0; k<4; k++) {
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)
515 i64 dlen;
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;
524 return;
527 dbuf_read_to_ucstring(c->infile, zz->pos, dlen, s, 0, d->input_encoding);
528 zz->pos += dlen;
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)
535 i64 dlen;
537 if(zz_avail(zz)<4) {
538 zz->pos = zz->endpos;
539 return;
542 dlen = psd_getu32zz(zz);
544 if(zz->pos + dlen > zz->endpos) { // error
545 zz->pos = zz->endpos;
546 return;
549 dbuf_read_to_ucstring(c->infile, zz->pos, dlen, s, 0, d->input_encoding);
550 zz->pos += dlen;
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)
556 i64 i;
557 int found = 0;
559 de_zeromem(ri_dst, sizeof(struct rsrc_info));
561 if(sig_id==CODE_PHUT) { // PhotoDeluxe resources seem to use incompatible formats.
562 ri_dst->id = n;
563 ri_dst->idname = "?";
564 return 0;
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 = "?";
571 return 1;
575 ri_dst->id = n;
576 ri_dst->idname = "?";
578 // Handle pattern-based resources that don't fit nicely in our table.
580 if(n>=0x07d0 && n<=0x0bb6) {
581 found = 1;
582 ri_dst->idname = "Path Information";
583 ri_dst->hfn = hrsrc_pathinfo;
585 else if(n>=0x0fa0 && n<=0x1387) {
586 found = 1;
587 ri_dst->idname = "Plug-In resource";
588 ri_dst->hfn = hrsrc_pluginresource;
591 return found;
594 static const char* units_name(i64 u)
596 switch(u) {
597 case 1: return "pixels/inch";
598 case 2: return "pixels/cm";
600 return "?";
603 static void hrsrc_resolutioninfo(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
605 i64 xres_int, yres_int;
606 double xres, yres;
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;
632 int idx = 0;
634 // This is a "series of Pascal strings", whatever that is.
636 s = ucstring_create(c);
637 while(zz->pos < (zz->endpos-1)) {
638 ucstring_empty(s);
639 read_pascal_string_to_ucstring(c, d, s, zz);
640 de_dbg(c, "%s[%d]: \"%s\"", ri->idname, idx, ucstring_getpsz_d(s));
641 idx++;
643 ucstring_destroy(s);
646 static void hrsrc_printflags(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
648 u8 fl[9];
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)
659 i64 num_records;
660 i64 i;
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++) {
665 zztype czz;
666 i64 t;
667 i64 x;
668 const char *name;
670 de_dbg(c, "path data record[%d] at %d", (int)i, (int)zz->pos);
671 zz_init_with_len(&czz, zz, 26);
672 de_dbg_indent(c, 1);
674 t = psd_getu16zz(&czz);
675 switch(t) {
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);
689 switch(t) {
690 case 0: case 3:
691 x = psd_getu16zz(&czz);
692 de_dbg(c, "number of Bezier knot records: %d", (int)x);
693 break;
694 case 8:
695 x = psd_getu16zz(&czz);
696 de_dbg(c, "value: %d", (int)x);
697 break;
700 zz->pos += 26;
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;
713 u8 crop_marks;
715 if(zz_avail(zz)!=10) return;
716 version = psd_getu16zz(zz);
717 crop_marks = psd_getbytezz(zz);
718 zz->pos++;
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)
733 d->has_iptc = 1;
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;
750 i64 len;
751 zztype czz;
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);
771 done:
775 static void do_pluginrsrc_mopt(deark *c, lctx *d, zztype *zz)
777 i64 x;
778 i64 num_items;
779 i64 i;
780 int saved_indent_level;
781 zztype czz;
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++) {
793 i64 dlen;
794 i64 something_len;
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);
799 de_dbg_indent(c, 1);
801 de_dbg(c, "[%d bytes of data at %d]", (int)something_len, (int)zz->pos);
802 if(c->debug_level>=2) {
803 de_dbg_indent(c, 1);
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, "");
817 zz->pos += dlen;
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)
829 zztype czz;
830 zz_init(&czz, 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;
837 zztype czz;
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);
843 zz_init(&czz, zz);
844 switch(fourcc.id) {
845 case CODE_mani:
846 do_pluginrsrc_mani(c, d, &czz);
847 break;
848 case CODE_mopt:
849 do_pluginrsrc_mopt(c, d, &czz);
850 break;
851 case CODE_mset:
852 do_pluginrsrc_descriptor(c, d, &czz);
853 break;
854 default:
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) {
859 de_dbg_indent(c, 1);
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)
871 i64 num_code_units;
873 if(zz_avail(zz)<4) { // error
874 zz->pos = zz->endpos;
875 return;
878 num_code_units = psd_getu32zz(zz);
879 if(zz->pos + num_code_units*2 > zz->endpos) { // error
880 zz->pos = zz->endpos;
881 return;
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)
897 if(flid->s) {
898 ucstring_destroy(flid->s);
899 flid->s = NULL;
901 if(flid->sz) {
902 de_free(c, flid->sz);
903 flid->sz = NULL;
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)
911 i64 length;
913 de_zeromem(flid, sizeof(struct flexible_id));
915 length = psd_getu32(pos);
916 if(length==0) {
917 flid->is_fourcc = 1;
918 dbuf_read_fourcc(c->infile, pos+4, &flid->fourcc, 4, d->is_le ? DE_4CCFLAG_REVERSED : 0);
919 flid->bytes_consumed = 4 + 4;
921 else {
922 i64 adjusted_length;
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);
951 else {
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)
958 u8 b;
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)
966 i64 n;
967 // No idea if this is signed or unsigned.
968 n = psd_geti32zz(zz);
969 de_dbg(c, "value: %d", (int)n);
972 // "Double"
973 static void do_item_type_doub(deark *c, lctx *d, zztype *zz)
975 double v;
976 v = dbuf_getfloat64x(c->infile, zz->pos, d->is_le);
977 de_dbg(c, "value: %f", v);
978 zz->pos += 8;
981 // "Unit float"
982 static void do_item_type_UntF(deark *c, lctx *d, zztype *zz)
984 double v;
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);
992 zz->pos += 8;
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);
1009 return 1;
1012 static int do_item_type_alis(deark *c, lctx *d, zztype *zz)
1014 i64 x;
1016 x = psd_getu32zz(zz);
1017 de_dbg(c, "alias length: %d", (int)x);
1018 zz->pos += x;
1019 return 1;
1022 // Undocumented UnFl descriptor item type
1023 static void do_item_type_UnFl(deark *c, lctx *d, zztype *zz)
1025 i64 count;
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)
1039 if(len<1) return;
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)
1060 i64 dlen;
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) {
1067 return 0;
1070 if(key_flid->sz) {
1071 if(!de_strcmp(key_flid->sz, "EngineData")) {
1072 do_text_engine_data(c, d, zz->pos, dlen);
1076 zz->pos += dlen;
1077 return 1;
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);
1095 // "List"
1096 static int do_item_type_VlLs(deark *c, lctx *d,
1097 const struct flexible_id *key_flid, zztype *zz, i64 outer_itempos)
1099 i64 num_items;
1100 i64 i;
1101 int ret;
1102 int retval = 0;
1103 zztype czz;
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);
1109 goto done;
1112 if(d->nesting_level>MAX_NESTING_LEVEL) goto done;
1114 for(i=0; i<num_items; i++) {
1115 i64 inner_itempos;
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);
1120 d->nesting_level++;
1121 zz_init(&czz, zz);
1122 ret = do_descriptor_item_ostype_and_data(c, d, key_flid, &czz, inner_itempos);
1123 d->nesting_level--;
1124 de_dbg_indent(c, -1);
1125 if(!ret) goto done;
1126 zz->pos += zz_used(&czz);
1129 retval = 1;
1130 done:
1131 return retval;
1134 static int do_item_type_descriptor(deark *c, lctx *d, zztype *zz, int has_version)
1136 int retval = 0;
1138 d->nesting_level++;
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, "");
1144 done:
1145 d->nesting_level--;
1146 return retval;
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);
1171 return 1;
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);
1192 return 1;
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);
1222 return 1;
1225 static int do_rele_reference(deark *c, lctx *d, zztype *zz)
1227 de_ucstring *tmps = NULL;
1228 struct flexible_id flid;
1229 i64 offs;
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);
1245 return 1;
1248 static int do_indx_reference(deark *c, lctx *d, zztype *zz)
1250 de_ucstring *tmps = NULL;
1251 struct flexible_id flid;
1252 i64 x;
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);
1271 return 1;
1274 // "Reference structure"
1275 static int do_item_type_obj(deark *c, lctx *d, zztype *zz)
1277 i64 num_items;
1278 i64 i;
1279 int retval = 0;
1280 int saved_indent_level;
1281 zztype czz;
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;
1290 i64 itempos;
1292 itempos = zz->pos;
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);
1299 zz_init(&czz, zz);
1300 switch(type4cc.id) {
1301 case CODE_Enmr:
1302 if(!do_Enmr_reference(c, d, &czz)) goto done;
1303 zz->pos += zz_used(&czz);
1304 break;
1305 case CODE_prop:
1306 if(!do_prop_reference(c, d, &czz)) goto done;
1307 zz->pos += zz_used(&czz);
1308 break;
1309 case CODE_name:
1310 if(!do_name_reference(c, d, &czz)) goto done;
1311 zz->pos += zz_used(&czz);
1312 break;
1313 case CODE_Clss:
1314 if(!do_Clss_reference(c, d, &czz)) goto done;
1315 zz->pos += zz_used(&czz);
1316 break;
1317 case CODE_rele:
1318 if(!do_rele_reference(c, d, &czz)) goto done;
1319 zz->pos += zz_used(&czz);
1320 break;
1321 case CODE_indx:
1322 if(!do_indx_reference(c, d, &czz)) goto done;
1323 zz->pos += zz_used(&czz);
1324 break;
1325 default:
1326 // TODO: 'Idnt'
1327 goto done;
1330 de_dbg_indent(c, -1);
1333 retval = 1;
1334 done:
1335 de_dbg_indent_restore(c, saved_indent_level);
1336 return retval;
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)
1343 int ret;
1344 int retval = 0;
1345 struct de_fourcc type4cc;
1346 zztype czz;
1348 psd_read_fourcc_zz(c, d, zz, &type4cc);
1349 de_dbg(c, "item OSType: '%s'", type4cc.id_dbgstr);
1351 zz_init(&czz, zz);
1353 switch(type4cc.id) {
1354 case CODE_bool:
1355 do_item_type_bool(c, d, &czz);
1356 zz->pos += zz_used(&czz);
1357 break;
1358 case CODE_long:
1359 do_item_type_long(c, d, &czz);
1360 zz->pos += zz_used(&czz);
1361 break;
1362 case CODE_doub:
1363 do_item_type_doub(c, d, &czz);
1364 zz->pos += zz_used(&czz);
1365 break;
1366 case CODE_comp:
1367 // TODO
1368 zz->pos += 8;
1369 break;
1370 case CODE_UntF:
1371 do_item_type_UntF(c, d, &czz);
1372 zz->pos += zz_used(&czz);
1373 break;
1374 case CODE_UnFl:
1375 do_item_type_UnFl(c, d, &czz);
1376 zz->pos += zz_used(&czz);
1377 break;
1378 case CODE_TEXT:
1379 do_item_type_TEXT(c, d, &czz);
1380 zz->pos += zz_used(&czz);
1381 break;
1382 case CODE_enum:
1383 do_item_type_enum(c, d, &czz);
1384 zz->pos += zz_used(&czz);
1385 break;
1386 case CODE_VlLs:
1387 ret = do_item_type_VlLs(c, d, key_flid, &czz, itempos);
1388 zz->pos += zz_used(&czz);
1389 if(!ret) goto done;
1390 break;
1391 case CODE_Objc:
1392 case CODE_GlbO:
1393 ret = do_item_type_descriptor(c, d, &czz, 0);
1394 zz->pos += zz_used(&czz);
1395 if(!ret) goto done;
1396 break;
1397 case CODE_ObAr:
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);
1401 if(!ret) goto done;
1402 break;
1403 case CODE_obj:
1404 ret = do_item_type_obj(c, d, &czz);
1405 zz->pos += zz_used(&czz);
1406 if(!ret) goto done;
1407 break;
1408 case CODE_tdta:
1409 ret = do_item_type_tdta(c, d, key_flid, &czz);
1410 zz->pos += zz_used(&czz);
1411 if(!ret) goto done;
1412 break;
1413 case CODE_type:
1414 case CODE_GlbC:
1415 ret = do_item_type_class(c, d, &czz);
1416 zz->pos += zz_used(&czz);
1417 if(!ret) goto done;
1418 break;
1419 case CODE_alis:
1420 ret = do_item_type_alis(c, d, &czz);
1421 zz->pos += zz_used(&czz);
1422 if(!ret) goto done;
1423 break;
1424 // TODO: 'Pth ' (undocumented type)
1425 default:
1426 goto done;
1429 retval = 1;
1430 done:
1431 return retval;
1434 static int do_descriptor_item(deark *c, lctx *d, zztype *zz)
1436 struct flexible_id key;
1437 zztype czz;
1438 i64 itempos;
1439 int ret;
1441 itempos = zz->pos;
1443 read_flexible_id_zz(c, d, zz, &key);
1444 dbg_print_flexible_id(c, d, &key, "key");
1446 zz_init(&czz, zz);
1447 ret = do_descriptor_item_ostype_and_data(c, d, &key, &czz, itempos);
1448 flexible_id_free_contents(c, &key);
1449 if(!ret) return 0;
1450 zz->pos += zz_used(&czz);
1452 return 1;
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;
1463 i64 ver_pos = 0;
1464 i64 dscr_pos;
1465 i64 num_items;
1466 i64 i;
1467 int ret;
1468 int retval = 0;
1469 i64 dv = 16;
1470 zztype czz;
1471 int saved_indent_level;
1473 de_dbg_indent_save(c, &saved_indent_level);
1475 if(has_version) {
1476 ver_pos = zz->pos;
1477 dv = psd_getu32zz(zz);
1480 dscr_pos = zz->pos;
1482 if(has_version) {
1483 de_dbg(c, "descriptor%s at %d (version# at %d)", dscrname, (int)dscr_pos, (int)ver_pos);
1485 else {
1486 de_dbg(c, "descriptor%s at %d", dscrname, (int)dscr_pos);
1489 if(dv!=16) {
1490 de_warn(c, "Unsupported descriptor version: %d", (int)dv);
1491 goto done;
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);
1509 // Descriptor 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);
1513 goto done;
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);
1517 zz_init(&czz, zz);
1518 ret = do_descriptor_item(c, d, &czz);
1519 if(!ret) {
1520 de_dbg(c, "[Failed to fully decode descriptor item.]");
1522 de_dbg_indent(c, -1);
1523 if(!ret) goto done;
1524 zz->pos += zz_used(&czz);
1527 retval = 1;
1529 done:
1530 de_dbg_indent_restore(c, saved_indent_level);
1531 ucstring_destroy(name_from_classid);
1532 return retval;
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;
1544 int retval = 0;
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);
1557 if(origin==1) {
1558 i64 layer_id;
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
1564 if(s->len>0) {
1565 de_dbg(c, "name: \"%s\"", ucstring_getpsz(s));
1567 ucstring_empty(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
1575 ucstring_empty(s);
1577 read_unicode_string(c, d, s, zz); // Target
1578 ucstring_empty(s);
1580 read_unicode_string(c, d, s, zz); // Message
1581 ucstring_empty(s);
1583 read_unicode_string(c, d, s, zz); // Alt Tag
1584 ucstring_empty(s);
1586 zz->pos += 1; // Flag: Cell text is HTML
1588 read_unicode_string(c, d, s, zz); // Cell text
1589 ucstring_empty(s);
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;
1596 retval = 1;
1598 done:
1599 ucstring_destroy(s);
1600 return retval;
1603 static void do_slices_v6(deark *c, lctx *d, zztype *zz)
1605 i64 num_slices;
1606 i64 i;
1607 de_ucstring *name_of_group_of_slices = NULL;
1608 zztype czz;
1609 int ret;
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);
1627 goto done;
1629 de_dbg(c, "slice[%d] at %d", (int)i, (int)zz->pos);
1630 de_dbg_indent(c, 1);
1631 zz_init(&czz, zz);
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)");
1647 if(!ret) goto done;
1649 done:
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)
1661 i64 sver;
1663 if(zz_avail(zz)<4) return;
1664 sver = psd_getu32(zz->pos);
1665 de_dbg(c, "slices resource format version: %d", (int)sver);
1667 if(sver==6) {
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)
1677 i64 fmt;
1678 const char *ext;
1679 dbuf *outf = NULL;
1680 i64 dpos;
1681 i64 dlen;
1683 if(zz_avail(zz)<=28) goto done;
1685 fmt = psd_getu32(zz->pos);
1686 if(fmt != 1) {
1687 // fmt != kJpegRGB
1688 de_dbg(c, "thumbnail in unsupported format (%d) found", (int)fmt);
1689 goto done;
1692 zz->pos += 28;
1693 dpos = zz->pos;
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.");
1703 else {
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);
1719 else {
1720 dbuf_copy(c->infile, dpos, dlen, outf);
1723 done:
1724 dbuf_close(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)
1730 u8 b;
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)
1738 i64 n;
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)
1746 i64 n;
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;
1769 int idx = 0;
1771 s = ucstring_create(c);
1772 while(zz_avail(zz)>=4) {
1773 ucstring_empty(s);
1774 read_unicode_string(c, d, s, zz);
1775 de_dbg(c, "%s[%d]: \"%s\"", ri->idname, idx, ucstring_getpsz_d(s));
1776 idx++;
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;
1807 i64 count;
1808 i64 i;
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;
1817 i64 id;
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));
1827 ucstring_empty(s);
1830 ucstring_destroy(s);
1833 static void hrsrc_versioninfo(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
1835 i64 ver, file_ver;
1836 u8 b;
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));
1849 ucstring_empty(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)
1861 i64 style;
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);
1867 zz->pos += 4;
1868 yloc = dbuf_getfloat32x(c->infile, zz->pos, d->is_le);
1869 zz->pos += 4;
1870 de_dbg(c, "location: (%f,%f)", xloc, yloc);
1871 scale = dbuf_getfloat32x(c->infile, zz->pos, d->is_le);
1872 zz->pos += 4;
1873 de_dbg(c, "scale: %f", scale);
1876 static void hrsrc_pixelaspectratio(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
1878 i64 version;
1879 double ratio;
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);
1884 zz->pos += 8;
1885 de_dbg(c, "x/y: %f", ratio);
1888 static void hrsrc_layerselectionids(deark *c, lctx *d, zztype *zz, const struct rsrc_info *ri)
1890 i64 count;
1891 int i;
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++) {
1898 i64 lyid;
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)
1906 i64 resource_id;
1907 i64 block_data_len;
1908 struct rsrc_info ri;
1909 de_ucstring *blkname = NULL;
1910 struct de_fourcc sig4cc;
1911 const char *signame = "Photoshop";
1912 zztype czz;
1913 int retval = 0;
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
1923 signame = "AgHg";
1925 else if(sig4cc.id==CODE_DCSR) { // ExifTool says this exists
1926 signame = "DCSR";
1928 else if(sig4cc.id==CODE_MeSa) { // Image Ready resource?
1929 signame = "MeSa";
1931 else if(sig4cc.id==CODE_PHUT) { // PhotoDeluxe resource?
1932 signame = "PHUT";
1934 else {
1935 de_warn(c, "Bad Photoshop resource block signature '%s' at %d",
1936 sig4cc.id_sanitized_sz, (int)zz->startpos);
1937 goto done;
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);
1944 zz_init(&czz, zz);
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);
1963 if(ri.hfn) {
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);
1979 retval = 1;
1981 done:
1982 if(blkname) ucstring_destroy(blkname);
1983 return retval;
1986 static void do_image_resource_blocks(deark *c, lctx *d, zztype *zz)
1988 zztype czz;
1990 while(1) {
1991 if(zz->pos>=zz->endpos) break;
1992 zz_init(&czz, zz);
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)
2001 i64 dlen;
2002 dlen = psd_getu32zz(zz);
2003 de_dbg(c, "layer mask data size: %d", (int)dlen);
2004 zz->pos += dlen;
2007 static void do_layer_blending_ranges(deark *c, lctx *d, zztype *zz)
2009 i64 dlen;
2010 dlen = psd_getu32zz(zz);
2011 de_dbg(c, "layer blending ranges data size: %d", (int)dlen);
2012 zz->pos += 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 {
2028 i64 num_channels;
2029 i64 total_len;
2032 static int do_layer_record(deark *c, lctx *d, zztype *zz, struct channel_data *cd)
2034 i64 nchannels;
2035 i64 extra_data_len;
2036 struct de_fourcc tmp4cc;
2037 i64 ch_id, ch_dlen;
2038 u8 b;
2039 int i;
2040 zztype czz;
2041 zztype extradatazz;
2042 int retval = 0;
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 cd->num_channels++;
2054 cd->total_len += ch_dlen;
2057 psd_read_fourcc_zz(c, d, zz, &tmp4cc);
2058 if(tmp4cc.id != CODE_8BIM) {
2059 de_warn(c, "Expected blend mode signature not found at %d", (int)(zz->pos-4));
2060 goto done;
2063 psd_read_fourcc_zz(c, d, zz, &tmp4cc);
2064 de_dbg(c, "blend mode: '%s'", tmp4cc.id_dbgstr);
2066 b = psd_getbytezz(zz);
2067 de_dbg(c, "opacity: %d", (int)b);
2069 b = psd_getbytezz(zz);
2070 de_dbg(c, "clipping: %d", (int)b);
2072 b = psd_getbytezz(zz);
2073 de_dbg(c, "flags: 0x%02x", (unsigned int)b);
2075 zz->pos += 1; // filler
2077 extra_data_len = psd_getu32zz(zz);
2079 if(zz->pos + extra_data_len > zz->endpos) {
2080 de_warn(c, "Malformed layer record at %d", (int)zz->startpos);
2081 goto done;
2084 zz_init_with_len(&extradatazz, zz, extra_data_len);
2085 zz->pos = extradatazz.endpos;
2087 zz_init(&czz, &extradatazz);
2088 do_layer_mask_data(c, d, &czz);
2089 extradatazz.pos += zz_used(&czz);
2091 zz_init(&czz, &extradatazz);
2092 do_layer_blending_ranges(c, d, &czz);
2093 extradatazz.pos += zz_used(&czz);
2095 zz_init(&czz, &extradatazz);
2096 do_layer_name(c, d, &czz);
2097 extradatazz.pos += zz_used(&czz);
2099 if(extradatazz.pos < extradatazz.endpos) {
2100 // The rest of the layer record data seems to be undocumented,
2101 // or unclearly documented.
2102 de_dbg(c, "layer record tagged blocks at %d, len=%d",
2103 (int)extradatazz.pos, (int)(extradatazz.endpos-extradatazz.pos));
2104 de_dbg_indent(c, 1);
2105 zz_init(&czz, &extradatazz);
2106 do_tagged_blocks(c, d, &czz, 0);
2107 de_dbg_indent(c, -1);
2110 retval = 1;
2111 done:
2112 return retval;
2115 static int do_layer_info_section(deark *c, lctx *d, zztype *zz, int has_len_field)
2117 int retval = 0;
2118 i64 layer_info_len;
2119 i64 layer_count_raw, layer_count;
2120 int saved_indent_level;
2121 int merged_result_flag;
2122 i64 layer_idx;
2123 zztype datazz;
2124 zztype czz;
2125 struct channel_data *cd = NULL;
2127 de_dbg_indent_save(c, &saved_indent_level);
2128 if(zz_avail(zz)<4) goto done;
2130 de_dbg(c, "layer info section at %d", (int)zz->pos);
2131 de_dbg_indent(c, 1);
2133 if(has_len_field) {
2134 layer_info_len = psd_getu32or64zz(c, d, zz);
2135 de_dbg(c, "length of layer info section: %d", (int)layer_info_len);
2137 else {
2138 layer_info_len = zz_avail(zz);
2140 zz_init_with_len(&datazz, zz, layer_info_len);
2141 zz->pos += layer_info_len;
2142 retval = 1;
2144 if(datazz.pos>=datazz.endpos) {
2145 // If the length field is 0, it's legal for this section to end here.
2146 goto done;
2149 layer_count_raw = psd_geti16zz(&datazz);
2150 if(layer_count_raw<0) {
2151 merged_result_flag = 1;
2152 layer_count = -layer_count_raw;
2154 else {
2155 merged_result_flag = 0;
2156 layer_count = layer_count_raw;
2158 de_dbg(c, "layer count: %d", (int)layer_count);
2159 de_dbg(c, "merged result flag: %d", (int)merged_result_flag);
2161 // Due to the recursive possibilities of PSD format, it would probably
2162 // be a bad idea to store this channel information in the 'd' struct.
2163 // Instead, we'll use a local variable.
2164 cd = de_malloc(c, sizeof(struct channel_data));
2165 cd->num_channels = 0;
2166 cd->total_len = 0;
2168 for(layer_idx=0; layer_idx<layer_count; layer_idx++) {
2169 de_dbg(c, "layer record[%d] at %d", (int)layer_idx, (int)datazz.pos);
2170 de_dbg_indent(c, 1);
2171 zz_init(&czz, &datazz);
2172 if(!do_layer_record(c, d, &czz, cd))
2173 goto done;
2174 datazz.pos += zz_used(&czz);
2175 de_dbg_indent(c, -1);
2178 de_dbg(c, "channel image data records at %d, count=%d, total len=%"I64_FMT"",
2179 (int)datazz.pos, (int)cd->num_channels, cd->total_len);
2181 done:
2182 de_dbg_indent_restore(c, saved_indent_level);
2183 de_free(c, cd);
2184 return retval;
2187 static void do_uint32_block(deark *c, lctx *d, zztype *zz,
2188 const struct de_fourcc *blk4cc, const char *name)
2190 i64 value;
2192 if(zz_avail(zz)!=4) return;
2193 value = psd_getu32zz(zz);
2194 de_dbg(c, "%s: %d", name, (int)value);
2197 static void do_boolean_block(deark *c, lctx *d, zztype *zz,
2198 const struct de_fourcc *blk4cc, const char *name)
2200 u8 value;
2201 i64 len;
2203 len = zz_avail(zz);
2204 if(len<1 || len>4) return;
2205 value = psd_getbytezz(zz);
2206 de_dbg(c, "%s: %d", name, (int)value);
2209 static void do_fourcc_block(deark *c, lctx *d, zztype *zz,
2210 const struct de_fourcc *blk4cc, const char *name)
2212 struct de_fourcc fourcc;
2214 if(zz_avail(zz)!=4) return;
2215 psd_read_fourcc_zz(c, d, zz, &fourcc);
2216 de_dbg(c, "%s: '%s'", name, fourcc.id_dbgstr);
2219 static void do_Layr_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2221 // "Layer info" section, but starting with the "Layer count" field
2222 do_layer_info_section(c, d, zz, 0);
2225 static void extract_linked_layer_blob(deark *c, lctx *d, i64 pos, i64 len)
2227 const char *ext = "layer.bin";
2228 u8 buf[8];
2230 if(len<1) return;
2232 // Sniff the file type.
2233 // (The "File Type" FourCC is not reliable.)
2234 de_read(buf, pos, sizeof(buf));
2235 if(!de_memcmp(buf, "8BPS\x00\x01", 6)) {
2236 ext = "layer.psd";
2238 else if(!de_memcmp(buf, "8BPS\x00\x02", 6)) {
2239 ext = "layer.psb";
2241 else if(!de_memcmp(buf, "\x89\x50\x4e\x47", 4)) {
2242 ext = "layer.png";
2244 else if(!de_memcmp(buf, "\xff\xd8\xff", 3)) {
2245 ext = "layer.jpg";
2247 else if(!de_memcmp(buf, "%PDF", 4)) {
2248 ext = "layer.pdf";
2251 // TODO: Maybe we should try to use the "original filename" field, somehow,
2252 // to construct our filename.
2253 dbuf_create_file_from_slice(c->infile, pos, len, ext,
2254 NULL, DE_CREATEFLAG_IS_AUX);
2257 static int do_one_linked_layer(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2259 int retval = 0;
2260 i64 dlen, dlen2=0;
2261 i64 ver;
2262 u8 file_open_descr_flag;
2263 struct de_fourcc type4cc;
2264 struct de_fourcc tmp4cc;
2265 de_ucstring *s = NULL;
2266 zztype datazz;
2268 dlen = psd_geti64zz(zz);
2269 de_dbg(c, "length: %"I64_FMT"", dlen);
2270 if(dlen<8 || zz->pos+dlen>zz->endpos) {
2271 de_warn(c, "Bad linked layer size %"I64_FMT" at %"I64_FMT"", dlen, zz->startpos);
2272 goto done;
2275 zz_init_with_len(&datazz, zz, dlen);
2277 // Seems to be padded to a multiple of 4 bytes. (The spec says nothing
2278 // about this.)
2279 zz->pos += de_pad_to_4(dlen);
2280 retval = 1;
2282 psd_read_fourcc_zz(c, d, &datazz, &type4cc);
2283 de_dbg(c, "type: '%s'", type4cc.id_dbgstr);
2285 ver = psd_getu32zz(&datazz);
2286 de_dbg(c, "version: %d", (int)ver);
2288 s = ucstring_create(c);
2289 read_pascal_string_to_ucstring(c, d, s, &datazz);
2290 de_dbg(c, "unique id: \"%s\"", ucstring_getpsz(s));
2292 ucstring_empty(s);
2293 read_unicode_string(c, d, s, &datazz);
2294 de_dbg(c, "original file name: \"%s\"", ucstring_getpsz(s));
2296 psd_read_fourcc_zz(c, d, &datazz, &tmp4cc);
2297 de_dbg(c, "file type: '%s'", tmp4cc.id_dbgstr);
2299 psd_read_fourcc_zz(c, d, &datazz, &tmp4cc);
2300 de_dbg(c, "file creator: '%s'", tmp4cc.id_dbgstr);
2302 dlen2 = psd_geti64zz(&datazz);
2303 de_dbg(c, "length2: %"I64_FMT"", dlen2);
2304 if(dlen2<0) goto done;
2306 file_open_descr_flag = psd_getbytezz(&datazz);
2307 de_dbg(c, "has file open descriptor: %d", (int)file_open_descr_flag);
2309 if(file_open_descr_flag) {
2310 if(!read_descriptor(c, d, &datazz, 1, " (of open parameters)")) {
2311 goto done;
2315 if(type4cc.id!=CODE_liFD) {
2316 // TODO: liFA and liFE need special handling.
2317 de_dbg(c, "[this linked layer type is not supported]");
2318 goto done;
2321 de_dbg(c, "raw file bytes at %"I64_FMT", len=%"I64_FMT"", datazz.pos, dlen2);
2322 extract_linked_layer_blob(c, d, datazz.pos, dlen2);
2324 // TODO: There may be more fields after this, depending on the version.
2326 done:
2327 ucstring_destroy(s);
2328 return retval;
2331 static void do_lnk2_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2333 int ret;
2334 zztype czz;
2336 while(zz->pos<zz->endpos) {
2337 de_dbg(c, "linked layer data at %"I64_FMT"", zz->pos);
2338 de_dbg_indent(c, 1);
2339 zz_init(&czz, zz);
2340 ret = do_one_linked_layer(c, d, &czz, blk4cc);
2341 de_dbg_indent(c, -1);
2342 if(!ret) break;
2343 zz->pos += zz_used(&czz);
2347 static void do_vm_array(deark *c, lctx *d, zztype *zz)
2349 i64 n;
2350 i64 dlen, idata_len;
2351 i64 saved_pos;
2353 zz->pos += 4; // Skip array-is-written flag (already processed)
2355 dlen = psd_getu32zz(zz);
2356 de_dbg(c, "length: %d", (int)dlen);
2357 if(dlen==0) goto done;
2359 saved_pos = zz->pos;
2361 n = psd_getu32zz(zz);
2362 de_dbg(c, "depth: %d", (int)n);
2364 read_rectangle_tlbr(c, d, zz, "rectangle");
2366 n = psd_getu16zz(zz);
2367 de_dbg(c, "depth: %d", (int)n);
2369 n = (i64)psd_getbytezz(zz);
2370 dbg_print_compression_method(c, d, n);
2372 idata_len = saved_pos + dlen - zz->pos;
2373 de_dbg(c, "[%d bytes of data at %d]", (int)idata_len, (int)zz->pos);
2375 zz->pos = saved_pos + dlen;
2376 done:
2380 static void do_vm_array_list(deark *c, lctx *d, zztype *zz)
2382 i64 ver;
2383 i64 dlen;
2384 i64 num_channels;
2385 zztype czz;
2386 i64 i;
2388 de_dbg(c, "virtual memory array list at %d, len=%"I64_FMT"", (int)zz->pos,
2389 zz_avail(zz));
2390 de_dbg_indent(c, 1);
2392 ver = psd_getu32zz(zz);
2393 de_dbg(c, "version: %d", (int)ver);
2395 dlen = psd_getu32zz(zz);
2396 de_dbg(c, "length: %d", (int)dlen);
2398 read_rectangle_tlbr(c, d, zz, "rectangle");
2400 num_channels = psd_getu32zz(zz);
2401 de_dbg(c, "number of channels: %d", (int)num_channels);
2403 for(i=0; i<num_channels+2; i++) {
2404 i64 is_written;
2406 // Look ahead at the array-is-written flag.
2407 is_written = psd_getu32(zz->pos);
2409 de_dbg(c, "virtual memory array[%d] at %d%s", (int)i, (int)zz->pos,
2410 is_written?"":" (empty)");
2411 if(is_written) {
2412 zz_init(&czz, zz);
2413 de_dbg_indent(c, 1);
2414 do_vm_array(c, d, &czz);
2415 de_dbg_indent(c, -1);
2416 zz->pos += zz_used(&czz);
2418 else {
2419 zz->pos += 4;
2423 de_dbg_indent(c, -1);
2426 // The main part of a "pattern" object, starting with the version and
2427 // color_mode[l] fields.
2428 static int do_pattern_internal(deark *c, lctx *d, zztype *zz)
2430 i64 pat_color_mode;
2431 i64 ver;
2432 i64 w, h;
2433 de_ucstring *s = NULL;
2434 zztype vmalzz; // for virtual memory array list
2435 int retval = 0;
2437 ver = psd_getu32zz(zz);
2438 de_dbg(c, "version: %d", (int)ver);
2439 if(ver!=1) goto done;
2441 pat_color_mode = psd_getu32zz(zz);
2442 de_dbg(c, "color mode: %d (%s)", (int)pat_color_mode, get_colormode_name(pat_color_mode));
2444 h = psd_getu16zz(zz);
2445 w = psd_getu16zz(zz);
2446 de_dbg_dimensions(c, w, h);
2448 s = ucstring_create(c);
2449 read_unicode_string(c, d, s, zz);
2450 de_dbg(c, "name: \"%s\"", ucstring_getpsz_d(s));
2452 ucstring_empty(s);
2453 read_pascal_string_to_ucstring(c, d, s, zz);
2454 de_dbg(c, "id: \"%s\"", ucstring_getpsz_d(s));
2456 if(pat_color_mode==PSD_CM_PALETTE) {
2457 de_dbg(c, "palette at %d", (int)zz->pos);
2458 zz->pos += 3*256;
2461 zz_init(&vmalzz, zz);
2462 do_vm_array_list(c, d, &vmalzz);
2463 zz->pos += zz_used(&vmalzz);
2464 retval = 1;
2465 done:
2466 ucstring_destroy(s);
2467 return retval;
2470 // Decode a single "pattern" object, starting with the "length" field for this
2471 // pattern.
2472 static int do_pattern(deark *c, lctx *d, zztype *zz, i64 pattern_idx)
2474 i64 pat_dlen;
2475 zztype datazz; // zz for the pattern data (minus the length field)
2476 int retval = 0;
2478 if(zz_avail(zz)<16) goto done;
2480 de_dbg(c, "pattern[%d] at %d", (int)pattern_idx, (int)zz->pos);
2481 de_dbg_indent(c, 1);
2483 pat_dlen = psd_getu32zz(zz);
2484 de_dbg(c, "length: %d", (int)pat_dlen);
2486 zz_init_with_len(&datazz, zz, pat_dlen);
2488 do_pattern_internal(c, d, &datazz);
2490 zz->pos += de_pad_to_4(pat_dlen);
2492 de_dbg_indent(c, -1);
2494 retval = 1;
2495 done:
2496 return retval;
2499 static void do_pattern_sequence(deark *c, lctx *d, zztype *zz)
2501 i64 pattern_idx;
2502 zztype czz;
2504 pattern_idx = 0;
2505 while(1) {
2506 if(zz_avail(zz)<16) break;
2507 zz_init(&czz, zz);
2508 if(!do_pattern(c, d, &czz, pattern_idx)) {
2509 break;
2511 zz->pos += zz_used(&czz);
2512 pattern_idx++;
2516 static void do_Patt_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *xblk4cc)
2518 do_pattern_sequence(c, d, zz);
2521 // Process a v6.1 'samp' block, starting right after the ID.
2522 static void do_samp_block_v61stuff(deark *c, lctx *d, zztype *zz)
2524 i64 n;
2525 i64 idata_len;
2527 // This code is based on guesswork, and may not be correct.
2529 zz->pos += 8; // 8 unknown bytes
2531 // Note the similarity to vm_array.
2533 n = psd_getu16zz(zz);
2534 de_dbg(c, "depth: %d", (int)n);
2536 read_rectangle_tlbr(c, d, zz, "rectangle");
2538 n = psd_getu16zz(zz);
2539 de_dbg(c, "depth: %d", (int)n);
2541 n = (i64)psd_getbytezz(zz);
2542 dbg_print_compression_method(c, d, n);
2544 idata_len = zz_avail(zz);
2545 de_dbg(c, "[%d bytes of data at %d]", (int)idata_len, (int)zz->pos);
2549 // Process a v6.2 'samp' block, starting right after the ID.
2550 static void do_samp_block_v62stuff(deark *c, lctx *d, zztype *zz)
2552 i64 x;
2553 zztype czz;
2555 // This code is based on guesswork, and may not be correct.
2557 // I don't know what the first 4 bytes are for. Observed to be 00 01 00 00.
2558 x = psd_getu32zz(zz);
2559 if(x != 0x00010000) {
2560 return;
2563 zz_init(&czz, zz);
2564 do_vm_array_list(c, d, &czz);
2567 static void do_samp_block(deark *c, lctx *d, zztype *zz)
2569 i64 item_idx;
2570 int saved_indent_level;
2571 de_ucstring *tmps = NULL;
2572 zztype czz;
2574 // Note: This code is based on guesswork, and may be incorrect.
2576 de_dbg_indent_save(c, &saved_indent_level);
2577 tmps = ucstring_create(c);
2579 item_idx = 0;
2580 while(1) {
2581 i64 item_data_len2;
2582 zztype datazz; // zz for the item data (minus the length field)
2584 if(zz->pos+16 > zz->endpos) break;
2586 de_dbg(c, "item[%d] at %d", (int)item_idx, (int)zz->pos);
2587 de_dbg_indent(c, 1);
2589 item_data_len2 = psd_getu32zz(zz);
2590 de_dbg(c, "length: %d", (int)item_data_len2);
2592 zz_init_with_len(&datazz, zz, item_data_len2);
2594 ucstring_empty(tmps);
2595 read_pascal_string_to_ucstring(c, d, tmps, &datazz);
2596 de_dbg(c, "id: \"%s\"", ucstring_getpsz_d(tmps));
2598 if(d->abr_major_ver==6 && d->abr_minor_ver<=1) {
2599 zz_init(&czz, &datazz);
2600 do_samp_block_v61stuff(c, d, &czz);
2602 else if(d->abr_major_ver>6 || (d->abr_major_ver==6 && d->abr_minor_ver>=2)) {
2603 zz_init(&czz, &datazz);
2604 do_samp_block_v62stuff(c, d, &czz);
2607 zz->pos += de_pad_to_4(item_data_len2);
2609 de_dbg_indent(c, -1);
2610 item_idx++;
2613 ucstring_destroy(tmps);
2614 de_dbg_indent_restore(c, saved_indent_level);
2617 static void do_lrFX_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2619 i64 ver;
2620 i64 count;
2621 i64 i;
2622 u32 sig;
2623 struct de_fourcc sig4cc;
2625 ver = psd_getu16zz(zz);
2626 if(ver!=0) goto done;
2628 count = psd_getu16zz(zz);
2629 de_dbg(c, "effects count: %d", (int)count);
2631 for(i=0; i<count; i++) {
2632 i64 epos;
2633 i64 dlen;
2635 if(zz->pos>=zz->endpos) goto done;
2636 epos = zz->pos;
2638 sig = (u32)psd_getu32zz(zz);
2639 if(sig!=CODE_8BIM) {
2640 de_warn(c, "Bad 'effects' block signature at %d", (int)zz->pos);
2641 goto done;
2644 psd_read_fourcc_zz(c, d, zz, &sig4cc);
2646 dlen = psd_getu32zz(zz);
2648 de_dbg(c, "effects[%d] '%s' at %d, dpos=%d, dlen=%d", (int)i, sig4cc.id_dbgstr,
2649 (int)epos, (int)zz->pos, (int)dlen);
2650 zz->pos += dlen;
2653 done:
2657 static void do_fxrp_block(deark *c, lctx *d, zztype *zz)
2659 double v[2];
2661 if(zz_avail(zz)!=16) return;
2662 v[0] = dbuf_getfloat64x(c->infile, zz->pos, d->is_le);
2663 zz->pos += 8;
2664 v[1] = dbuf_getfloat64x(c->infile, zz->pos, d->is_le);
2665 zz->pos += 8;
2666 de_dbg(c, "reference point: %f, %f", v[0], v[1]);
2669 static void do_lsct_block(deark *c, lctx *d, zztype *zz)
2671 i64 x;
2672 struct de_fourcc tmp4cc;
2674 if(zz_avail(zz)<4) return;
2675 x = psd_getu32zz(zz);
2676 de_dbg(c, "section divider setting type: %d", (int)x);
2678 zz->pos += 4; // skip '8BIM' signature
2680 if(zz_avail(zz)<4) return;
2681 psd_read_fourcc_zz(c, d, zz, &tmp4cc);
2682 de_dbg(c, "blend mode key: '%s'", tmp4cc.id_dbgstr);
2684 if(zz_avail(zz)<4) return;
2685 x = psd_getu32zz(zz);
2686 de_dbg(c, "sub type: %d", (int)x);
2689 static void do_lspf_block(deark *c, lctx *d, zztype *zz)
2691 unsigned int x;
2692 if(zz_avail(zz)!=4) return;
2693 x = (unsigned int)psd_getu32zz(zz);
2694 de_dbg(c, "protection flags: transparency=%u, composite=%u, position=%u",
2695 (x&0x1), (x&0x2)>>1, (x&0x4)>>2);
2698 static void do_vmsk_block(deark *c, lctx *d, zztype *zz)
2700 i64 ver;
2701 i64 flags;
2702 zztype czz;
2704 ver = psd_getu32zz(zz);
2705 if(ver!=3) return;
2706 flags = psd_getu32zz(zz);
2707 de_dbg(c, "flags: 0x%08x", (unsigned int)flags);
2709 de_dbg(c, "path components at %d", (int)zz->pos);
2710 de_dbg_indent(c, 1);
2711 zz_init(&czz, zz);
2712 do_pathinfo(c, d, &czz);
2713 de_dbg_indent(c, -1);
2716 static void do_vscg_block(deark *c, lctx *d, zztype *zz)
2718 struct de_fourcc key4cc;
2720 psd_read_fourcc_zz(c, d, zz, &key4cc);
2721 de_dbg(c, "key: '%s'", key4cc.id_dbgstr);
2722 read_descriptor(c, d, zz, 1, " (for Vector Stroke Content Data)");
2725 static void do_vogk_block(deark *c, lctx *d, zztype *zz)
2727 i64 ver;
2729 ver = psd_getu32zz(zz);
2730 if(ver!=1) return;
2731 read_descriptor(c, d, zz, 1, " (for Vector Origination Data)");
2734 static void do_unicodestring_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc,
2735 const char *name)
2737 de_ucstring *s = NULL;
2739 s = ucstring_create(c);
2740 read_unicode_string(c, d, s, zz);
2741 de_dbg(c, "%s: \"%s\"", name, ucstring_getpsz(s));
2742 ucstring_destroy(s);
2745 static void do_descriptor_block(deark *c, lctx *d, zztype *zz,
2746 const struct de_fourcc *blk4cc, const char *name)
2748 char dscrname[100];
2750 if(name[0])
2751 de_snprintf(dscrname, sizeof(dscrname), " (for %s)", name);
2752 else
2753 de_strlcpy(dscrname, "", sizeof(dscrname));
2755 read_descriptor(c, d, zz, 1, dscrname);
2758 static void do_lfx2_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2760 i64 oe_ver;
2761 zztype czz;
2763 if(zz_avail(zz)<8) return;
2764 oe_ver = psd_getu32zz(zz);
2765 de_dbg(c, "object effects version: %d", (int)oe_ver);
2766 if(oe_ver!=0) return;
2768 zz_init(&czz, zz);
2769 do_descriptor_block(c, d, &czz, blk4cc, "object-based effects layer info");
2772 // Handles 'TySh' and 'tySh'
2773 static void do_TySh_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2775 i64 ver, textver;
2777 ver = psd_getu16zz(zz);
2778 de_dbg(c, "version: %d", (int)ver);
2779 if(ver!=1) goto done;
2781 zz->pos += 6*8; // transform
2783 textver = psd_getu16zz(zz);
2784 de_dbg(c, "text version: %d", (int)textver);
2785 // For 'tySh', textver should be 6 -- TODO
2786 // For 'TySh', textver should be 50
2787 if(textver!=50) goto done;
2789 if(!read_descriptor(c, d, zz, 1, " (for type tool object setting - text)")) {
2790 goto done;
2793 zz->pos += 2; // warp version
2794 if(!read_descriptor(c, d, zz, 1, " (for type tool object setting - warp)")) {
2795 goto done;
2798 // TODO: "left, top, right, bottom" (field purpose and data type are undocumented)
2799 zz->pos += 4*8;
2801 done:
2805 static void do_SoLd_block(deark *c, lctx *d, zztype *zz)
2807 struct de_fourcc id4cc;
2808 i64 ver;
2810 psd_read_fourcc_zz(c, d, zz, &id4cc);
2811 de_dbg(c, "identifier: '%s'", id4cc.id_dbgstr);
2812 ver = psd_getu32zz(zz);
2813 de_dbg(c, "version: %d", (int)ver);
2815 read_descriptor(c, d, zz, 1, " (of placed layer information)");
2818 static void do_filter_effect_channel(deark *c, lctx *d, zztype *zz)
2820 i64 dlen;
2821 i64 saved_pos;
2822 i64 cmpr_mode;
2824 zz->pos += 4; // Skip array-is-written flag (already processed)
2826 dlen = psd_geti64zz(zz);
2827 de_dbg(c, "length: %"I64_FMT"", dlen);
2828 saved_pos = zz->pos;
2829 if(dlen<=0) goto done;
2831 cmpr_mode = psd_getu16zz(zz);
2832 dbg_print_compression_method(c, d, cmpr_mode);
2834 de_dbg(c, "[%d bytes at %d]", (int)(saved_pos + dlen - zz->pos), (int)zz->pos);
2835 zz->pos = saved_pos + dlen;
2836 done:
2840 static void do_filter_effect(deark *c, lctx *d, zztype *zz)
2842 i64 ver2;
2843 i64 dlen2;
2844 de_ucstring *s = NULL;
2845 i64 x;
2846 i64 ch;
2847 i64 max_channels;
2848 u8 b;
2849 zztype czz;
2850 int saved_indent_level;
2851 i64 filter_effects_savedpos;
2853 de_dbg_indent_save(c, &saved_indent_level);
2855 s = ucstring_create(c);
2857 ucstring_empty(s);
2858 read_pascal_string_to_ucstring(c, d, s, zz);
2859 de_dbg(c, "identifier: \"%s\"", ucstring_getpsz(s));
2861 // Note the clear similarites to the "virtual memory array lists" used in
2862 // Pattern data. But it is not the same. Maybe some of the code should be
2863 // consolidated.
2865 ver2 = psd_getu32zz(zz);
2866 de_dbg(c, "version: %d", (int)ver2);
2867 if(ver2 != 1) goto done;
2869 dlen2 = psd_geti64zz(zz);
2870 de_dbg(c, "length: %"I64_FMT"", dlen2);
2871 filter_effects_savedpos = zz->pos;
2873 read_rectangle_tlbr(c, d, zz, "rectangle");
2875 x = psd_getu32zz(zz);
2876 de_dbg(c, "depth: %d", (int)x);
2878 max_channels = psd_getu32zz(zz);
2879 de_dbg(c, "max channels: %d", (int)max_channels);
2881 for(ch=0; ch<max_channels+2; ch++) {
2882 i64 is_written;
2884 if(zz->pos >= zz->endpos) goto done;
2886 // Look ahead at the array-is-written flag.
2887 is_written = psd_getu32(zz->pos);
2889 de_dbg(c, "channel[%d] at %d%s", (int)ch, (int)zz->pos,
2890 is_written?"":" (empty)");
2892 if(is_written) {
2893 zz_init(&czz, zz);
2894 de_dbg_indent(c, 1);
2895 do_filter_effect_channel(c, d, &czz);
2896 de_dbg_indent(c, -1);
2897 zz->pos += zz_used(&czz);
2899 else {
2900 zz->pos += 4;
2904 if(zz->pos < (filter_effects_savedpos + dlen2)) {
2905 de_dbg(c, "[%d unknown bytes at %d]", (int)(filter_effects_savedpos + dlen2 - zz->pos),
2906 (int)zz->pos);
2909 zz->pos = filter_effects_savedpos + dlen2;
2911 b = psd_getbytezz(zz);
2912 de_dbg(c, "next-items-present: %d", (int)b);
2914 if(b) {
2915 x = psd_getu16zz(zz);
2916 dbg_print_compression_method(c, d, x);
2919 de_dbg(c, "[%d bytes at %d]", (int)zz_avail(zz), (int)zz->pos);
2920 zz->pos = zz->endpos;
2922 done:
2923 ucstring_destroy(s);
2924 de_dbg_indent_restore(c, saved_indent_level);
2927 static void do_FXid_block(deark *c, lctx *d, zztype *zz, const struct de_fourcc *blk4cc)
2929 i64 ver1;
2930 i64 dlen1;
2931 i64 idx;
2932 i64 main_endpos;
2933 zztype czz;
2935 ver1 = psd_getu32zz(zz);
2936 de_dbg(c, "version: %d", (int)ver1);
2937 if(ver1<1 || ver1>3) goto done;
2939 // TODO: I suspect that this next "length" field is actually part of each
2940 // individual filter effect, contrary to what the documentation says.
2941 // That way, there can be multiple "filter effects" in the same block.
2942 // Sample files needed.
2944 dlen1 = psd_geti64zz(zz);
2945 de_dbg(c, "length: %"I64_FMT"", dlen1);
2946 main_endpos = zz->pos + dlen1;
2948 idx = 0;
2951 de_dbg(c, "filter effect[%d] at %d", (int)idx, (int)zz->pos);
2952 zz_init_with_len(&czz, zz, main_endpos-zz->pos);
2953 de_dbg_indent(c, 1);
2954 do_filter_effect(c, d, &czz);
2955 de_dbg_indent(c, -1);
2956 zz->pos += zz_used(&czz);
2957 idx++;
2960 if(zz->pos < main_endpos) {
2961 de_dbg(c, "[%d bytes of data at %d]", (int)(main_endpos-zz->pos), (int)zz->pos);
2964 zz->pos = main_endpos;
2965 done:
2969 static void do_shmd_block(deark *c, lctx *d, zztype *zz)
2971 i64 count;
2972 i64 i;
2973 zztype czz;
2975 if(zz_avail(zz)<4) return;
2977 count = psd_getu32zz(zz);
2978 de_dbg(c, "number of metadata items: %d", (int)count);
2980 for(i=0; i<count; i++) {
2981 i64 itempos, dpos, dlen;
2982 struct de_fourcc key4cc;
2984 if(zz->pos >= zz->endpos) break;
2985 itempos = zz->pos;
2987 zz->pos += 4; // signature ("8BIM", presumably)
2989 psd_read_fourcc_zz(c, d, zz, &key4cc);
2991 zz->pos += 1; // flag
2992 zz->pos += 3; // padding
2994 dlen = psd_getu32zz(zz);
2996 dpos = zz->pos;
2997 de_dbg(c, "metadata item[%d] '%s' at %d, dpos=%d, dlen=%d",
2998 (int)i, key4cc.id_dbgstr, (int)itempos, (int)dpos, (int)dlen);
3000 de_dbg_indent(c, 1);
3002 switch(key4cc.id) {
3003 case CODE_cust: // Undocumented, but seems to be a versioned Descriptor
3004 case CODE_mlst: // Undocumented, but seems to be a versioned Descriptor
3005 zz_init_with_len(&czz, zz, dlen);
3006 read_descriptor(c, d, &czz, 1, "");
3007 break;
3010 de_dbg_indent(c, -1);
3012 zz->pos += dlen;
3016 static int do_tagged_block(deark *c, lctx *d, zztype *zz, int tbnamespace)
3018 i64 blklen;
3019 i64 blklen_len = 4; // Length of the block length field
3020 struct de_fourcc blk4cc;
3021 u32 sig;
3022 zztype czz;
3024 if(zz_avail(zz)<12) return 0;
3026 sig = (u32)psd_getu32zz(zz);
3027 if(sig!=CODE_8BIM && sig!=CODE_8B64) {
3028 de_warn(c, "Expected tagged block signature not found at %d", (int)zz->pos);
3029 return 0;
3032 psd_read_fourcc_zz(c, d, zz, &blk4cc);
3034 // Some blocks types have an 8-byte length in PSD format
3035 if(d->intsize_4or8==8) {
3036 switch(blk4cc.id) {
3037 case CODE_LMsk: case CODE_Lr16: case CODE_Lr32: case CODE_Layr:
3038 case CODE_Mt16: case CODE_Mt32: case CODE_Mtrn: case CODE_Alph:
3039 case CODE_FMsk: case CODE_lnk2: case CODE_FEid: case CODE_FXid:
3040 case CODE_PxSD:
3041 blklen_len = 8;
3045 if(blklen_len==8) {
3046 blklen = psd_geti64zz(zz);
3048 else {
3049 blklen = psd_getu32zz(zz);
3052 zz_init_with_len(&czz, zz, blklen);
3054 de_dbg(c, "tagged block '%s' at %d, dpos=%d, dlen=%d", blk4cc.id_dbgstr,
3055 (int)zz->startpos, (int)czz.startpos, (int)blklen);
3057 de_dbg_indent(c, 1);
3058 switch(blk4cc.id) {
3059 case CODE_clbl:
3060 do_boolean_block(c, d, &czz, &blk4cc, "blend clipped elements");
3061 break;
3062 case CODE_infx:
3063 do_boolean_block(c, d, &czz, &blk4cc, "blend interior elements");
3064 break;
3065 case CODE_knko:
3066 do_boolean_block(c, d, &czz, &blk4cc, "knockout");
3067 break;
3068 case CODE_lyid:
3069 do_uint32_block(c, d, &czz, &blk4cc, "layer ID");
3070 break;
3071 case CODE_lnsr:
3072 do_fourcc_block(c, d, &czz, &blk4cc, "layer name ID");
3073 break;
3074 case CODE_Layr:
3075 case CODE_Lr16:
3076 do_Layr_block(c, d, &czz, &blk4cc);
3077 break;
3078 case CODE_lnkD:
3079 case CODE_lnk2:
3080 case CODE_lnk3:
3081 do_lnk2_block(c, d, &czz, &blk4cc);
3082 break;
3083 case CODE_Patt:
3084 case CODE_Pat2:
3085 case CODE_Pat3:
3086 do_Patt_block(c, d, &czz, &blk4cc);
3087 break;
3088 case CODE_lrFX:
3089 do_lrFX_block(c, d, &czz, &blk4cc);
3090 break;
3091 case CODE_luni:
3092 do_unicodestring_block(c, d, &czz, &blk4cc, "Unicode layer name");
3093 break;
3094 case CODE_GdFl:
3095 do_descriptor_block(c, d, &czz, &blk4cc, "Gradient fill setting");
3096 break;
3097 case CODE_PtFl:
3098 do_descriptor_block(c, d, &czz, &blk4cc, "Pattern fill setting");
3099 break;
3100 case CODE_SoCo:
3101 do_descriptor_block(c, d, &czz, &blk4cc, "Solid color sheet setting");
3102 break;
3103 case CODE_vstk:
3104 do_descriptor_block(c, d, &czz, &blk4cc, "Vector Stroke Data");
3105 break;
3106 case CODE_blwh:
3107 do_descriptor_block(c, d, &czz, &blk4cc, "Black and White");
3108 break;
3109 case CODE_CgEd:
3110 do_descriptor_block(c, d, &czz, &blk4cc, "Content Generator Extra Data");
3111 break;
3112 case CODE_vibA:
3113 do_descriptor_block(c, d, &czz, &blk4cc, "Vibrance");
3114 break;
3115 case CODE_pths:
3116 do_descriptor_block(c, d, &czz, &blk4cc, "Unicode Path Name");
3117 break;
3118 case CODE_anFX:
3119 do_descriptor_block(c, d, &czz, &blk4cc, "Animation Effects");
3120 break;
3121 case CODE_PxSc:
3122 do_descriptor_block(c, d, &czz, &blk4cc, "Pixel Source Data");
3123 break;
3124 case CODE_artb:
3125 case CODE_artd:
3126 case CODE_abdd:
3127 do_descriptor_block(c, d, &czz, &blk4cc, "Artboard Data");
3128 break;
3129 case CODE_vmsk:
3130 case CODE_vsms:
3131 do_vmsk_block(c, d, &czz);
3132 break;
3133 case CODE_vscg:
3134 do_vscg_block(c, d, &czz);
3135 break;
3136 case CODE_vogk:
3137 do_vogk_block(c, d, &czz);
3138 break;
3139 case CODE_fxrp:
3140 do_fxrp_block(c, d, &czz);
3141 break;
3142 case CODE_lsct:
3143 do_lsct_block(c, d, &czz);
3144 break;
3145 case CODE_lspf:
3146 do_lspf_block(c, d, &czz);
3147 break;
3148 case CODE_lfx2:
3149 do_lfx2_block(c, d, &czz, &blk4cc);
3150 break;
3151 case CODE_Txt2:
3152 do_text_engine_data(c, d, czz.startpos, blklen);
3153 break;
3154 case CODE_TySh:
3155 case CODE_tySh:
3156 do_TySh_block(c, d, &czz, &blk4cc);
3157 break;
3158 case CODE_SoLd:
3159 do_SoLd_block(c, d, &czz);
3160 break;
3161 case CODE_FEid:
3162 case CODE_FXid:
3163 do_FXid_block(c, d, &czz, &blk4cc);
3164 break;
3165 case CODE_shmd:
3166 do_shmd_block(c, d, &czz);
3167 break;
3168 case CODE_AnDs: // Observed in Plug-in Resources/'mani'/'IRFR'
3169 if(tbnamespace==1) {
3170 do_descriptor_block(c, d, &czz, &blk4cc, "");
3172 break;
3173 case CODE_desc:
3174 if(tbnamespace==2) { // Observed in ABR (brush) files
3175 do_descriptor_block(c, d, &czz, &blk4cc, "");
3177 break;
3178 case CODE_patt:
3179 if(tbnamespace==2) {
3180 do_Patt_block(c, d, &czz, &blk4cc);
3182 break;
3183 case CODE_samp:
3184 if(tbnamespace==2) {
3185 do_samp_block(c, d, &czz);
3187 break;
3188 default:
3189 if(blklen>0) {
3190 if(c->debug_level>=2) {
3191 de_dbg_hexdump(c, c->infile, czz.startpos, blklen, 256, NULL, 0x1);
3193 else {
3194 de_dbg(c, "[%d bytes of tagged block data at %d]", (int)blklen, (int)czz.startpos);
3198 de_dbg_indent(c, -1);
3200 // Apparently, the data is padded to the next multiple of 4 bytes.
3201 // (This is not what the PSD spec says.)
3202 zz->pos += de_pad_to_4(blklen);
3203 return 1;
3206 // A "Series of tagged blocks" - part of the "Layer and Mask Information" section.
3207 // Or, the payload data from a TIFF "ImageSourceData" tag.
3208 // Or, at the end of a "layer record".
3209 static void do_tagged_blocks(deark *c, lctx *d, zztype *zz, int tbnamespace)
3211 zztype czz;
3213 d->nesting_level++;
3214 if(d->nesting_level>MAX_NESTING_LEVEL) goto done; // Defend against excessive recursion.
3216 if(d->tagged_blocks_only && d->nesting_level==1) {
3217 // If we're reading *only* this data structure (e.g. from a TIFF file), the
3218 // byte order may be of interest.
3219 de_dbg(c, "byte order: %s-endian", d->is_le?"little":"big");
3222 while(1) {
3223 if(zz->pos+12 > zz->endpos) break;
3224 zz_init(&czz, zz);
3225 if(!do_tagged_block(c, d, &czz, tbnamespace)) break;
3226 zz->pos += zz_used(&czz);
3229 done:
3230 d->nesting_level--;
3233 static int do_layer_and_mask_info_section(deark *c, lctx *d, zztype *zz)
3235 i64 layer_and_mask_info_section_len; // The "Length" field. Whole section is 4 bytes longer.
3236 i64 gl_layer_mask_info_len;
3237 zztype lmidataczz;
3238 zztype czz;
3239 int saved_indent_level;
3240 int retval = 0;
3242 de_dbg_indent_save(c, &saved_indent_level);
3244 // The "layer and mask section" contains up to 3 sub-sections:
3245 // 1. layer info
3246 // 2. global layer mask info
3247 // 3. tagged blocks
3249 de_dbg(c, "layer & mask info section at %d", (int)zz->pos);
3250 de_dbg_indent(c, 1);
3252 layer_and_mask_info_section_len = psd_getu32or64zz(c, d, zz);
3253 de_dbg(c, "layer & mask info section total data len: %d", (int)layer_and_mask_info_section_len);
3254 if(zz->pos + layer_and_mask_info_section_len > zz->endpos) {
3255 de_err(c, "Unexpected end of PSD file");
3256 goto done;
3258 zz_init_with_len(&lmidataczz, zz, layer_and_mask_info_section_len);
3260 // We won't use zz again (we'll use lmidataczz instead), so we can go ahead and
3261 // advance its ->pos field.
3262 zz->pos += layer_and_mask_info_section_len;
3263 // Now that we know the size of this element, we can treat this function as "successful".
3264 retval = 1;
3266 ///// 1. layer info /////
3268 zz_init(&czz, &lmidataczz);
3269 if(!do_layer_info_section(c, d, &lmidataczz, 1)) {
3270 goto done;
3272 if(czz.endpos > lmidataczz.endpos) {
3273 de_warn(c, "Oversized Layer Info section");
3274 goto done;
3276 lmidataczz.pos += zz_used(&czz);
3278 /////
3280 if(lmidataczz.pos >= lmidataczz.endpos) {
3281 goto done;
3284 ///// 2. global layer mask info /////
3286 de_dbg(c, "global layer mask info at %d", (int)lmidataczz.pos);
3287 de_dbg_indent(c, 1);
3288 gl_layer_mask_info_len = psd_getu32zz(&lmidataczz);
3289 de_dbg(c, "length of global layer mask info section: %"I64_FMT, gl_layer_mask_info_len);
3290 de_dbg_indent(c, -1);
3291 if(lmidataczz.pos+gl_layer_mask_info_len > lmidataczz.endpos) {
3292 de_warn(c, "Oversized Global Layer Mask Info section");
3293 goto done;
3295 lmidataczz.pos += gl_layer_mask_info_len;
3297 /////
3299 if(lmidataczz.pos >= lmidataczz.endpos) {
3300 goto done;
3303 ///// 3. tagged blocks /////
3305 de_dbg(c, "tagged blocks at %d", (int)lmidataczz.pos);
3306 de_dbg_indent(c, 1);
3307 de_dbg(c, "expected length of tagged blocks section: %d", (int)(lmidataczz.endpos-lmidataczz.pos));
3308 zz_init(&czz, &lmidataczz);
3309 do_tagged_blocks(c, d, &czz, 0);
3310 de_dbg_indent(c, -1);
3312 done:
3313 de_dbg_indent_restore(c, saved_indent_level);
3314 return retval;
3317 static int do_action_item(deark *c, lctx *d, zztype *zz)
3319 struct de_fourcc id4cc;
3320 de_ucstring *s = NULL;
3321 i64 dscr_flag;
3322 int retval = 0;
3324 zz->pos += 1; // action-is-expanded
3325 zz->pos += 1; // action-is-enabled
3326 zz->pos += 1; // dialogs-should-be-displayed
3327 zz->pos += 1; // options for displaying dialogs
3329 s = ucstring_create(c);
3331 psd_read_fourcc_zz(c, d, zz, &id4cc);
3332 de_dbg(c, "identifier type: '%s'", id4cc.id_dbgstr);
3333 if(id4cc.id==CODE_TEXT) {
3334 read_prefixed_string_to_ucstring(c, d, s, zz);
3335 de_dbg(c, "id: \"%s\"", ucstring_getpsz_d(s));
3337 else if(id4cc.id==CODE_long) {
3338 i64 id_long;
3339 id_long = psd_getu32zz(zz);
3340 de_dbg(c, "itemID: %d", (int)id_long);
3342 else {
3343 de_err(c, "Unsupported identifier type: '%s'", id4cc.id_sanitized_sz);
3344 goto done;
3347 ucstring_empty(s);
3348 read_prefixed_string_to_ucstring(c, d, s, zz);
3349 de_dbg(c, "dictionary name: \"%s\"", ucstring_getpsz_d(s));
3351 dscr_flag = psd_geti32zz(zz);
3352 de_dbg(c, "descriptor flag: %d", (int)dscr_flag);
3354 if(dscr_flag == -1) {
3355 if(!read_descriptor(c, d, zz, 0, "")) goto done;
3357 else if(dscr_flag==0) {
3360 else {
3361 de_err(c, "Unsupported descriptor flag: %d", (int)dscr_flag);
3362 goto done;
3365 retval = 1;
3367 done:
3368 ucstring_destroy(s);
3369 return retval;
3372 static int do_one_action(deark *c, lctx *d, zztype *zz)
3374 i64 action_pos;
3375 i64 idx;
3376 i64 num_items;
3377 i64 item_idx;
3378 de_ucstring *s = NULL;
3379 zztype czz;
3380 int saved_indent_level;
3381 int retval = 0;
3383 de_dbg_indent_save(c, &saved_indent_level);
3384 action_pos = zz->pos;
3385 idx = psd_getu16zz(zz);
3386 de_dbg(c, "index: %d", (int)idx);
3388 zz->pos += 1; // shift key flag
3389 zz->pos += 1; // command key flag
3390 zz->pos += 2; // color index info
3392 s = ucstring_create(c);
3393 read_unicode_string(c, d, s, zz);
3394 de_dbg(c, "action name: \"%s\"", ucstring_getpsz_d(s));
3396 zz->pos += 1; // action-is-expanded
3398 num_items = psd_getu32zz(zz);
3399 de_dbg(c, "number of items: %d", (int)num_items);
3401 for(item_idx=0; item_idx<num_items; item_idx++) {
3402 if(zz_avail(zz)<1) goto done;
3403 zz_init(&czz, zz);
3404 de_dbg(c, "item[%d] at %d (for action @%d)", (int)item_idx, (int)zz->pos, (int)action_pos);
3405 de_dbg_indent(c, 1);
3406 if(!do_action_item(c, d, &czz)) goto done;
3407 zz->pos += zz_used(&czz);
3408 de_dbg_indent(c, -1);
3411 retval = 1;
3413 done:
3414 de_dbg_indent_restore(c, saved_indent_level);
3415 ucstring_destroy(s);
3416 return retval;
3419 static void do_action_set(deark *c, lctx *d, zztype *zz)
3421 i64 ver;
3422 i64 num_actions;
3423 i64 action_idx;
3424 de_ucstring *s = NULL;
3425 zztype czz;
3426 int saved_indent_level;
3427 u8 b;
3429 de_dbg_indent_save(c, &saved_indent_level);
3430 ver = psd_getu32zz(zz);
3431 de_dbg(c, "version: %d", (int)ver);
3432 if(ver!=16) {
3433 de_err(c, "Unsupported Action format version: %d", (int)ver);
3434 goto done;
3437 s = ucstring_create(c);
3438 read_unicode_string(c, d, s, zz);
3439 de_dbg(c, "action set name: \"%s\"", ucstring_getpsz_d(s));
3441 b = psd_getbytezz(zz);
3442 de_dbg(c, "set-is-expanded: %d", (int)b);
3444 num_actions = psd_getu32zz(zz);
3445 de_dbg(c, "number of actions: %d", (int)num_actions);
3447 for(action_idx=0; action_idx<num_actions; action_idx++) {
3448 if(zz_avail(zz)<1) goto done;
3449 zz_init(&czz, zz);
3450 de_dbg(c, "action[%d] at %d", (int)action_idx, (int)zz->pos);
3451 de_dbg_indent(c, 1);
3452 if(!do_one_action(c, d, &czz)) goto done;
3453 zz->pos += zz_used(&czz);
3454 de_dbg_indent(c, -1);
3457 done:
3458 de_dbg_indent_restore(c, saved_indent_level);
3459 ucstring_destroy(s);
3462 // Call this after setting d->version.
3463 static void init_version_specific_info(deark *c, lctx *d)
3465 if(d->version==2) { // PSB format
3466 d->intsize_2or4 = 4;
3467 d->intsize_4or8 = 8;
3469 else { // Regular PSD format
3470 d->intsize_2or4 = 2;
3471 d->intsize_4or8 = 4;
3474 // The PSD spec does not say what encoding these strings use.
3475 // Some sources say they use MacRoman, and *some* PSD files do use MacRoman.
3476 // But other PSD files use other encodings, and I don't know how to know what
3477 // encoding they use.
3478 d->input_encoding = de_get_input_encoding(c, NULL, DE_ENCODING_MACROMAN);
3480 d->jpeg_rbswap_mode = 1;
3483 static int do_psd_header(deark *c, lctx *d, i64 pos)
3485 int retval = 0;
3487 de_dbg(c, "header at %d", (int)pos);
3488 de_dbg_indent(c, 1);
3489 d->version = (int)psd_getu16(pos+4);
3490 de_dbg(c, "PSD version: %d", d->version);
3491 init_version_specific_info(c, d);
3493 if(d->version==1) {
3494 de_declare_fmt(c, "PSD");
3496 else if(d->version==2) {
3497 de_declare_fmt(c, "PSB");
3499 else {
3500 de_err(c, "Unsupported PSD version: %d", (int)d->version);
3501 goto done;
3504 d->main_iinfo->num_channels = psd_getu16(pos+12);
3505 de_dbg(c, "number of channels: %d", (int)d->main_iinfo->num_channels);
3507 d->main_iinfo->height = psd_getu32(pos+14);
3508 d->main_iinfo->width = psd_getu32(pos+18);
3509 de_dbg_dimensions(c, d->main_iinfo->width, d->main_iinfo->height);
3511 d->main_iinfo->bits_per_channel = psd_getu16(pos+22);
3512 de_dbg(c, "bits/channel: %d", (int)d->main_iinfo->bits_per_channel);
3514 d->main_iinfo->color_mode = psd_getu16(pos+24);
3515 de_dbg(c, "color mode: %d (%s)", (int)d->main_iinfo->color_mode,
3516 get_colormode_name(d->main_iinfo->color_mode));
3518 retval = 1;
3520 done:
3521 de_dbg_indent(c, -1);
3522 return retval;
3525 static void do_external_tagged_blocks(deark *c, lctx *d, zztype *zz)
3527 u32 code;
3529 d->tagged_blocks_only = 1;
3530 if(zz_avail(zz)<4) return;
3532 // Evidently, it is possible for this to use little-endian byte order. Weird.
3534 // Peek at the first 4 bytes
3535 code = (u32)de_getu32le(0);
3536 if(code==CODE_8BIM || code==CODE_8B64) {
3537 d->is_le = 1;
3540 do_tagged_blocks(c, d, zz, 0);
3543 static void do_psd_color_mode_data(deark *c, lctx *d, zztype *zz)
3545 i64 len;
3546 i64 k;
3547 u8 r, g, b;
3548 struct image_info *iinfo = d->main_iinfo;
3550 len = zz_avail(zz);
3551 de_dbg(c, "color data at %d, len=%d", (int)zz->pos, (int)len);
3552 iinfo->pal_entries = len/3;
3553 if(iinfo->pal_entries<1) return;
3554 if(iinfo->pal_entries>256) iinfo->pal_entries=256;
3556 de_dbg_indent(c, 1);
3557 for(k=0; k<iinfo->pal_entries; k++) {
3558 r = de_getbyte(zz->pos + k);
3559 g = de_getbyte(zz->pos + iinfo->pal_entries + k);
3560 b = de_getbyte(zz->pos + 2*iinfo->pal_entries + k);
3561 iinfo->pal[k] = DE_MAKE_RGB(r, g, b);
3562 de_dbg_pal_entry(c, k, iinfo->pal[k]);
3564 de_dbg_indent(c, -1);
3567 static u8 scale_float_to_255(double x)
3569 if(x<=0.0) return 0;
3570 if(x>=1.0) return 255;
3571 return (u8)(0.5+x*255.0);
3574 // Extract the primary image
3575 static void do_bitmap(deark *c, lctx *d, const struct image_info *iinfo, dbuf *f,
3576 i64 pos, i64 len)
3578 de_bitmap *img = NULL;
3579 de_finfo *fi = NULL;
3580 i64 i, j, plane;
3581 i64 nplanes = 0; // Number of planes to read. May be less than d->num_channels.
3582 i64 planespan, rowspan, samplespan;
3583 u8 b;
3585 if(!de_good_image_dimensions(c, iinfo->width, iinfo->height)) goto done;
3587 if(iinfo->color_mode==PSD_CM_BITMAP && iinfo->bits_per_channel==1 &&
3588 iinfo->num_channels==1)
3590 de_convert_and_write_image_bilevel2(f, 0, iinfo->width, iinfo->height,
3591 (iinfo->width+7)/8, DE_CVTF_WHITEISZERO, NULL, 0);
3592 goto done;
3595 if(iinfo->bits_per_channel!=8 && iinfo->bits_per_channel!=16 &&
3596 iinfo->bits_per_channel!=32)
3598 de_err(c, "Unsupported bits/channel: %d", (int)iinfo->bits_per_channel);
3599 goto done;
3602 if(iinfo->color_mode==PSD_CM_GRAY && iinfo->num_channels>=1) {
3603 nplanes = 1;
3605 else if(iinfo->color_mode==PSD_CM_PALETTE && iinfo->num_channels>=1 && iinfo->bits_per_channel==8) {
3606 nplanes = 1;
3608 else if(iinfo->color_mode==PSD_CM_RGB && iinfo->num_channels>=3) {
3609 nplanes = 3;
3611 else {
3612 de_err(c, "This type of image is not supported (color=%d, "
3613 "num channels=%d, bits/channel=%d)",
3614 (int)iinfo->color_mode, (int)iinfo->num_channels, (int)iinfo->bits_per_channel);
3615 goto done;
3618 img = de_bitmap_create(c, iinfo->width, iinfo->height,
3619 iinfo->color_mode==PSD_CM_GRAY ? 1 : 3);
3621 fi = de_finfo_create(c);
3623 if(iinfo->density.code!=DE_DENSITY_UNKNOWN) {
3624 fi->density = iinfo->density;
3627 samplespan = iinfo->bits_per_channel/8;
3628 rowspan = iinfo->width * samplespan;
3629 planespan = iinfo->height * rowspan;
3631 for(plane=0; plane<nplanes; plane++) {
3632 for(j=0; j<iinfo->height; j++) {
3633 for(i=0; i<iinfo->width; i++) {
3634 if(iinfo->bits_per_channel==32) {
3635 // TODO: The format of 32-bit samples does not seem to be documented.
3636 // This is little more than a guess.
3637 double tmpd;
3638 tmpd = dbuf_getfloat32x(f, pos + plane*planespan + j*rowspan + i*samplespan, d->is_le);
3639 b = scale_float_to_255(tmpd);
3641 else {
3642 b = dbuf_getbyte(f, pos + plane*planespan + j*rowspan + i*samplespan);
3644 if(iinfo->color_mode==PSD_CM_RGB) {
3645 de_bitmap_setsample(img, i, j, plane, b);
3647 else if(iinfo->color_mode==PSD_CM_GRAY) {
3648 de_bitmap_setpixel_gray(img, i, j, b);
3650 else if(iinfo->color_mode==PSD_CM_PALETTE) {
3651 de_bitmap_setpixel_rgb(img, i, j, iinfo->pal[(unsigned int)b]);
3657 de_bitmap_write_to_file_finfo(img, fi, 0);
3658 done:
3659 de_bitmap_destroy(img);
3660 de_finfo_destroy(c, fi);
3663 static void do_bitmap_packbits(deark *c, lctx *d, zztype *zz, const struct image_info *iinfo)
3665 dbuf *unc_pixels = NULL;
3666 i64 cmpr_data_size = 0;
3667 i64 k;
3669 // Data begins with a table of row byte counts.
3670 de_dbg(c, "row sizes table at %"I64_FMT", len=%d", zz->pos,
3671 (int)(iinfo->num_channels * iinfo->height * d->intsize_2or4));
3673 for(k=0; k < iinfo->num_channels * iinfo->height; k++) {
3674 if(d->intsize_2or4==4) {
3675 cmpr_data_size += psd_getu32zz(zz);
3677 else {
3678 cmpr_data_size += psd_getu16zz(zz);
3682 de_dbg(c, "compressed data at %"I64_FMT", len=%"I64_FMT"", zz->pos, cmpr_data_size);
3683 if(zz->pos + cmpr_data_size>c->infile->len) {
3684 de_err(c, "Unexpected end of file");
3685 goto done;
3688 unc_pixels = dbuf_create_membuf(c, 1024, 0);
3689 fmtutil_decompress_packbits(c->infile, zz->pos, cmpr_data_size, unc_pixels, NULL);
3690 zz->pos += cmpr_data_size;
3691 de_dbg_indent(c, 1);
3692 de_dbg(c, "decompressed %"I64_FMT" bytes to %"I64_FMT"", cmpr_data_size, unc_pixels->len);
3693 de_dbg_indent(c, -1);
3694 do_bitmap(c, d, iinfo, unc_pixels, 0, unc_pixels->len);
3696 done:
3697 dbuf_close(unc_pixels);
3700 static void do_image_data(deark *c, lctx *d, zztype *zz)
3702 i64 cmpr;
3703 i64 len;
3704 i64 image_data_size;
3705 zztype czz;
3707 len = zz_avail(zz);
3708 if(len<2) return;
3709 de_dbg(c, "image data section at %d, expected len=%d", (int)zz->pos, (int)len);
3710 de_dbg_indent(c, 1);
3711 cmpr = psd_getu16zz(zz);
3712 dbg_print_compression_method(c, d, cmpr);
3714 image_data_size = zz_avail(zz);
3716 if(c->extract_policy == DE_EXTRACTPOLICY_AUXONLY) goto done;
3718 // Copy the global density info (from Resources section, presumably) to the image info
3719 d->main_iinfo->density = d->density;
3721 if(cmpr==0) { // Uncompressed
3722 do_bitmap(c, d, d->main_iinfo, c->infile, zz->pos, image_data_size);
3724 else if(cmpr==1) { // PackBits
3725 zz_init(&czz, zz);
3726 do_bitmap_packbits(c, d, &czz, d->main_iinfo);
3727 zz->pos += zz_used(&czz);
3729 else {
3730 de_err(c, "Compression method not supported: %d", (int)cmpr);
3733 done:
3734 de_dbg_indent(c, -1);
3737 static void de_run_psd(deark *c, de_module_params *mparams)
3739 lctx *d = NULL;
3740 i64 x;
3741 zztype *zz = NULL;
3742 zztype czz;
3743 int whattodo = 0;
3745 d = de_malloc(c, sizeof(lctx));
3746 zz = de_malloc(c, sizeof(zztype));
3747 zz_init_absolute(zz, 0, c->infile->len);
3749 if(de_havemodcode(c, mparams, 'R')) {
3750 whattodo = 'R';
3752 else if(de_havemodcode(c, mparams, 'T')) {
3753 whattodo = 'T';
3755 else if(de_havemodcode(c, mparams, 'B')) {
3756 whattodo = 'B';
3758 else if(!dbuf_memcmp(c->infile, 0, "8BIM", 4)) {
3759 // Assume this is a raw resources file (maybe extracted from an
3760 // .8bimtiff file)
3761 whattodo = 'R';
3764 if(whattodo=='R') { // Image resources
3765 de_declare_fmt(c, "Photoshop resources");
3766 d->version = 1;
3767 init_version_specific_info(c, d);
3768 do_image_resource_blocks(c, d, zz);
3769 if(mparams) {
3770 // .out_params.flags: 0x02: has_iptc
3771 mparams->out_params.flags = 0;
3772 if(d->has_iptc) mparams->out_params.flags |= 0x02;
3774 goto done;
3776 else if(whattodo=='T') { // Tagged blocks
3777 d->version = 1;
3778 init_version_specific_info(c, d);
3779 do_external_tagged_blocks(c, d, zz);
3780 goto done;
3782 else if(whattodo=='B') { // Tagged blocks, PSB-format
3783 d->version = 2;
3784 init_version_specific_info(c, d);
3785 do_external_tagged_blocks(c, d, zz);
3786 goto done;
3789 d->main_iinfo = de_malloc(c, sizeof(struct image_info));
3791 if(!do_psd_header(c, d, zz->pos)) goto done;
3792 zz->pos += 26;
3794 de_dbg(c, "color mode data section at %d", (int)zz->pos);
3795 de_dbg_indent(c, 1);
3796 x = psd_getu32zz(zz);
3797 zz_init_with_len(&czz, zz, x);
3798 do_psd_color_mode_data(c, d, &czz);
3799 zz->pos += x;
3800 de_dbg_indent(c, -1);
3802 de_dbg(c, "image resources section at %d", (int)zz->pos);
3803 de_dbg_indent(c, 1);
3804 x = psd_getu32zz(zz); // Length of Image Resources
3805 // The PSD spec is ambiguous, but in practice the "length" field's value
3806 // does not include the size of the "length" field itself.
3807 de_dbg(c, "image resources data at %d, len=%d", (int)zz->pos, (int)x);
3809 if(x>0) {
3810 if(de_get_ext_option_bool(c, "extract8bim", 0)) {
3811 fmtutil_handle_photoshop_rsrc(c, c->infile, zz->pos, x, 0x1);
3813 else {
3814 de_dbg_indent(c, 1);
3815 zz_init_with_len(&czz, zz, x);
3816 do_image_resource_blocks(c, d, &czz);
3817 de_dbg_indent(c, -1);
3820 zz->pos += x;
3821 de_dbg_indent(c, -1);
3823 zz_init(&czz, zz);
3824 if(!do_layer_and_mask_info_section(c, d, &czz)) goto done;
3825 zz->pos += zz_used(&czz);
3827 zz_init(&czz, zz);
3828 do_image_data(c, d, &czz);
3830 done:
3831 de_free(c, zz);
3832 if(d) {
3833 de_free(c, d->main_iinfo);
3834 de_free(c, d);
3838 static void de_run_ps_action(deark *c, de_module_params *mparams)
3840 lctx *d = NULL;
3841 zztype *zz = NULL;
3843 de_declare_fmt(c, "Photoshop Action");
3845 d = de_malloc(c, sizeof(lctx));
3846 d->version = 1;
3847 init_version_specific_info(c, d);
3849 zz = de_malloc(c, sizeof(zztype));
3850 zz_init_absolute(zz, 0, c->infile->len);
3852 do_action_set(c, d, zz);
3854 de_free(c, zz);
3855 de_free(c, d);
3858 static void de_run_ps_gradient(deark *c, de_module_params *mparams)
3860 lctx *d = NULL;
3861 zztype *zz = NULL;
3862 i64 grd_ver;
3864 de_declare_fmt(c, "Photoshop Gradient");
3866 d = de_malloc(c, sizeof(lctx));
3867 d->version = 1;
3868 init_version_specific_info(c, d);
3870 zz = de_malloc(c, sizeof(zztype));
3871 zz_init_absolute(zz, 0, c->infile->len);
3873 zz->pos += 4; // 8BGR signature
3874 grd_ver = psd_getu16zz(zz);
3875 de_dbg(c, "file version: %d", (int)grd_ver);
3877 if(grd_ver==5) {
3878 read_descriptor(c, d, zz, 1, "");
3880 else {
3881 de_err(c, "Unsupported Photoshop Gradient file version: %d", (int)grd_ver);
3884 de_free(c, zz);
3885 de_free(c, d);
3888 // .asl format, "Patterns" object
3889 static void do_asl_patterns(deark *c, lctx *d, zztype *zz)
3891 i64 pat_ver;
3892 i64 patseq_len;
3893 zztype czz_patseq;
3895 de_dbg(c, "patterns at %d", (int)zz->pos);
3896 de_dbg_indent(c, 1);
3897 pat_ver = psd_getu16zz(zz);
3898 de_dbg(c, "patterns version: %d", (int)pat_ver);
3899 patseq_len = psd_getu32zz(zz);
3900 de_dbg(c, "patterns total length: %d", (int)patseq_len);
3902 // Sequence of patterns
3903 zz_init_with_len(&czz_patseq, zz, patseq_len);
3905 do_pattern_sequence(c, d, &czz_patseq);
3907 zz->pos += patseq_len;
3909 de_dbg_indent(c, -1);
3912 // .asl format, "Styles" object
3913 static void do_asl_patterns_and_styles(deark *c, lctx *d, zztype *zz)
3915 zztype czz;
3916 i64 num_styles;
3917 i64 style_idx;
3918 i64 style_len;
3920 zz->pos += 4; // 8BSL signature
3922 zz_init(&czz, zz);
3923 do_asl_patterns(c, d, &czz);
3924 zz->pos += zz_used(&czz);
3926 de_dbg(c, "styles at %d", (int)zz->pos);
3927 de_dbg_indent(c, 1);
3929 num_styles = psd_getu32zz(zz);
3930 de_dbg(c, "number of styles: %d", (int)num_styles);
3932 for(style_idx=0; style_idx<=num_styles; style_idx++) {
3933 if(zz_avail(zz)<4) break;
3935 de_dbg(c, "style[%d] at %d", (int)style_idx, (int)zz->pos);
3936 de_dbg_indent(c, 1);
3938 style_len = psd_getu32zz(zz);
3939 de_dbg(c, "style length: %d", (int)style_len);
3941 zz_init_with_len(&czz, zz, style_len);
3942 read_descriptor(c, d, &czz, 1, " (for style identification)");
3943 read_descriptor(c, d, &czz, 1, " (for style information)");
3945 zz->pos += style_len;
3946 de_dbg_indent(c, -1);
3949 de_dbg_indent(c, -1);
3952 static void de_run_ps_styles(deark *c, de_module_params *mparams)
3954 lctx *d = NULL;
3955 zztype *zz = NULL;
3956 i64 asl_ver;
3958 de_declare_fmt(c, "Photoshop Styles");
3960 d = de_malloc(c, sizeof(lctx));
3961 d->version = 1;
3962 init_version_specific_info(c, d);
3964 zz = de_malloc(c, sizeof(zztype));
3965 zz_init_absolute(zz, 0, c->infile->len);
3967 asl_ver = psd_getu16zz(zz);
3968 de_dbg(c, "file version: %d", (int)asl_ver);
3969 if(asl_ver!=2) {
3970 de_err(c, "Unsupported Photoshop Styles file version: %d", (int)asl_ver);
3971 goto done;
3974 do_asl_patterns_and_styles(c, d, zz);
3976 done:
3977 de_free(c, zz);
3978 de_free(c, d);
3981 static void do_abr_v1(deark *c, lctx *d, zztype *zz)
3983 i64 num_brushes;
3984 i64 i;
3986 zz->pos += 2;
3987 num_brushes = psd_getu16zz(zz);
3988 de_dbg(c, "number of brushes: %d", (int)num_brushes);
3990 for(i=0; i<num_brushes; i++) {
3991 i64 brushtype;
3992 i64 bdeflen;
3994 if(zz->pos >= zz->endpos) break;
3996 de_dbg(c, "brush definition[%d] at %d", (int)i, (int)zz->pos);
3997 de_dbg_indent(c, 1);
3999 brushtype = psd_getu16zz(zz);
4000 de_dbg(c, "brush type: %d", (int)brushtype);
4001 bdeflen = psd_getu32zz(zz);
4002 de_dbg(c, "brush definition data dpos=%d, dlen=%d", (int)zz->pos, (int)bdeflen);
4004 zz->pos += bdeflen;
4006 de_dbg_indent(c, -1);
4011 static void do_abr_v6(deark *c, lctx *d, zztype *zz)
4013 u32 sig;
4014 zztype czz;
4016 zz->pos += 4; // Version numbers(?), already read
4017 sig = (u32)psd_getu32(zz->pos);
4018 if(sig!=CODE_8BIM) {
4019 de_err(c, "Bad signature or unsupported Brush format");
4020 goto done;
4023 zz_init(&czz, zz);
4024 do_tagged_blocks(c, d, &czz, 2);
4026 done:
4030 static void de_run_ps_brush(deark *c, de_module_params *mparams)
4032 lctx *d = NULL;
4033 zztype *zz = NULL;
4034 int has_8bim_sig;
4036 d = de_malloc(c, sizeof(lctx));
4037 d->version = 1;
4038 init_version_specific_info(c, d);
4040 zz = de_malloc(c, sizeof(zztype));
4041 zz_init_absolute(zz, 0, c->infile->len);
4043 d->abr_major_ver = (int)psd_getu16(0);
4044 de_dbg(c, "file version: %d", (int)d->abr_major_ver);
4046 has_8bim_sig = (psd_getu32(4) == CODE_8BIM);
4048 if(has_8bim_sig && d->abr_major_ver>=3) {
4049 d->abr_minor_ver = (int)psd_getu16(2);
4050 de_declare_fmt(c, "Photoshop Brush (new format)");
4051 do_abr_v6(c, d, zz);
4053 else if(d->abr_major_ver<=5) {
4054 de_declare_fmt(c, "Photoshop Brush (old format)");
4055 do_abr_v1(c, d, zz);
4057 else {
4058 de_err(c, "Unsupported Photoshop Brush format (version=%d)", (int)d->abr_major_ver);
4059 goto done;
4062 done:
4063 de_free(c, zz);
4064 de_free(c, d);
4067 static void do_custom_shape(deark *c, lctx *d, zztype *zz)
4069 de_ucstring *s = NULL;
4070 i64 dlen;
4071 i64 saved_pos;
4072 zztype datazz;
4073 zztype pathinfozz;
4075 s = ucstring_create(c);
4076 saved_pos = zz->pos;
4077 read_unicode_string(c, d, s, zz);
4078 de_dbg(c, "name: \"%s\"", ucstring_getpsz_d(s));
4079 // This Unicode String is padded to a multiple of 4 bytes, unlike pretty much
4080 // every other Unicode String in every Photoshop format.
4081 zz->pos = saved_pos + de_pad_to_4(zz->pos - saved_pos);
4083 zz->pos += 4; // Unknown field
4085 dlen = psd_getu32zz(zz);
4086 de_dbg(c, "shape data length: %d", (int)dlen);
4088 zz_init_with_len(&datazz, zz, dlen);
4089 // We expect this length to be a multiple of 4. I don't know what to do if
4090 // it's not.
4091 zz->pos += dlen;
4093 ucstring_empty(s);
4094 read_pascal_string_to_ucstring(c, d, s, &datazz);
4095 de_dbg(c, "id: \"%s\"", ucstring_getpsz(s));
4097 read_rectangle_tlbr(c, d, &datazz, "bounds");
4099 de_dbg(c, "path records at %d", (int)datazz.pos);
4100 zz_init(&pathinfozz, &datazz);
4101 de_dbg_indent(c, 1);
4102 do_pathinfo(c, d, &pathinfozz);
4103 de_dbg_indent(c, -1);
4105 ucstring_destroy(s);
4108 static void de_run_ps_csh(deark *c, de_module_params *mparams)
4110 lctx *d = NULL;
4111 zztype *zz = NULL;
4112 i64 csh_ver;
4113 i64 num_shapes;
4114 i64 i;
4115 zztype czz;
4117 d = de_malloc(c, sizeof(lctx));
4118 d->version = 1;
4119 init_version_specific_info(c, d);
4121 zz = de_malloc(c, sizeof(zztype));
4122 zz_init_absolute(zz, 0, c->infile->len);
4124 zz->pos += 4; // Skip over 'cush' signature
4126 csh_ver = psd_getu32zz(zz);
4127 de_dbg(c, "file version: %d", (int)csh_ver);
4129 if(csh_ver!=2) {
4130 de_warn(c, "CSH v%d format might not be supported correctly", (int)csh_ver);
4133 num_shapes = psd_getu32zz(zz);
4134 de_dbg(c, "number of shapes: %d", (int)num_shapes);
4136 for(i=0; i<num_shapes; i++) {
4137 if(zz_avail(zz)<28) break;
4138 de_dbg(c, "shape[%d] at %d", (int)i, (int)zz->pos);
4139 zz_init(&czz, zz);
4140 de_dbg_indent(c, 1);
4141 do_custom_shape(c, d, &czz);
4142 de_dbg_indent(c, -1);
4143 zz->pos += zz_used(&czz);
4146 de_free(c, zz);
4147 de_free(c, d);
4150 static void de_run_ps_pattern(deark *c, de_module_params *mparams)
4152 lctx *d = NULL;
4153 zztype *zz = NULL;
4154 i64 pat_ver;
4155 i64 num_patterns;
4156 i64 i;
4157 zztype czz;
4159 d = de_malloc(c, sizeof(lctx));
4160 d->version = 1;
4161 init_version_specific_info(c, d);
4163 zz = de_malloc(c, sizeof(zztype));
4164 zz_init_absolute(zz, 0, c->infile->len);
4166 zz->pos += 4; // Skip over '8BPT' signature
4168 pat_ver = psd_getu16zz(zz);
4169 de_dbg(c, "file version: %d", (int)pat_ver);
4171 if(pat_ver!=1) {
4172 de_warn(c, "PAT v%d format might not be supported correctly", (int)pat_ver);
4175 num_patterns = psd_getu32zz(zz);
4176 de_dbg(c, "number of patterns: %d", (int)num_patterns);
4178 for(i=0; i<num_patterns; i++) {
4179 if(zz_avail(zz)<4) break;
4180 de_dbg(c, "pattern[%d] at %d", (int)i, (int)zz->pos);
4181 zz_init(&czz, zz);
4182 de_dbg_indent(c, 1);
4183 if(!do_pattern_internal(c, d, &czz)) break;
4184 de_dbg_indent(c, -1);
4185 zz->pos += zz_used(&czz);
4188 de_free(c, zz);
4189 de_free(c, d);
4192 static int de_identify_psd(deark *c)
4194 u8 buf[4];
4196 de_read(buf, 0, 4);
4197 if(!de_memcmp(buf, "8BPS", 4)) return 100;
4198 if(!de_memcmp(buf, "8BIM", 4)) {
4199 // We sometimes write .8bim files, so we want to identify them.
4200 // This is not necessarily a standard file format.
4201 if(de_input_file_has_ext(c, "8bim")) return 100;
4202 return 75;
4204 return 0;
4207 void de_module_psd(deark *c, struct deark_module_info *mi)
4209 mi->id = "psd";
4210 mi->desc = "Photoshop PSD";
4211 mi->run_fn = de_run_psd;
4212 mi->identify_fn = de_identify_psd;
4215 static int de_identify_ps_action(deark *c)
4217 int ver=0;
4219 if(!dbuf_memcmp(c->infile, 0, "\x00\x00\x00\x10\x00\x00", 6)) {
4220 ver = 16;
4222 else if(!dbuf_memcmp(c->infile, 0, "\x00\x00\x00\x0c", 4)) {
4223 ver = 12;
4225 if(ver==0) return 0;
4226 if(!de_input_file_has_ext(c, "atn")) return 0;
4227 if(ver==16) return 100;
4228 return 5; // A version we don't support
4231 void de_module_ps_action(deark *c, struct deark_module_info *mi)
4233 mi->id = "ps_action";
4234 mi->desc = "Photoshop Action";
4235 mi->run_fn = de_run_ps_action;
4236 mi->identify_fn = de_identify_ps_action;
4239 static int de_identify_ps_gradient(deark *c)
4241 if(!dbuf_memcmp(c->infile, 0, "8BGR", 4)) {
4242 if(de_input_file_has_ext(c, "grd")) return 100;
4243 return 90;
4245 return 0;
4248 void de_module_ps_gradient(deark *c, struct deark_module_info *mi)
4250 mi->id = "ps_gradient";
4251 mi->desc = "Photoshop Gradient";
4252 mi->run_fn = de_run_ps_gradient;
4253 mi->identify_fn = de_identify_ps_gradient;
4256 static int de_identify_ps_styles(deark *c)
4258 if(!dbuf_memcmp(c->infile, 2, "8BSL", 4)) {
4259 if(de_input_file_has_ext(c, "asl")) return 100;
4260 return 90;
4262 return 0;
4265 void de_module_ps_styles(deark *c, struct deark_module_info *mi)
4267 mi->id = "ps_styles";
4268 mi->desc = "Photoshop Styles";
4269 mi->run_fn = de_run_ps_styles;
4270 mi->identify_fn = de_identify_ps_styles;
4273 static int de_identify_ps_brush(deark *c)
4275 i64 ver;
4277 ver = de_getu16be(0);
4278 if(ver==1 || ver==2 || ver==6 || ver==7) {
4279 if(de_input_file_has_ext(c, "abr")) return 80;
4281 return 0;
4284 void de_module_ps_brush(deark *c, struct deark_module_info *mi)
4286 mi->id = "ps_brush";
4287 mi->desc = "Photoshop Brush";
4288 mi->run_fn = de_run_ps_brush;
4289 mi->identify_fn = de_identify_ps_brush;
4292 static int de_identify_ps_csh(deark *c)
4294 if(!dbuf_memcmp(c->infile, 0, "cush", 4)) {
4295 if(de_input_file_has_ext(c, "csh")) return 100;
4296 return 80;
4298 return 0;
4301 void de_module_ps_csh(deark *c, struct deark_module_info *mi)
4303 mi->id = "ps_csh";
4304 mi->desc = "Photoshop Custom Shape";
4305 mi->run_fn = de_run_ps_csh;
4306 mi->identify_fn = de_identify_ps_csh;
4309 static int de_identify_ps_pattern(deark *c)
4311 if(!dbuf_memcmp(c->infile, 0, "8BPT", 4)) {
4312 if(de_input_file_has_ext(c, "pat")) return 100;
4313 return 90;
4315 return 0;
4318 void de_module_ps_pattern(deark *c, struct deark_module_info *mi)
4320 mi->id = "ps_pattern";
4321 mi->desc = "Photoshop Pattern";
4322 mi->run_fn = de_run_ps_pattern;
4323 mi->identify_fn = de_identify_ps_pattern;