// PSD_SHARED.C
// Copyright © 2000 Joe Riedel, All Rights Reserved.
// Author: Joe Riedel.
#include "psd_shared.h"
#include <stdlib.h>
#include <string.h>

void FreePSDImage(PSDImage_t* PSD)
{
	int i;
	PSDImageLayer_t* layer;

	for(i = 0; i < PSD->NumLayers; i++)
	{
		layer = &PSD->Layers[i];
		
		if(layer->Alpha)
			free(layer->Alpha);
		if(layer->Mask)
			free(layer->Mask);
		if(layer->RGB)
			free(layer->RGB);
	}

	if(PSD->Layers)
		free(PSD->Layers);
	PSD->Layers = 0;
	PSD->NumLayers = 0;
}

Image_t* ImageNew(int w, int h, int bytes_pp)
{
	Image_t* image = (Image_t*)malloc(sizeof(Image_t));
	if(image == 0)
		return 0;
	memset(image, 0, sizeof(Image_t));
	
	if(w == 0 || h == 0)
		return 0;

	image->x = image->y = 0;
	image->width = w;
	image->height = h;
	image->flags = 0;

	image->data = (unsigned char*)malloc(bytes_pp*w*h);
	if(!image->data)
	{
		free(image);
		return 0;
	}

	return image;
}

void FreeImageData(Image_t* image)
{
	if(image->data == 0)
		return;
	free(image->data);
}

void FreeImageStruct(Image_t* image)
{
	FreeImageData(image);
	free(image);
}

Image_t* PSDMakeImageFromLayer(PSDImageLayer_t* Layer, int flags)
{
	Image_t* image=0;

	switch(flags)
	{
	case PSD_FLAG_RGB:
		if(!Layer->RGB)
			return 0;
		// just get rgb.
		image = ImageNew(Layer->Width, Layer->Height, 3);
		if(!image)
			return 0;
		image->x = Layer->Left; image->y = Layer->Top;
		memcpy(image->data, Layer->RGB, Layer->Width*Layer->Height*3);
		break;
	case PSD_FLAG_ALPHA:
		if(!Layer->Alpha)
			return 0;
		// just get alpha.
		image = ImageNew(Layer->Width, Layer->Height, 1);
		if(!image)
			return 0;
		image->x = Layer->Left; image->y = Layer->Top;
		memcpy(image->data, Layer->Alpha, Layer->Width*Layer->Height);
		break;
	case PSD_FLAG_MASK:
		if(!Layer->Mask)
			return 0;
		image = ImageNew(Layer->MaskWidth, Layer->MaskHeight, 1);
		if(!image)
			return 0;
		image->x = Layer->MaskLeft; image->y = Layer->MaskTop;
		memcpy(image->data, Layer->Mask, Layer->MaskWidth*Layer->MaskHeight);
		break;
	case PSD_FLAG_RGBA:
		{
			int i, numbytes;
			unsigned char* rgb, *alpha, *data;
			
			if(!Layer->RGB || !Layer->Alpha)
				return 0;
				
			image = ImageNew(Layer->Width, Layer->Height, 4);
			if(!image)
				return 0;
			image->x = Layer->Left; image->y = Layer->Top;
			numbytes = Layer->Width*Layer->Height*4;

			rgb = Layer->RGB;
			alpha = Layer->Alpha;
			data = image->data;

			for(i = 0; i < numbytes; i+=4)
			{
				*data++ = *rgb++;
				*data++ = *rgb++;
				*data++ = *rgb++;
				*data++ = *alpha++;
			}
		}
	}

	if(image)
		image->flags = flags;

	return image;
}

void FreePSDLayerInfoSectionBlock(PSDLayerInfoSection_t* LayerSection)
{
#if 1
	int i, k;
	PSDLayerRecord_t* LayerRecord;

	for(i = 0; i < LayerSection->NumLayers; i++)
	{
		LayerRecord = &LayerSection->LayerRecordsPtr[i];

		// Free all channel data.
		for(k = 0; k < LayerRecord->NumChannels; k++)
		{
			if(LayerRecord->ChannelImageData == 0)
				continue;

			if(LayerRecord->ChannelImageData[k].Data)
				free(LayerRecord->ChannelImageData[k].Data);
		}

		if(LayerRecord->ChannelImageData)
			free(LayerRecord->ChannelImageData);
		if(LayerRecord->ChannelLengthInfoPtr)
			free(LayerRecord->ChannelLengthInfoPtr);
		if(LayerRecord->LayerBlendingRanges.ChannelBlendRanges)
			free(LayerRecord->LayerBlendingRanges.ChannelBlendRanges);
		if(LayerRecord->Name)
			free(LayerRecord->Name);
	}

	free(LayerSection->LayerRecordsPtr);
	memset(LayerSection,0,sizeof(PSDLayerInfoSection_t));
#endif
}