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