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