/**********************************************************************
 
	Copyright (C) 2003-2004
	Hirohisa MORI <joshua@nichibun.ac.jp>
	Tomoki SEKIYAMA <sekiyama@yahoo.co.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/



#include <string.h>

#include "v/v_types.h"
#include "v/v_errors.h"

extern "C" {

VImage* v_image_eff_dark(VImage* img);
VImage* v_image_eff_bright(VImage* img);
VImage* v_image_eff_dark_b(VImage* img, VSize border);
VImage* v_image_eff_bright_b(VImage* img, VSize border);


static void
v_image_eff_dark_sub(VImage *dst, VImage* src, int w0, int h0, int wm, int hm)
{
	short wb = src->w_border;
	unsigned int op;
	SET_RGB8_32(op,0x7f,0x7f,0x7f,0xff);
	for ( short h = h0 ; h < hm ; h++ )
		for ( short w = w0 ; w < wm ; w++ )
			dst->buf_32[w + h*wb] = (src->buf_32[w + h*wb] >> 1) & op;
}

static void
v_image_eff_bright_sub(VImage *dst, VImage* src, int w0, int h0, int wm, int hm)
{
	int wb = src->w_border;
	unsigned int op, op2;
	SET_RGB8_32(op,0x80,0x80,0x80,0x00);
	SET_RGB8_32(op2,0x7f,0x7f,0x7f,0xff);
	for ( short h = h0 ; h < hm ; h++ )
		for ( short w = w0 ; w < wm ; w++ )
			dst->buf_32[w + h*wb] = op +
				((src->buf_32[w + h*wb] >> 1) & op2);
}


VImage*
v_image_eff_dark(VImage* img)
{
	unsigned int op;
	SET_RGB8_32(op,0x7f,0x7f,0x7f,0xff);
	VImage* ret = v_image_new(img->size.w, img->size.h, 32);
	if ( img->size.w * img->size.h ) {
		v_image_draw_start(img, 0);
		v_image_draw_start(ret, 0);
		int cnt = img->w_border * img->size.h;
		while ( --cnt )
			ret->buf_32[cnt] = (img->buf_32[cnt] >> 1) & op;
		v_image_draw_end(ret);
		v_image_draw_end(img);
	}
	return ret;
}

VImage*
v_image_eff_bright(VImage* img)
{
	unsigned int op, op2;
	SET_RGB8_32(op,0x80,0x80,0x80,0x00);
	SET_RGB8_32(op2,0x7f,0x7f,0x7f,0xff);
	VImage* ret = v_image_new(img->size.w, img->size.h, 32);
	if ( img->size.w * img->size.h ) {
		v_image_draw_start(img, 0);
		v_image_draw_start(ret, 0);
		int cnt = img->w_border * img->size.h;
		while ( --cnt )
			ret->buf_32[cnt] = op +
				((img->buf_32[cnt] >> 1) & op2);
		v_image_draw_end(ret);
		v_image_draw_end(img);
	}
	return ret;
}

VImage*
v_image_eff_dark_b(VImage* img, VSize border)
{
	VImage* ret = v_image_copy(img);
	if ( img->size.w * img->size.h ) {
		v_image_draw_start(img, 0);
		v_image_draw_start(ret, 0);
		
		short ws = img->size.w < border.w ? img->size.w : border.w;
		short hs = img->size.h < border.h ? img->size.h : border.h;

		v_image_eff_dark_sub(ret, img, 0, 0, img->size.w, hs);
		v_image_eff_dark_sub(ret, img, 0, hs, ws, img->size.h);
		v_image_eff_dark_sub(ret, img, img->size.w-ws, hs, img->size.w, img->size.h);
		v_image_eff_dark_sub(ret, img, ws, img->size.h-hs, img->size.w-ws, img->size.h);
		
		v_image_draw_end(ret);
		v_image_draw_end(img);
	}
	return ret;
}

VImage*
v_image_eff_bright_b(VImage* img, VSize border)
{
	VImage* ret = v_image_copy(img);
	if ( img->size.w * img->size.h ) {
		v_image_draw_start(img, 0);
		v_image_draw_start(ret, 0);
		
		short ws = img->size.w < border.w ? img->size.w : border.w;
		short hs = img->size.h < border.h ? img->size.h : border.h;

		v_image_eff_bright_sub(ret, img, 0, 0, img->size.w, hs);
		v_image_eff_bright_sub(ret, img, 0, hs, ws, img->size.h);
		v_image_eff_bright_sub(ret, img, img->size.w-ws, hs, img->size.w, img->size.h);
		v_image_eff_bright_sub(ret, img, ws, img->size.h-hs, img->size.w-ws, img->size.h);
		
		v_image_draw_end(ret);
		v_image_draw_end(img);
	}
	return ret;
}

} // extern "C"
