home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Panoráma
/
computer_panorama_1997-12-hibas.iso
/
SHARE
/
GRAPH
/
PTC051.ZIP
/
SRC
/
CONVERT.H
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-21
|
13KB
|
464 lines
//////////////////////
// converter module //
//////////////////////
#ifndef __CONVERT_H
#define __CONVERT_H
#include "misc.h"
#include "lang.h"
#include "globals.h"
#include "config.h"
#include "format.h"
#include "color.h"
#include "list.h"
#include "x86_8.h"
#include "x86_16.h"
#include "x86_32.h"
#include "x86_fake.h"
#include "x86_copy.h"
#include "mmx_8.h"
#include "mmx_16.h"
#include "mmx_32.h"
#include "mmx_fake.h"
#include "mmx_copy.h"
#include "cpp_8.h"
#include "cpp_16.h"
#include "cpp_32.h"
#include "cpp_copy.h"
class CONVERTER
{
private:
// converter handle
class HANDLE
{
public:
// setup
HANDLE();
HANDLE(int src_id,int dest_id,int iextra=0,int icleanup=0);
~HANDLE();
// initialize
void init(int src_id,int dest_id,int iextra=0,int icleanup=0);
// data
FORMAT *src;
FORMAT *dest;
int extra;
int copy;
int cleanup;
void (*Convert)(void *src,void *dest,uint pixels,void *extra);
void (*AreaConvert)(void *src,void *dest,uint width,uint height,uint dest_advance,uint src_advance,void *extra);
void (*PartialConvert)(void *src,void *dest,int start_byte,int stop_byte,void *extra);
};
public:
// setup
CONVERTER();
~CONVERTER();
// basic conversion
inline int Convert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,uint pixels,void *extra);
inline int AreaConvert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,uint width,uint height,uint src_advance,uint dest_advance,void *extra);
inline int PartialConvert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,int start_byte,int stop_byte,void *extra);
// conversion routine access
inline HANDLE* RequestHandle(int src_id,int dest_id);
inline HANDLE* RequestHandle(FORMAT const &src,FORMAT const &dest);
inline void FreeHandle(HANDLE* converter);
// conversion via handle
inline int Convert(HANDLE *handle,void *src,void *dest,uint pixels,void *extra);
inline int AreaConvert(HANDLE *handle,void *src,void *dest,uint width,uint height,uint src_advance,uint dest_advance,void *extra);
inline int PartialConvert(HANDLE *handle,void *src,void *dest,int start_byte,int stop_byte,void *extra);
private:
// converter handle internals
static void InitHandles();
static void CloseHandles();
static void DefaultHandles();
static int DefaultHandles_X86();
static int DefaultHandles_CPP();
static int DefaultHandles_MMX();
static int SetupHandle(int src_id,int dest_id,void *convert,void *area,void *partial);
// interal conversion routines
inline int InternalConvert(HANDLE *handle,void *src,void *dest,uint pixels,void *extra);
// table generation
static int GenerateTable16_X86(void *dest,FORMAT const &format);
// reference count
static int count;
// static copy converter handle
static HANDLE *StaticCopyHandle;
// static 32bit -> X converter handles
static HANDLE *StaticHandle32;
// static 16bit -> X converter handles
static HANDLE *StaticHandle16;
// static 8bit -> X converter handles
static HANDLE *StaticHandle8;
static HANDLE *StaticHandle8_4BYTE;
static HANDLE *StaticHandle8_3BYTE;
static HANDLE *StaticHandle8_2BYTE;
static HANDLE *StaticHandle8_1BYTE;
};
inline int CONVERTER::Convert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,uint pixels,void *extra)
{
// convert
HANDLE *handle=RequestHandle(src_format,dest_format);
int result=Convert(handle,src,dest,pixels,extra);
FreeHandle(handle);
return result;
}
inline int CONVERTER::AreaConvert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,uint width,uint height,uint src_advance,uint dest_advance,void *extra)
{
// area convert
HANDLE *handle=RequestHandle(src_format,dest_format);
int result=AreaConvert(handle,src,dest,width,height,src_advance,dest_advance,extra);
FreeHandle(handle);
return result;
}
inline int CONVERTER::PartialConvert(void *src,FORMAT const &src_format,void *dest,FORMAT const &dest_format,int start_byte,int stop_byte,void *extra)
{
return 0;
}
inline CONVERTER::HANDLE* CONVERTER::RequestHandle(int src_id,int dest_id)
{
// fail on invalid destination id
if (dest_id<FORMATBASE || dest_id>FORMATMAX) return NULL;
// check for identical format ids = copy convert
if (src_id==dest_id) return &StaticCopyHandle[src_id-FORMATBASE];
// converters via src id
if (src_id==ARGB8888) return &StaticHandle32[dest_id-FORMATBASE];
if (src_id==RGB565) return &StaticHandle16[dest_id-FORMATBASE];
if (src_id==INDEX8) return &StaticHandle8 [dest_id-FORMATBASE];
// failure
return NULL;
}
inline CONVERTER::HANDLE* CONVERTER::RequestHandle(FORMAT const &src,FORMAT const &dest)
{
// try to get converter by id
HANDLE *handle=RequestHandle(src.id,dest.id);
if (handle) return handle;
// check 8bit -> X
if (src.id==INDEX8)
{
// check for byte size table handle
switch (dest.bytes)
{
case 4: return StaticHandle8_4BYTE;
case 3: return StaticHandle8_3BYTE;
case 2: return StaticHandle8_2BYTE;
case 1: return StaticHandle8_1BYTE;
}
}
// unknown format - check for match
if (src==dest && src.ok())
{
// allocate custom copy handle
handle=new HANDLE;
if (!handle) return NULL;
*handle->src=src;
*handle->dest=dest;
handle->extra=0;
handle->copy=1;
handle->cleanup=1;
handle->Convert=StaticCopyHandle[0].Convert;
handle->AreaConvert=StaticCopyHandle[0].AreaConvert;
handle->PartialConvert=StaticCopyHandle[0].PartialConvert;
return handle;
}
// generic converter
handle=new HANDLE;
if (!handle) return NULL;
*handle->src=src;
*handle->dest=dest;
handle->extra=0; // how to handle this?
handle->copy=0;
handle->cleanup=1;
handle->Convert=NULL;
handle->AreaConvert=NULL;
handle->PartialConvert=NULL;
return handle;
}
inline void CONVERTER::FreeHandle(CONVERTER::HANDLE *handle)
{
if (handle && handle->cleanup) delete handle;
}
inline int CONVERTER::Convert(CONVERTER::HANDLE *handle,void *src,void *dest,uint pixels,void *extra)
{
// check valid handle
if (!handle) return 0;
// copy convert needs bytes not pixels
if (handle->copy) pixels*=handle->src->bytes;
// check that if handle needs extra its been given
if (handle->extra && !extra) return 0;
// perform the conversion
return InternalConvert(handle,src,dest,pixels,extra);
}
inline int CONVERTER::AreaConvert(CONVERTER::HANDLE *handle,void *src,void *dest,uint width,uint height,uint src_advance,uint dest_advance,void *extra)
{
/*
// check for valid converter handle
if (!handle || !handle->Convert) return 0;
// check that if converter needs extra its been given
if (handle->extra && !extra) return 0;
// copy convert needs bytes not pixels
if (handle->copy) width*=handle->src->bytes;
// try specified AreaConverter in Converter (not yet)
// fail on invalid data
if (!src || !dest) return 0;
// provide a backup area converter
if (handle->AreaConvert==NULL)
{
// fail on bad converter
if (!handle->Con