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