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