Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef PSD_INCLUDED
Toshihiro Shimizu 890ddd
#define PSD_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "psdutils.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define REF_LAYER_BY_NAME
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TRasterImageP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TNZCORE_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Photoshop's mode
Toshihiro Shimizu 890ddd
#define ModeBitmap 0
Toshihiro Shimizu 890ddd
#define ModeGrayScale 1
Toshihiro Shimizu 890ddd
#define ModeIndexedColor 2
Toshihiro Shimizu 890ddd
#define ModeRGBColor 3
Toshihiro Shimizu 890ddd
#define ModeCMYKColor 4
Toshihiro Shimizu 890ddd
#define ModeHSLColor 5
Toshihiro Shimizu 890ddd
#define ModeHSBColor 6
Toshihiro Shimizu 890ddd
#define ModeMultichannel 7
Toshihiro Shimizu 890ddd
#define ModeDuotone 8
Toshihiro Shimizu 890ddd
#define ModeLabColor 9
Toshihiro Shimizu 890ddd
#define ModeGray16 10
Toshihiro Shimizu 890ddd
#define ModeRGB48 11
Toshihiro Shimizu 890ddd
#define ModeLab48 12
Toshihiro Shimizu 890ddd
#define ModeCMYK64 13
Toshihiro Shimizu 890ddd
#define ModeDeepMultichannel 14
Toshihiro Shimizu 890ddd
#define ModeDuotone16 15
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TPSDLayerMaskInfo {
Toshihiro Shimizu 890ddd
	psdByte size;
Toshihiro Shimizu 890ddd
	long top;
Toshihiro Shimizu 890ddd
	long left;
Toshihiro Shimizu 890ddd
	long bottom;
Toshihiro Shimizu 890ddd
	long right;
Toshihiro Shimizu 890ddd
	char default_colour;
Toshihiro Shimizu 890ddd
	char flags;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	psdPixel rows, cols;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TPSDBlendModeInfo {
Toshihiro Shimizu 890ddd
	char sig[4];
Toshihiro Shimizu 890ddd
	char key[4];
Toshihiro Shimizu 890ddd
	unsigned char opacity;
Toshihiro Shimizu 890ddd
	unsigned char clipping;
Toshihiro Shimizu 890ddd
	unsigned char flags;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TPSDLayerInfo {
Toshihiro Shimizu 890ddd
	long top;
Toshihiro Shimizu 890ddd
	long left;
Toshihiro Shimizu 890ddd
	long bottom;
Toshihiro Shimizu 890ddd
	long right;
Toshihiro Shimizu 890ddd
	short channels;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPSDChannelInfo *chan;
Toshihiro Shimizu 890ddd
	int *chindex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned long layerId;
Toshihiro Shimizu 890ddd
	unsigned long protect;
Toshihiro Shimizu 890ddd
	unsigned long section;
Toshihiro Shimizu 890ddd
	unsigned long foreignEffectID;
Toshihiro Shimizu 890ddd
	unsigned long layerVersion;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int blendClipping;
Toshihiro Shimizu 890ddd
	int blendInterior;
Toshihiro Shimizu 890ddd
	int knockout;
Toshihiro Shimizu 890ddd
	int transparencyShapes;
Toshihiro Shimizu 890ddd
	int layerMaskAsGlobalMask;
Toshihiro Shimizu 890ddd
	int vectorMaskAsGlobalMask;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPSDBlendModeInfo blend;
Toshihiro Shimizu 890ddd
	TPSDLayerMaskInfo mask;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double referencePointX;
Toshihiro Shimizu 890ddd
	double referencePointY;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char *name;
Toshihiro Shimizu 890ddd
	char *nameno; // "layerNr"
Toshihiro Shimizu 890ddd
	char *unicodeName;
Toshihiro Shimizu 890ddd
	char *layerNameSource;
Toshihiro Shimizu 890ddd
	psdByte additionalpos;
Toshihiro Shimizu 890ddd
	psdByte additionallen;
Toshihiro Shimizu 890ddd
	psdByte filepos; //
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	psdByte startDataPos; // Posizione di inizio dati all'interno del file
Toshihiro Shimizu 890ddd
	psdByte dataLength;   // lunghezza dati
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// LAYER EFFECTS
Toshihiro Shimizu 890ddd
	unsigned long int *fxCommonStateVersion;
Toshihiro Shimizu 890ddd
	int fxCommonStateVisible;
Toshihiro Shimizu 890ddd
	unsigned long int fxShadowVersion;
Toshihiro Shimizu 890ddd
	float fxShadowBlur;
Toshihiro Shimizu 890ddd
	float fxShadowIntensity;
Toshihiro Shimizu 890ddd
	float fxShadowAngle;
Toshihiro Shimizu 890ddd
	float fxShadowDistance;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//my tags
Toshihiro Shimizu 890ddd
	bool isFolder;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TPSDHeaderInfo {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char sig[4];
Toshihiro Shimizu 890ddd
	short version;
Toshihiro Shimizu 890ddd
	char reserved[6];
Toshihiro Shimizu 890ddd
	short channels;
Toshihiro Shimizu 890ddd
	long rows;
Toshihiro Shimizu 890ddd
	long cols;
Toshihiro Shimizu 890ddd
	short depth;
Toshihiro Shimizu 890ddd
	short mode;
Toshihiro Shimizu 890ddd
	double vres; // image resource. Vertical resolution
Toshihiro Shimizu 890ddd
	double hres; // image resource. Horizontal resolution
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	psdByte colormodepos;
Toshihiro Shimizu 890ddd
	int layersCount;
Toshihiro Shimizu 890ddd
	int mergedalpha;
Toshihiro Shimizu 890ddd
	bool linfoBlockEmpty;
Toshihiro Shimizu 890ddd
	TPSDLayerInfo *linfo;	 // array of layer info
Toshihiro Shimizu 890ddd
	psdByte lmistart, lmilen; // set by doLayerAndMaskInfo()
Toshihiro Shimizu 890ddd
	psdByte layerDataPos;	 //set by doInfo
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct dictentry {
Toshihiro Shimizu 890ddd
	int id;
Campbell Barton 4aa85c
	const char *key, *tag, *desc;
Toshihiro Shimizu 890ddd
	void (*func)(FILE *f, struct dictentry *dict, TPSDLayerInfo *li);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// PSD LIB
Toshihiro Shimizu 890ddd
// Restituisce eccezioni
Toshihiro Shimizu 890ddd
class DVAPI TPSDReader
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFilePath m_path;
Toshihiro Shimizu 890ddd
	FILE *m_file;
Toshihiro Shimizu 890ddd
	int m_lx, m_ly;
Toshihiro Shimizu 890ddd
	TPSDHeaderInfo m_headerInfo;
Toshihiro Shimizu 890ddd
	int m_layerId;
Toshihiro Shimizu 890ddd
	int m_shrinkX;
Toshihiro Shimizu 890ddd
	int m_shrinkY;
Toshihiro Shimizu 890ddd
	TRect m_region;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TPSDReader(const TFilePath &path);
Toshihiro Shimizu 890ddd
	~TPSDReader();
Toshihiro Shimizu 890ddd
	TImageReaderP getFrameReader(TFilePath path);
Toshihiro Shimizu 890ddd
	TPSDHeaderInfo getPSDHeaderInfo();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void load(TRasterImageP &rasP, int layerId);
Toshihiro Shimizu 890ddd
	TDimension getSize() const { return TDimension(m_lx, m_ly); }
Toshihiro Shimizu 890ddd
	TPSDLayerInfo *getLayerInfo(int index);
Toshihiro Shimizu 890ddd
	int getLayerInfoIndexById(int layerId);
Toshihiro Shimizu 890ddd
	void setShrink(int shrink)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_shrinkX = shrink;
Toshihiro Shimizu 890ddd
		m_shrinkY = shrink;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void setShrink(int shrinkX, int shrinkY)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_shrinkX = shrinkX;
Toshihiro Shimizu 890ddd
		m_shrinkY = shrinkY;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void setRegion(TRect region) { m_region = region; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getShrinkX() { return m_shrinkX; }
Toshihiro Shimizu 890ddd
	int getShrinkY() { return m_shrinkY; }
Toshihiro Shimizu 890ddd
	TRect getRegion() { return m_region; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 3bfa54
	std::map<int, trect=""> m_layersSavebox;</int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool doInfo();
Toshihiro Shimizu 890ddd
	bool doHeaderInfo();
Toshihiro Shimizu 890ddd
	bool doColorModeData();
Toshihiro Shimizu 890ddd
	bool doImageResources();
Toshihiro Shimizu 890ddd
	bool doLayerAndMaskInfo();
Toshihiro Shimizu 890ddd
	bool doLayersInfo();
Toshihiro Shimizu 890ddd
	bool readLayerInfo(int index);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//void doImage(unsigned char *rasP, TPSDLayerInfo *li);
Toshihiro Shimizu 890ddd
	void doImage(TRasterP &rasP, int layerId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void readImageData(TRasterP &rasP, TPSDLayerInfo *li, TPSDChannelInfo *chan,
Toshihiro Shimizu 890ddd
					   int chancount, psdPixel rows, psdPixel cols);
Toshihiro Shimizu 890ddd
	int m_error;
Toshihiro Shimizu 890ddd
	TThread::Mutex m_mutex;
Toshihiro Shimizu 890ddd
	int openFile();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void doExtraData(TPSDLayerInfo *li, psdByte length);
Toshihiro Shimizu 890ddd
	int sigkeyblock(FILE *f, struct dictentry *dict, TPSDLayerInfo *li);
Toshihiro Shimizu 890ddd
	struct dictentry *findbykey(FILE *f, struct dictentry *parent, char *key, TPSDLayerInfo *li);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// converts psd layers structure into toonz level structure	according to path
Toshihiro Shimizu 890ddd
class DVAPI TPSDParser
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	class Level
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	public:
Shinya Kitaoka 3bfa54
		Level(std::string nm = "Unknown", int lid = 0, bool is_folder = false) : name(nm),
Toshihiro Shimizu 890ddd
																			layerId(lid),
Toshihiro Shimizu 890ddd
																			folder(is_folder)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		void addFrame(int layerId, bool isFolder = false) { framesId.push_back(Frame(layerId, isFolder)); }
Toshihiro Shimizu 890ddd
		int getFrameCount() { return (int)framesId.size(); }
Shinya Kitaoka 3bfa54
		std::string getName() { return name; }
Toshihiro Shimizu 890ddd
		int getLayerId() { return layerId; }
Shinya Kitaoka 3bfa54
		void setName(std::string nname) { name = nname; }
Toshihiro Shimizu 890ddd
		void setLayerId(int nlayerId) { layerId = nlayerId; }
Toshihiro Shimizu 890ddd
		int getFrameId(int index)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			assert(index >= 0 && index < (int)framesId.size());
Toshihiro Shimizu 890ddd
			return framesId[index].layerId;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		// return true if frame is a subfolder
Toshihiro Shimizu 890ddd
		bool isSubFolder(int frameIndex)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			assert(frameIndex >= 0 && frameIndex < (int)framesId.size());
Toshihiro Shimizu 890ddd
			return framesId[frameIndex].isFolder;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		// return true if the level is built from a psd folder
Toshihiro Shimizu 890ddd
		bool isFolder() { return folder; }
Toshihiro Shimizu 890ddd
	private:
Toshihiro Shimizu 890ddd
		struct Frame {
Toshihiro Shimizu 890ddd
			int layerId; // psd layerId
Toshihiro Shimizu 890ddd
			bool isFolder;
Toshihiro Shimizu 890ddd
			Frame(int layId, bool folder) : layerId(layId), isFolder(folder)
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
		std::string name;				 // psd name
Toshihiro Shimizu 890ddd
		int layerId;				 // psd layer id
Toshihiro Shimizu 890ddd
		std::vector framesId; // array of layer ID as frame
Toshihiro Shimizu 890ddd
		bool folder;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath m_path;
Toshihiro Shimizu 890ddd
	std::vector<level> m_levels; // layers id</level>
Toshihiro Shimizu 890ddd
	TPSDReader *m_psdreader;	 //lib
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	// path define levels construction method
Toshihiro Shimizu 890ddd
	// if path = :
Campbell Barton ea4f7e
	//  filename.psd                    flat image so LevelsCount = 1;
Campbell Barton ea4f7e
	//  filename#LAYERID.psd            each psd layer as a tlevel
Campbell Barton ea4f7e
	//  filename#LAYERID#frames.psd     each psd layer as a frame so there is only one tlevel with 1 or more frames;
Campbell Barton ea4f7e
	//  filename#LAYERID#folder.psd     each psd layer is a tlevel and
Campbell Barton ea4f7e
	//                                  each folder is a tlevel such as the psd layers
Campbell Barton ea4f7e
	//                                  contained into folder are frames of tlevel
Toshihiro Shimizu 890ddd
	// LAYERID(Integer) is psd layerId
Toshihiro Shimizu 890ddd
	TPSDParser(const TFilePath &path);
Toshihiro Shimizu 890ddd
	~TPSDParser();
Toshihiro Shimizu 890ddd
	int getLevelsCount() { return (int)m_levels.size(); }
Toshihiro Shimizu 890ddd
	// load a psd layer
Toshihiro Shimizu 890ddd
	// if layerId == 0 load flat image
Toshihiro Shimizu 890ddd
	void load(TRasterImageP &rasP, int layerId = 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Returns psd layerID
Toshihiro Shimizu 890ddd
	int getLevelId(int index)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0 && index < (int)m_levels.size());
Toshihiro Shimizu 890ddd
		return m_levels[index].getLayerId();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	bool isFolder(int levelIndex)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(levelIndex >= 0 && levelIndex < (int)m_levels.size());
Toshihiro Shimizu 890ddd
		return m_levels[levelIndex].isFolder();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int getLevelIndexById(int levelId);
Toshihiro Shimizu 890ddd
	// Returns layerID by name. Note that the layer name is not unique, so it return the first layer id found.
Shinya Kitaoka 3bfa54
	int getLevelIdByName(std::string levelName);
Toshihiro Shimizu 890ddd
	int getFrameId(int layerId, int frameIndex) { return m_levels[getLevelIndexById(layerId)].getFrameId(frameIndex); }
Toshihiro Shimizu 890ddd
	int getFramesCount(int levelId);
Toshihiro Shimizu 890ddd
	bool isSubFolder(int levelIndex, int frameIndex)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(levelIndex >= 0 && levelIndex < (int)m_levels.size());
Toshihiro Shimizu 890ddd
		return m_levels[levelIndex].isSubFolder(frameIndex);
Toshihiro Shimizu 890ddd
	}
Shinya Kitaoka 3bfa54
	std::string getLevelName(int levelId);
Toshihiro Shimizu 890ddd
	// Returns level name.
Toshihiro Shimizu 890ddd
	// If there are 2 or more level with the same name then
Toshihiro Shimizu 890ddd
	// returns levelname, levelname__2, etc
Shinya Kitaoka 3bfa54
	std::string getLevelNameWithCounter(int levelId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	void doLevels(); // do m_levels
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TIIO_PSD_H