/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.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	"r64.h"
#include	"r64_types.h"

int
r64_red(unsigned char * buf,R64_FILE * f,int w,int h,int level)
{
R64_CACHE_ENT * ce;
	if ( f->level_ofs[level] == 0 ) {
		r64_error = E_NOLEV;
		return -1;
	}
	if ( w < 0 || w >= f->level_w[level] ||
			h < 0 || h >= f->level_h[level] ) {
		switch ( f->rc_type ) {
		case RC_NEAR:
			if ( 0 <= w && w < f->level_w[level] && h < 0 )
				return r64_red(buf,f,w,0,level);
			if ( 0 <= w && w < f->level_w[level] &&
					h >= f->level_h[level] )
				return r64_red(buf,f,w,
					f->level_h[level]-1,level);
			if ( 0 <= h && h < f->level_h[level] && w < 0 )
				return r64_red(buf,f,0,h,level);
			if ( 0 <= h && h < f->level_h[level] && 
					w >= f->level_w[level] )
				return r64_red(buf,f,
					f->level_w[level]-1,h,level);
			if ( w < 0 && h < 0 )
				return r64_red(buf,f,0,0,level);
			if ( w < 0 )
				return r64_red(buf,f,0,
					f->level_h[level]-1,level);
			if ( h < 0 )
				return r64_red(buf,f,
					f->level_w[level]-1,0,level);
			return r64_red(buf,f,
				f->level_w[level]-1,
				f->level_h[level]-1,
				level);
		case RC_BACK:
			memcpy(buf,f->background,ENT_UNIT_VOL(f));
			r64_error = E_OK;
			return 0;
		default:
			r64_error = E_FATAL;
			return -1;
		}
	}
	if ( _search_ce(f,w,h,level) < 0 )
		return -1;
	ce = f->cache[0].next;
	if ( f->header.type == 'B' ) {
	int pos,bit;
		pos = (h - ce->h_ofs)*
			(ce->w_len/8 + (ce->w_len%8 ? 1 : 0)) +
			w/8;
		bit = 7-w%8;
		if ( ce->buf[pos]&(1<<bit) )
			*buf = 0xff;
		else	*buf = 0x00;
	}
	else {
		memcpy(buf,&ce->buf[BIT_OFS_IN_CH(f,ce,w,h)],
			ENT_UNIT_VOL(f));
/*
printf("CE(%x) %x %i - %x\n",f,ce,BIT_OFS_IN_CH(f,ce,w,h),buf[0]);
*/
	}
	r64_error = E_OK;
	return 0;
}

