/////////////////////////////////////////////////////////////
// CINEMA SDK : RENDERING        													 //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D																	 //
/////////////////////////////////////////////////////////////
// (c) 1989-2002 MAXON Computer GmbH, all rights reserved	 //
/////////////////////////////////////////////////////////////
// video post example file - invert image
// simple video post effect 
// - usage of VPBuffer
// - operates after the image is completly rendered
/////////////////////////////////////////////////////////////

#include "c4d.h"
#include "c4d_symbols.h"

class InvertData : public VideoPostData
{
	public:
		static NodeData *Alloc(void) { return gNew InvertData; }
		virtual LONG Execute(PluginVideoPost *node, VideoPostStruct *vps);
		virtual LONG GetRenderInfo(PluginVideoPost *node) { return VIDEOPOST_REFRESH; }
};

LONG InvertData::Execute(PluginVideoPost *node, VideoPostStruct *vps)
{
	if (vps->vp==VP_RENDER && !vps->open && *vps->error==RAY_OK && !vps->thread->TestBreak())
	{
		VPBuffer *rgba    = C4DOS.Sh->VPGetBuffer(vps->render,VPBUFFER_RGBA,NOTOK);
		RayParameter *ray = vps->vd->GetRayParameter(); // only in VP_INNER & VP_RENDER
		if (!ray)  return RAY_NOMEM;
		if (!rgba) return RAY_NOMEM;

		LONG x1,y1,x2,y2,x,y,cnt,i;

		// example functions
		LONG depth = rgba->GetInfo(VPGETINFO_BITDEPTH);
		LONG cpp   = rgba->GetInfo(VPGETINFO_CPP);

		x1 = ray->left;
		y1 = ray->top;
		x2 = ray->right;
		y2 = ray->bottom;
		cnt = x2-x1+1;

		SReal *b,*buffer = (SReal*)GeAlloc(cpp*cnt*sizeof(SReal));
		if (!buffer) return RAY_NOMEM;

		for (y=y1;y<=y2;y++)
		{
			rgba->GetLine(x1,y,cnt,buffer,32,TRUE);

			for (b=buffer,x=x1;x<=x2;x++,b+=cpp)
			{
				for (i=0;i<3;i++)
					b[i] = 1.0-b[i];
			}

			rgba->SetLine(x1,y,cnt,buffer,32,TRUE);
		}
		GeFree(buffer);
	}
		
	return RAY_OK;	
}

// be sure to use a unique ID obtained from www.plugincafe.com
#define ID_INVERTVIDEOPOST 1000455

Bool RegisterVPInvertImage(void)
{
	// decide by name if the plugin shall be registered - just for user convenience
	String name=GeLoadString(IDS_VPINVERTIMAGE); if (!name.Content()) return TRUE;
	return RegisterVideoPostPlugin(ID_INVERTVIDEOPOST,name,0,InvertData::Alloc,"",0,0);
}
