1 module psd.layer;
2 import psd.parser;
3 import asdf;
4 import std.stdio : File;
5 
6 /**
7     Photoshop blending modes
8 */
9 enum BlendingMode : string {
10     PassThrough = "pass",
11     Normal = "norm",
12     Dissolve = "diss",
13     Darken = "dark",
14     Multiply = "mul ",
15     ColorBurn = "idiv",
16     LinearBurn = "lbrn",
17     DarkerColor = "dkCl",
18     Lighten = "lite",
19     Screen = "scrn",
20     ColorDodge = "div ",
21     LinearDodge = "lddg",
22     LighterColor = "lgCl",
23     Overlay = "over",
24     SoftLight = "sLit",
25     HardLight = "hLit",
26     VividLight = "vLit",
27     LinearLight = "lLit",
28     PinLight = "pLit",
29     HardMix = "hMix",
30     Difference = "diff",
31     Exclusion = "smud",
32     Subtract = "fsub",
33     Divide = "fdiv",
34     Hue = "hue ",
35     Saturation = "sat ",
36     Color = "colr",
37     Luminosity = "lum "
38 }
39 
40 /**
41     A struct representing a layer mask as stored in the layers of the Layer Mask section.
42 */
43 struct LayerMask
44 {
45 	/**
46         Top coordinate of the rectangle that encloses the mask.
47     */
48     int top;
49 
50 	/**
51         Left coordinate of the rectangle that encloses the mask.
52     */
53     int left;
54 
55 	/**
56         Bottom coordinate of the rectangle that encloses the mask.
57     */
58     int bottom;
59 
60 	/**
61         Right coordinate of the rectangle that encloses the mask.
62     */
63     int right;
64 
65 
66 	/**
67         The offset from the start of the file where the channel's data is stored.
68     */
69     ulong fileOffset;
70 
71 
72 	/**
73         Planar data, having a size of (right-left)*(bottom-top)*bytesPerPixel.
74     */
75     ubyte[] data;
76 
77 
78 	/**
79         The mask's feather value.
80     */
81     double feather;
82 
83 	/**
84         The mask's density value.
85     */
86     ubyte density;
87 
88 	/**
89         The mask's default color regions outside the enclosing rectangle.
90     */
91     ubyte defaultColor;
92 };
93 
94 /**
95     A struct representing a vector mask as stored in the layers of the Layer Mask section.
96 */
97 struct VectorMask
98 {
99 	/**
100         Top coordinate of the rectangle that encloses the mask.
101     */
102     int top;
103 
104 	/**
105         Left coordinate of the rectangle that encloses the mask.
106     */
107     int left;
108 
109 	/**
110         Bottom coordinate of the rectangle that encloses the mask.
111     */
112     int bottom;
113 
114 	/**
115         Right coordinate of the rectangle that encloses the mask.
116     */
117     int right;
118 
119 
120 	/**
121         The offset from the start of the file where the channel's data is stored.
122     */
123     ulong fileOffset;
124 
125 
126 	/**
127         Planar data, having a size of (right-left)*(bottom-top)*bytesPerPixel.
128     */
129     ubyte[] data;
130 
131 
132 	/**
133         The mask's feather value.
134     */
135     double feather;
136 
137 	/**
138         The mask's density value.
139     */
140     ubyte density;
141 
142 	/**
143         The mask's default color regions outside the enclosing rectangle.
144     */
145     ubyte defaultColor;
146 };
147 
148 /**
149     Information about Masks
150 */
151 struct MaskData
152 {
153     /**
154         Top X coordinate of mask
155     */
156     int top;
157 
158     /**
159         Left X coordinate of mask
160     */
161     int left;
162 
163     /**
164         Bottom Y coordinate of mask
165     */
166     int bottom;
167 
168     /**
169         Right X coordinate of mask
170     */
171     int right;
172     
173     /**
174         Default color of mask
175     */
176     ubyte defaultColor;
177     
178     /**
179         If the mask is a vector mask or not
180     */
181     bool isVectorMask;
182 };
183 
184 /**
185     Type of channel.
186 */
187 enum ChannelType
188 {
189     INVALID = 32767,					///< Internal value. Used to denote that a channel no longer holds valid data.
190 
191     R = 0,								///< Type denoting the R channel, not necessarily the first in a RGB Color Mode document.
192     G = 1,								///< Type denoting the G channel, not necessarily the second in a RGB Color Mode document.
193     B = 2,								///< Type denoting the B channel, not necessarily the third in a RGB Color Mode document.
194 
195     TRANSPARENCY_MASK = -1,				///< The layer's channel data is a transparency mask.
196     LAYER_OR_VECTOR_MASK = -2,			///< The layer's channel data is either a layer or vector mask.
197     LAYER_MASK = -3						///< The layer's channel data is a layer mask.
198 }
199 
200 /**
201     Information about color channels
202 */
203 struct ChannelInfo {
204     /**
205         Type of channel
206     */
207     short type;
208 
209     /**
210         Offset into the file of the color channel
211     */
212     uint fileOffset;
213 
214     /**
215         Length of data in color channel
216     */
217     uint dataLength;
218     
219     /**
220         The data of the channel
221     */
222     @serdeIgnore
223     ubyte[] data;
224 
225     /**
226         Gets whether the channel is a mask
227     */
228     bool isMask() {
229         return type < 0;
230     }
231 }
232 
233 /**
234     The different types of layer
235 */
236 enum LayerType {
237     /**
238         Any other type of layer
239     */
240     Any = 0,
241 
242     /**
243         An open folder
244     */
245     OpenFolder = 1,
246 
247     /**
248         A closed folder
249     */
250     ClosedFolder = 2,
251 
252     /**
253         A bounding section divider
254     
255         Hidden in the UI
256     */
257     SectionDivider = 3
258 }
259 
260 /**
261     Flags for a layer
262 */
263 enum LayerFlags : ubyte {
264     TransProtect    = 0b00000001,
265     Visible         = 0b00000010,
266     Obsolete        = 0b00000100,
267     ModernDoc       = 0b00001000,
268     PixelIrrel      = 0b00010000,
269 
270     /**
271         Special mask used for getting whether a layer is a group layer
272         flags & GroupMask = 24, for a layer group.
273     */
274     GroupMask       = 0b00011000
275 }
276 
277 /**
278     A layer
279 */
280 struct Layer {
281 package(psd):
282     File filePtr;
283 
284 public:
285 
286     /**
287         Parent of layer
288     */
289     //Layer* parent;
290 
291     /**
292         Name of layer
293     */
294     string name;
295 
296     /**
297         Bounding box for layer
298     */
299     union {
300         struct {
301 
302             /**
303                 Top X coordinate of layer
304             */
305             int top;
306 
307             /**
308                 Left X coordinate of layer
309             */
310             int left;
311 
312             /**
313                 Bottom Y coordinate of layer
314             */
315             int bottom;
316 
317             /**
318                 Right X coordinate of layer
319             */
320             int right;
321         }
322 
323         /**
324             Bounds as array
325         */
326         int[4] bounds;
327     }
328 
329     /**
330         Blending mode
331     */
332     //BlendingMode blendModeKey;
333     uint blendModeKey;
334 
335     /**
336         Channels in layer
337     */
338     ChannelInfo[] channels;
339     
340     /**
341         The layer's user mask, if any.
342     */
343 	LayerMask[] layerMask;
344     
345     /**
346         The layer's vector mask, if any.
347     */
348 	VectorMask[] vectorMask;
349 
350     /**
351         Opacity of the layer
352     */
353     ubyte opacity;
354 
355     /**
356         Whether clipping is base or non-base
357     */
358     bool clipping;
359 
360     /**
361         Flags for the layer
362     */
363     @serdeProxy!uint
364     LayerFlags flags;
365 
366     /**
367         The data of the layer
368     */
369     @serdeIgnore
370     ubyte[] data;
371 
372     /**
373         The type of layer
374     */
375     LayerType type;
376 
377     /**
378         Whether the layer is visible or not
379     */
380     bool isVisible;
381 
382     /**
383         Gets the center coordinates of the layer
384     */
385     uint[2] center() {
386         return [
387             left+(width/2),
388             top+(height/2),
389         ];
390     }
391 
392     /**
393         Gets the size of this layer
394     */
395     uint[2] size() {
396         return [
397             width,
398             height
399         ];
400     }
401 
402     /**
403         Width
404     */
405     uint width() {
406         return right-left;
407     }
408 
409     /**
410         Height
411     */
412     uint height() {
413         return bottom-top;
414     }
415 
416     /**
417         Returns true if the layer is a group
418     */
419     bool isLayerGroup() {
420         return type == LayerType.OpenFolder || type == LayerType.ClosedFolder;
421     }
422 
423     /**
424         Is the layer useful?
425     */
426     bool isLayerUseful() {
427         return !isLayerGroup() && (width != 0 && height != 0);
428     }
429 
430     /**
431         Length of data
432     */
433     size_t dataLengthUncompressed() {
434         return this.area()*channels.length;
435     }
436 
437     /**
438         Gets total data count
439     */
440     size_t totalDataCount() {
441         uint length;
442         foreach(channel; channels) length += channel.dataLength;
443         return length;
444     }
445 
446     /**
447         Area of the layer
448     */
449     size_t area() {
450         return width * height;
451     }
452 
453     /**
454         Extracts the layer image
455     */
456     void extractLayerImage() {
457         extractLayer(this);
458     }
459 }
460 
461 /**
462     A layer mask section
463 */
464 struct LayerMaskSection {
465 
466     /**
467         The layers in the section
468     */
469     Layer[] layers;
470 
471     /**
472         The amount of layers in the section
473     */
474     uint layerCount = 0;
475 
476     /**
477         The colorspace of the overlay (unused)
478     */
479     ushort overlayColorSpace = 0;
480     
481     /**
482         The global opacity level (0 = transparent, 100 = opaque)
483     */
484     ushort opacity = 0;
485     
486     /**
487         The global layer kind
488     */
489     ubyte kind = 128u;
490 
491     /**
492         Whether the layer data contains a transparency mask
493     */
494     bool hasTransparencyMask = false;
495 }