/*
	Copyright (C) 2026 Mark Tyler

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program in the file COPYING.
*/

#include "private.h"



static void gin_render_pixmap_rgb ( GinRenderWork const * const work )
{
	if ( work->pitch == work->w * 3 )
	{
		unsigned char const * const src = work->src + work->w*work->ystart*3;
		unsigned char * const dest = work->dest + work->pitch * work->ystart;
		int const yh = work->ylim - work->ystart;

		// Fast path – can memcpy whole thing
		memcpy ( dest, src, (size_t)(yh * work->pitch));
	}
	else
	{
		// Slow path – copy row by row (rare on modern x86/64)
		for ( int y = work->ystart; y < work->ylim; y++ )
		{
			memcpy( work->dest + y * work->pitch,
				work->src + y * work->w * 3,
				(size_t)(work->w * 3)
				);
		}
	}
}

static void gin_render_pixmap_indexed ( GinRenderWork const * const work )
{
	unsigned char const * src = work->src + work->w * work->ystart;
	unsigned char * dest = work->dest + work->pitch * work->ystart;
	mtColor	const * const cols = work->cols;

	if ( work->pitch == work->w * 3 )
	{
		unsigned char * const end = work->dest + work->pitch*work->ylim;
		for ( ; dest < end; src++ )
		{
			*dest++ = cols[ *src ].red;
			*dest++ = cols[ *src ].green;
			*dest++ = cols[ *src ].blue;
		}
	}
	else
	{
		for ( int y=work->ystart; y < work->ylim; y++, src+=work->w )
		{
			dest = work->dest + y * work->pitch;

			for ( int x=0; x < work->w; x++ )
			{
				*dest++ = cols[ src[x] ].red;
				*dest++ = cols[ src[x] ].green;
				*dest++ = cols[ src[x] ].blue;
			}
		}
	}
}

void gin_render_pixmap ( GinRenderWork const * const work )
{
	switch ( work->bpp )
	{
	case 1:
		gin_render_pixmap_indexed ( work );
		break;
	case 3:
		gin_render_pixmap_rgb ( work );
		break;
	}
}

