/*
**
** PSD_SHARED.H
** Copyright © Joe Riedel, All Rights Reserved.
** Author: Joe Riedel.
**
** FILE DESCRIPTION:
**
** Shared defs for photoshop reader/writer.
**
*/ 
#ifndef __PSD_SHARED_H__
#define __PSD_SHARED_H__


// All this was taken straight from the psd docs.
// Note: this reader does not read the image resources block.

#define PSD_MODE_BITMAP			0
#define PSD_MODE_GRAYSCALE		1
#define PSD_MODE_INDEXED		2
#define PSD_MODE_RGB			3
#define PSD_MODE_CMYK			4
#define PSD_MODE_MULTICHANNEL	7
#define PSD_MODE_DUOTONE		8
#define PSD_MODE_LAB			9

#define PSD_HEADER_SIG			'8BPS'//('8'+('B'<<8)+('P'<<16)+('S'<<24))

typedef struct PSDHeader_t
{
	int			Signature;	// Should be '8BPS'
	short		Version;	// Should be 1.
	char		Reserved1[6];
	short		NumChannels;
	int			Width;
	int			Height;
	short		BitsPerChannel;
	short		Mode;

} PSDHeader_t;

typedef struct PSDColorMode_t
{
	int			Length;
	unsigned char*		ColorModeDataPtr;
} PSDColorMode_t;

// layer stuff.

typedef struct PSDChannelLengthInfo_t
{
	short		ChannelID;
	int			Length;
} PSDChannelLengthInfo_t;

typedef struct PSDLayerMaskData_t
{
	int			Length;
	int			Top, Left, Bottom, Right;
	char		DefaultColor;
	char		Flags;
	char		Padd[2];

} PSDLayerMaskData_t;

typedef struct PSDLayerChannelBlendRange_t
{
	int		 Src;
	int		 Dst;
} PSDLayerChannelBlendRange_t;

typedef struct PSDLayerBlendingRanges_t
{
	int		Length;
	PSDLayerChannelBlendRange_t GrayBlend;
	PSDLayerChannelBlendRange_t	*ChannelBlendRanges;

} PSDLayerBlendingRanges_t;

typedef struct PSDChannelImageData_t
{
	short Compression;
	unsigned char*	Data;
} PSDChannelImageData_t;

typedef struct PSDGlobalLayerMaskInfo_t
{
	int			Length;
	short		Overlay;
	short		ColorComponents[4];
	short		Opacity;
	unsigned char	Kind;
	unsigned char	Pad;
} PSDGlobalLayerMaskInfo_t;

#define PSD_ADJUSTMENTLAYERINFO_SIG		'8BIM'

typedef struct PSDAdjustmentLayerInfo_t
{
	int		Signature;	// Shoulde be '8BIM'
	int		Key;		// We don't care.
	int		Length;		// Length of adjustment info.
} PSDAdjustmentLayerInfo_t;

typedef struct PSDLayerRecord_t
{
	int			Top, Left, Bottom, Right;
	short		NumChannels;
	PSDChannelLengthInfo_t*	ChannelLengthInfoPtr;
	int			BlendModeSig;
	int			BlendModeKey;
	unsigned char	Opacity;
	unsigned char	Clipping;
	unsigned char	Flags;
	unsigned char	Pad1;
	int	ExtraDataSize;
	PSDLayerMaskData_t LayerMaskData;
	PSDLayerBlendingRanges_t LayerBlendingRanges;
	char*		Name;
	
	// New since 4.0.
	PSDAdjustmentLayerInfo_t	AdjustmentLayerInfo;

	// Tacked our channel data here.
	PSDChannelImageData_t*	ChannelImageData;
} PSDLayerRecord_t;

typedef struct PSDLayerInfoSection_t
{
	int		Length;
	short		NumLayers;
	PSDLayerRecord_t*	LayerRecordsPtr;
	
	PSDGlobalLayerMaskInfo_t	GlobalLayerMask;

} PSDLayerInfoSection_t;

/*****************************************************************
** PUBLICLY USED STRUCTS										**
*****************************************************************/
typedef struct PSDImageLayer_t
{
	char* Name;
	int Top, Left, Bottom, Right;	// Surrounding rect.
	int MaskTop, MaskLeft, MaskBottom, MaskRight;
	int Width, Height;
	int MaskWidth, MaskHeight;
	unsigned char* RGB;
	unsigned char* Alpha;
	unsigned char* Mask;
} PSDImageLayer_t;

typedef struct PSDImage_t
{
	int Width;
	int Height;
	int NumLayers;
	PSDImageLayer_t* Layers;

} PSDImage_t;

#define PSD_OK			0

void FreePSDImage(PSDImage_t* PSD);
void FreePSDLayerInfoSectionBlock(PSDLayerInfoSection_t* LayerSection);

#define PSD_FLAG_RGB	0
#define PSD_FLAG_ALPHA	1
#define PSD_FLAG_MASK	2
#define PSD_FLAG_RGBA	3

typedef struct Image_t
{
	int x, y, width, height;
	int flags;
	unsigned char* data;
} Image_t;

Image_t* ImageNew(int w, int h, int bytes_pp);
void FreeImageData(Image_t* image);
void FreeImageStruct(Image_t* image);

Image_t* PSDMakeImageFromLayer(PSDImageLayer_t* Layer, int flags);

#define PSD_FLAGS_TO_BYTES_PP(flags) ( (flags) == PSD_FLAG_RGB ? 3 : (flags) == PSD_FLAG_ALPHA ? 1 : (flags) == PSD_FLAG_MASK ? 1 : (flags) == PSD_FLAG_RGBA ? 4 : 0 )

#endif