1 #pragma once
2 
3 #ifndef PSD_INCLUDED
4 #define PSD_INCLUDED
5 
6 #include "psdutils.h"
7 #include "timage_io.h"
8 
9 #define REF_LAYER_BY_NAME
10 
11 class TRasterImageP;
12 
13 #undef DVAPI
14 #undef DVVAR
15 
16 #ifdef TNZCORE_EXPORTS
17 #define DVAPI DV_EXPORT_API
18 #define DVVAR DV_EXPORT_VAR
19 #else
20 #define DVAPI DV_IMPORT_API
21 #define DVVAR DV_IMPORT_VAR
22 #endif
23 
24 // Photoshop's mode
25 #define ModeBitmap 0
26 #define ModeGrayScale 1
27 #define ModeIndexedColor 2
28 #define ModeRGBColor 3
29 #define ModeCMYKColor 4
30 #define ModeHSLColor 5
31 #define ModeHSBColor 6
32 #define ModeMultichannel 7
33 #define ModeDuotone 8
34 #define ModeLabColor 9
35 #define ModeGray16 10
36 #define ModeRGB48 11
37 #define ModeLab48 12
38 #define ModeCMYK64 13
39 #define ModeDeepMultichannel 14
40 #define ModeDuotone16 15
41 
42 struct TPSDLayerMaskInfo {
43   psdByte size;
44   long top;
45   long left;
46   long bottom;
47   long right;
48   char default_colour;
49   char flags;
50 
51   psdPixel rows, cols;
52 };
53 
54 struct TPSDBlendModeInfo {
55   char sig[4];
56   char key[4];
57   unsigned char opacity;
58   unsigned char clipping;
59   unsigned char flags;
60 };
61 
62 struct TPSDLayerInfo {
63   long top;
64   long left;
65   long bottom;
66   long right;
67   short channels;
68 
69   TPSDChannelInfo *chan;
70   int *chindex;
71 
72   unsigned long layerId;
73   unsigned long protect;
74   unsigned long section;
75   unsigned long foreignEffectID;
76   unsigned long layerVersion;
77 
78   int blendClipping;
79   int blendInterior;
80   int knockout;
81   int transparencyShapes;
82   int layerMaskAsGlobalMask;
83   int vectorMaskAsGlobalMask;
84 
85   TPSDBlendModeInfo blend;
86   TPSDLayerMaskInfo mask;
87 
88   double referencePointX;
89   double referencePointY;
90 
91   char *name;
92   char *nameno;  // "layerNr"
93   char *unicodeName;
94   char *layerNameSource;
95   psdByte additionalpos;
96   psdByte additionallen;
97   psdByte filepos;  //
98 
99   psdByte startDataPos;  // Posizione di inizio dati all'interno del file
100   psdByte dataLength;    // lunghezza dati
101 
102   // LAYER EFFECTS
103   unsigned long int *fxCommonStateVersion;
104   int fxCommonStateVisible;
105   unsigned long int fxShadowVersion;
106   float fxShadowBlur;
107   float fxShadowIntensity;
108   float fxShadowAngle;
109   float fxShadowDistance;
110 
111   // my tags
112   bool isFolder;
113 };
114 
115 struct TPSDHeaderInfo {
116   char sig[4];
117   short version;
118   char reserved[6];
119   short channels;
120   long rows;
121   long cols;
122   short depth;
123   short mode;
124   double vres;  // image resource. Vertical resolution
125   double hres;  // image resource. Horizontal resolution
126 
127   psdByte colormodepos;
128   int layersCount;
129   int mergedalpha;
130   bool linfoBlockEmpty;
131   TPSDLayerInfo *linfo;      // array of layer info
132   psdByte lmistart, lmilen;  // set by doLayerAndMaskInfo()
133   psdByte layerDataPos;      // set by doInfo
134 };
135 
136 struct dictentry {
137   int id;
138   const char *key, *tag, *desc;
139   void (*func)(FILE *f, struct dictentry *dict, TPSDLayerInfo *li);
140 };
141 
142 // PSD LIB
143 // Restituisce eccezioni
144 class DVAPI TPSDReader {
145   TFilePath m_path;
146   FILE *m_file;
147   int m_lx, m_ly;
148   TPSDHeaderInfo m_headerInfo;
149   int m_layerId;
150   int m_shrinkX;
151   int m_shrinkY;
152   TRect m_region;
153 
154 public:
155   TPSDReader(const TFilePath &path);
156   ~TPSDReader();
157   TImageReaderP getFrameReader(TFilePath path);
158   TPSDHeaderInfo getPSDHeaderInfo();
159 
160   void load(TRasterImageP &rasP, int layerId);
getSize()161   TDimension getSize() const { return TDimension(m_lx, m_ly); }
162   TPSDLayerInfo *getLayerInfo(int index);
163   int getLayerInfoIndexById(int layerId);
setShrink(int shrink)164   void setShrink(int shrink) {
165     m_shrinkX = shrink;
166     m_shrinkY = shrink;
167   }
setShrink(int shrinkX,int shrinkY)168   void setShrink(int shrinkX, int shrinkY) {
169     m_shrinkX = shrinkX;
170     m_shrinkY = shrinkY;
171   }
setRegion(TRect region)172   void setRegion(TRect region) { m_region = region; }
173 
getShrinkX()174   int getShrinkX() { return m_shrinkX; }
getShrinkY()175   int getShrinkY() { return m_shrinkY; }
getRegion()176   TRect getRegion() { return m_region; }
177 
178 private:
179   std::map<int, TRect> m_layersSavebox;
180 
181   bool doInfo();
182   bool doHeaderInfo();
183   bool doColorModeData();
184   bool doImageResources();
185   bool doLayerAndMaskInfo();
186   bool doLayersInfo();
187   bool readLayerInfo(int index);
188 
189   // void doImage(unsigned char *rasP, TPSDLayerInfo *li);
190   void doImage(TRasterP &rasP, int layerId);
191 
192   void readImageData(TRasterP &rasP, TPSDLayerInfo *li, TPSDChannelInfo *chan,
193                      int chancount, psdPixel rows, psdPixel cols);
194   int m_error;
195   TThread::Mutex m_mutex;
196   int openFile();
197 
198   void doExtraData(TPSDLayerInfo *li, psdByte length);
199   int sigkeyblock(FILE *f, struct dictentry *dict, TPSDLayerInfo *li);
200   struct dictentry *findbykey(FILE *f, struct dictentry *parent, char *key,
201                               TPSDLayerInfo *li);
202 };
203 
204 // converts psd layers structure into toonz level structure	according to
205 // path
206 class DVAPI TPSDParser {
207   class Level {
208   public:
209     Level(std::string nm = "Unknown", int lid = 0, bool is_folder = false)
name(nm)210         : name(nm), layerId(lid), folder(is_folder) {}
211     void addFrame(int layerId, bool isFolder = false) {
212       framesId.push_back(Frame(layerId, isFolder));
213     }
getFrameCount()214     int getFrameCount() { return (int)framesId.size(); }
getName()215     std::string getName() { return name; }
getLayerId()216     int getLayerId() { return layerId; }
setName(std::string nname)217     void setName(std::string nname) { name = nname; }
setLayerId(int nlayerId)218     void setLayerId(int nlayerId) { layerId = nlayerId; }
getFrameId(int index)219     int getFrameId(int index) {
220       assert(index >= 0 && index < (int)framesId.size());
221       return framesId[index].layerId;
222     }
223     // return true if frame is a subfolder
isSubFolder(int frameIndex)224     bool isSubFolder(int frameIndex) {
225       assert(frameIndex >= 0 && frameIndex < (int)framesId.size());
226       return framesId[frameIndex].isFolder;
227     }
228     // return true if the level is built from a psd folder
isFolder()229     bool isFolder() { return folder; }
230 
231   private:
232     struct Frame {
233       int layerId;  // psd layerId
234       bool isFolder;
FrameFrame235       Frame(int layId, bool folder) : layerId(layId), isFolder(folder) {}
236     };
237 
238     std::string name;             // psd name
239     int layerId;                  // psd layer id
240     std::vector<Frame> framesId;  // array of layer ID as frame
241     bool folder;
242   };
243 
244   TFilePath m_path;
245   std::vector<Level> m_levels;  // layers id
246   TPSDReader *m_psdreader;      // lib
247 public:
248   // path define levels construction method
249   // if path = :
250   //  filename.psd                    flat image so LevelsCount = 1;
251   //  filename#LAYERID.psd            each psd layer as a tlevel
252   //  filename#LAYERID#frames.psd     each psd layer as a frame so there is only
253   //  one tlevel with 1 or more frames;
254   //  filename#LAYERID#folder.psd     each psd layer is a tlevel and
255   //                                  each folder is a tlevel such as the psd
256   //                                  layers
257   //                                  contained into folder are frames of tlevel
258   // LAYERID(Integer) is psd layerId
259   TPSDParser(const TFilePath &path);
260   ~TPSDParser();
getLevelsCount()261   int getLevelsCount() { return (int)m_levels.size(); }
262   // load a psd layer
263   // if layerId == 0 load flat image
264   void load(TRasterImageP &rasP, int layerId = 0);
265 
266   // Returns psd layerID
getLevelId(int index)267   int getLevelId(int index) {
268     assert(index >= 0 && index < (int)m_levels.size());
269     return m_levels[index].getLayerId();
270   }
isFolder(int levelIndex)271   bool isFolder(int levelIndex) {
272     assert(levelIndex >= 0 && levelIndex < (int)m_levels.size());
273     return m_levels[levelIndex].isFolder();
274   }
275   int getLevelIndexById(int levelId);
276   // Returns layerID by name. Note that the layer name is not unique, so it
277   // return the first layer id found.
278   int getLevelIdByName(std::string levelName);
getFrameId(int layerId,int frameIndex)279   int getFrameId(int layerId, int frameIndex) {
280     return m_levels[getLevelIndexById(layerId)].getFrameId(frameIndex);
281   }
282   int getFramesCount(int levelId);
isSubFolder(int levelIndex,int frameIndex)283   bool isSubFolder(int levelIndex, int frameIndex) {
284     assert(levelIndex >= 0 && levelIndex < (int)m_levels.size());
285     return m_levels[levelIndex].isSubFolder(frameIndex);
286   }
287   std::string getLevelName(int levelId);
288   // Returns level name.
289   // If there are 2 or more level with the same name then
290   // returns levelname, levelname__2, etc
291   std::string getLevelNameWithCounter(int levelId);
292 
293 private:
294   void doLevels();  // do m_levels
295 };
296 
297 #endif  // TIIO_PSD_H
298