#include <stdio.h>
#include "plugin.h"

VarStruct varstr[]= {
	{LABEL, "In: 1 Strip", 0.0f, 0.0f, 0.0f, ""}, 
	{INT|TOG, "Show alpha", 0.0f, 0.0f, 1.0f, "Show the alpha channel as a greyscale image"}
};

#ifdef WIN32
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI
#endif

typedef struct {
	long dummy;
	long showalpha;
} Parameters;

#ifdef __cplusplus
export "C" {
#endif

/* main routines: */
int DLLAPI plugin_seq_getversion(void);
void DLLAPI plugin_getinfo(PluginInfo *);

/* callback: */
void DLLAPI plugin_doit(Parameters*, float, float, int, int, ImBuf*, ImBuf*, ImBuf*, ImBuf*);

#ifdef __cplusplus
}
#endif

float DLLAPI cfra = 0;

int DLLAPI plugin_seq_getversion(void)
{
	return B_PLUGIN_VERSION;
}

void DLLAPI plugin_getinfo(PluginInfo *pi)
{
	memset(pi, 0, sizeof(PluginInfo));
	pi->name = "PostMul";
	pi->nvars = 2;
	pi->varstr = varstr;
	pi->cfra = &cfra;
	pi->seq_doit = (SeqDoit)plugin_doit;
}

void DLLAPI plugin_doit(Parameters *params, float fac, float facf, int x, int y, ImBuf *in1, ImBuf* in2, ImBuf* out, ImBuf *use)
{
	int i;
	unsigned int r,g,b, *pIn = in1->rect, *pOut = out->rect;
	int count = in1->x * in1->y;

	/* sanity check */
	if (!in1 || !out)
	{
		fprintf(stderr, "NULL passed to plugin!\n");
		return;
	}

	if (params->showalpha)
	{
		for (i = 0; i < count; i++, pIn++, pOut++)
		{
			unsigned int alpha = (*pIn & 0xFF000000) >> 24;
			*pOut = 0xFF000000 | (alpha << 16) | (alpha << 8) | alpha;
	}
	}
	else
	{
		for (i = 0; i < count; i++, pIn++, pOut++)
		{
			unsigned int alpha = (*pIn & 0xFF000000) >> 24;
			if (alpha > 0 && alpha < 255) /* nothing to change if 0 or 255 */
			{
				r = (*pIn & 0x000000FF);
				g = (*pIn & 0x0000FF00) >> 8;
				b = (*pIn & 0x00FF0000) >> 16;
				if (r > alpha)
				{
					fprintf(stderr, "red > alpha at %d,%d - really premul?", i % in1->x, i / in1->x);
					r = alpha;
				}
				if (g > alpha)
				{
					fprintf(stderr, "green > alpha at %d,%d - really premul?", i % in1->x, i / in1->x);
					g = alpha;
				}
				if (b > alpha)
				{
					fprintf(stderr, "blue > alpha at %d,%d - really premul?", i % in1->x, i / in1->x);
					b = alpha;
				}
				r = CEIL((r * 255.0) / alpha);
				g = CEIL((g * 255.0) / alpha);
				b = CEIL((b * 255.0) / alpha);
				/* just to be sure */
				r = MIN2(r,255);
				g = MIN2(g,255);
				b = MIN2(b,255);

				*pOut = (alpha << 24) | (b << 16) | (g << 8) | r;
			}
			else
				*pOut = *pIn;
		}
	}
}

/* Windows wants it... */
#ifdef WIN32
int __stdcall LibMain(void * hinstDLL, unsigned long fdwReason, void *lpvReserved)
{
	return 1;
}
#endif

