Files
FireBee_Setup/tools/vision/LDV/LDV.C
2022-11-14 10:05:42 +01:00

1203 lines
36 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "..\tools\chkstack.h"
#include "..\tools\scalemem.h"
#include "..\tools\gwindows.h"
#include "..\tools\rasterop.h"
#include "..\tools\frecurse.h"
#include "..\tools\logging.h"
#include "..\tools\xfile.h"
#include "..\tools\ini.h"
#include "..\tools\cpupng.h" /* Workaround */
#include "actions.h"
#include "ldv\ldvcom.h"
static LDV_MODULE *Modules ;
static int NbModules ;
static int NumModule ;
static short ListTypes[] = { TLDV_MODIFYIMG, TLDV_LOADIMG, TLDV_SAVEIMG } ;
#define VAPI_LDVVERSION 0x0104
static VAPI *Vapi = NULL ;
static GEM_WINDOW *LdvProg = NULL ;
void cdecl PrSetText(long no_line, char *text)
{
if ( LdvProg && ( no_line >= 0 ) && ( no_line <= 2 ) )
StdProgWText( LdvProg, (int)no_line, text ) ;
}
void cdecl PrSetProg(long pc)
{
if ( LdvProg ) LdvProg->ProgPc( LdvProg, (int)pc, NULL ) ;
}
long cdecl PrSetProgEx(long pc)
{
long ret = 0 ;
if ( LdvProg ) ret = LdvProg->ProgPc( LdvProg, (int)pc, NULL ) ;
if ( ret != 0 ) LdvProg = NULL ;
return( ret ) ;
}
void cdecl PrOptimize(long mask)
{
if ( LdvProg )
{
StdProgDisplay030( LdvProg, (int)mask & 0x01 ) ;
StdProgDisplayDSP( LdvProg, (int)mask & 0x02 ) ;
StdProgDisplayFPU( LdvProg, (int)mask & 0x04 ) ;
}
}
void cdecl RaImgWhite(MFDB *img)
{
img_raz( img ) ;
}
long cdecl RaIs15Bits(void)
{
long is_15bits = 0 ;
if ( nb_plane == 16 ) is_15bits = RVBOrg.Is15Bits ;
return( is_15bits ) ;
}
void cdecl RaTCConvert(MFDB *img)
{
tc_convert( img ) ;
}
void cdecl RaTCInvConvert(MFDB *img)
{
tc_invconvert( img ) ;
}
void cdecl RaInd2RasterInit(MFDB *out, long width)
{
int raz_done = 0 ;
i2r_init( out, (short)width, raz_done ) ;
}
void cdecl RaInd2Raster(unsigned char *indexes, long nb_indexes)
{
i2r_data = indexes ;
i2r_nb = nb_indexes ;
ind2raster() ;
}
void cdecl RaRaster2Ind(short *pt_raster, long nb_pts, long nplans, unsigned char *out)
{
raster2ind( (int*)pt_raster, out, nb_pts, (short)nplans ) ;
}
unsigned char * cdecl RaGetTOS2VDIArray(long nplanes)
{
return( get_pttos2vdi( (short)nplanes ) ) ;
}
unsigned char * cdecl RaGetVDI2TOSArray(long nplanes)
{
return( get_ptvdi2tos( (short)nplanes ) ) ;
}
unsigned long cdecl RaGetImgSize(long width, long height, long nplanes)
{
return( (unsigned long) img_size( (int)width, (int)height, (int)nplanes ) ) ;
}
long cdecl RaRasterAlloc(MFDB *raster)
{
size_t size ;
size = img_size( raster->fd_w, raster->fd_h, raster->fd_nplanes ) ;
raster->fd_addr = Xalloc( size ) ;
if ( raster->fd_addr )
{
raster->fd_wdwidth = raster->fd_w / 16 ;
if ( raster->fd_w % 16 ) raster->fd_wdwidth++ ;
return( 0 ) ;
}
return( -1 ) ; /* Erreur */
}
void cdecl RaRasterFree(MFDB *raster)
{
if ( raster->fd_addr ) Xfree( raster->fd_addr ) ;
memset( raster, 0, sizeof(MFDB) ) ;
}
void cdecl RaTC15RemapColors(REMAP_COLORS *rc)
{
TC15RemapColors( rc ) ;
}
void cdecl RaTC16RemapColors(REMAP_COLORS *rc)
{
TC16RemapColors( rc ) ;
}
void cdecl RaTC32RemapColors(REMAP_COLORS *rc)
{
TC32RemapColors( rc ) ;
}
void cdecl RaRasterRotateGetDstMFDB(MFDB *in, MFDB *out, long angle)
{
float cosinus, sinus ;
raster_rgetdstmfdb( (int)angle, in, out, &cosinus, &sinus ) ;
}
long cdecl RaRasterRotate(MFDB *in, MFDB *out, long angle, long flags)
{
LDV_STATUS status ;
int ret ;
if ( flags & 0x01L ) /* Progression */
ret = raster_rotate( in, out, (int) angle, LdvProg ) ;
else
ret = raster_rotate( in, out, (int) angle, NULL ) ;
switch( ret )
{
case 0 : status = ELDV_NOERROR ;
break ;
case -1 : status = ELDV_NOTENOUGHMEMORY ;
break ;
case 1 : status = ELDV_CANCELLED ;
break ;
default : status = ELDV_GENERALFAILURE ;
break ;
}
return( (long)status ) ;
}
void cdecl GEMMessageLoop(void *msg)
{
EVENT event ;
memcpy( &event.ev_mmgpbuf, msg, sizeof(event.ev_mmgpbuf) ) ;
GeneralMesagHandler( &event ) ;
}
char* cdecl CoGetLDVPath(void)
{
return( config.path_ldv ) ;
}
char* cdecl CoGetCurrentLanguage(void)
{
return( config.language ) ;
}
unsigned long cdecl CoGetFunctionOptimizations(void *function)
{
unsigned long code = 0 ;
if ( MachineInfo.cpu >= 30L )
{
if ( ( function == (void *)Vapi->MeSCopyMemory16 ) ||
( function == (void *)Vapi->MeSCopyMemory32 ) ||
( function == (void *)Vapi->RaRasterRotate ) ||
( function == (void *)Vapi->RaInd2Raster )
) code |= 0x01 ;
}
return( code ) ;
}
unsigned long cdecl CoGetProcessors(void)
{
unsigned long pmask = 0 ;
if ( (MachineInfo.cpu >= 30L) && ((config.ldv_options & LDVO_HIDE030) == 0) )
pmask |= CO_HAS_030 ;
if ( get_fpu() && ((config.ldv_options & LDVO_HIDEFPU) == 0) )
pmask |= CO_HAS_FPU ;
if ( DspInfo.type && ((config.ldv_options & LDVO_HIDEDSP) == 0) )
pmask |= CO_HAS_DSP ;
return pmask ;
}
long cdecl InOpen(char *file)
{
return( (long) OpenIni( file ) ) ;
}
long cdecl InClose(HINI h_ini)
{
return( CloseIni( h_ini ) ) ;
}
long cdecl InSaveAndClose(HINI h_ini, char *new_name)
{
return( SaveAndCloseIni( h_ini, new_name ) ) ;
}
long cdecl InGetKey(HINI h_ini, char *section, char *key, char *val_key)
{
return( GetIniKey( h_ini, section, key, val_key ) ) ;
}
long cdecl InSetKey(HINI h_ini, char *section, char *key, char *val_key)
{
return( SetIniKey( h_ini, section, key, val_key ) ) ;
}
long cdecl InGetOrSetKey(HINI h_ini, char *section, char *key, char *val_default_key)
{
return( GetOrSetIniKey( h_ini, section, key, val_default_key ) ) ;
}
long cdecl InGetKeyFromFile(char *file, char *section, char *key, char *val_key)
{
return GetIniKeyFromFile( file, section, key, val_key ) ;
}
void cdecl MeSCopyMemory8(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm_smemcpy8( dst, src, nb_elems_dst, nb_elems_src ) ;
}
void cdecl MeSCopyMemory16(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm_smemcpy16( dst, src, nb_elems_dst, nb_elems_src ) ;
}
void cdecl MeSCopyMemory32(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm_smemcpy32( dst, src, nb_elems_dst, nb_elems_src ) ;
}
void cdecl Me030SCopyMemory8(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm030_smemcpy8( dst, src, nb_elems_dst, nb_elems_src ) ;
}
void cdecl Me030SCopyMemory16(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm030_smemcpy16( dst, src, nb_elems_dst, nb_elems_src ) ;
}
void cdecl Me030SCopyMemory32(void *dst, void *src, unsigned long nb_elems_dst, unsigned long nb_elems_src)
{
asm030_smemcpy32( dst, src, nb_elems_dst, nb_elems_src ) ;
}
unsigned long cdecl LoGetLogLevel(void)
{
return LoggingGetLevel() ;
}
#ifdef __NO_LOGGING
#pragma warn -par
long cdecl LoDoLog(unsigned long level, char* format, ...)
{
return 0 ;
}
#pragma warn +par
#else
long cdecl LoDoLog(unsigned long level, char* format, ...)
{
va_list argp ;
long r ;
va_start(argp, format) ;
r = LoggingvDo(level, format, argp) ;
va_end(argp) ;
return r ;
}
#endif
VAPI *LDVInitVAPI(void)
{
if ( Vapi == NULL )
{
Vapi = (VAPI *) Xcalloc( 1, sizeof(VAPI) ) ;
if ( Vapi )
{
Vapi->Header.Version = VAPI_LDVVERSION ;
Vapi->Header.StrSize = sizeof(VAPI) ;
LoggingDo(LL_INFO, "VAPI Version: %02x.%02x", Vapi->Header.Version >> 8, Vapi->Header.Version & 0xFF) ;
LoggingDo(LL_INFO, "VAPI interface size:%d bytes", Vapi->Header.StrSize) ;
Vapi->Header.Global = _GemParBlk.global ;
Vapi->Header.GEMMessageLoop = GEMMessageLoop ;
/* Progress Interface */
Vapi->PrSetProg = PrSetProg ;
Vapi->PrOptimize = PrOptimize ;
Vapi->PrSetText = PrSetText ;
Vapi->PrSetProgEx = PrSetProgEx ;
/* Raster Interface */
Vapi->RaImgWhite = RaImgWhite ;
Vapi->RaIs15Bits = RaIs15Bits ;
Vapi->RaTCInvConvert = RaTCInvConvert ;
Vapi->RaTCConvert = RaTCConvert ;
Vapi->RaInd2RasterInit = RaInd2RasterInit ;
Vapi->RaInd2Raster = RaInd2Raster ;
Vapi->RaRaster2Ind = RaRaster2Ind ;
Vapi->RaGetTOS2VDIArray = RaGetTOS2VDIArray ;
Vapi->RaGetVDI2TOSArray = RaGetVDI2TOSArray ;
Vapi->RaGetImgSize = RaGetImgSize ;
Vapi->RaRasterAlloc = RaRasterAlloc ;
Vapi->RaRasterFree = RaRasterFree ;
Vapi->RaTC15RemapColors = RaTC15RemapColors ;
Vapi->RaTC16RemapColors = RaTC16RemapColors ;
Vapi->RaTC32RemapColors = RaTC32RemapColors ;
Vapi->RaRasterRotateGetDstMFDB = RaRasterRotateGetDstMFDB ;
Vapi->RaRasterRotate = RaRasterRotate ;
/* Config Interface */
Vapi->CoGetLDVPath = CoGetLDVPath ;
Vapi->CoGetCurrentLanguage = CoGetCurrentLanguage ;
Vapi->CoGetFunctionOptimizations = CoGetFunctionOptimizations ;
Vapi->CoGetProcessors = CoGetProcessors ;
/* INI Interface */
Vapi->InOpen = InOpen ;
Vapi->InClose = InClose ;
Vapi->InSaveAndClose = InSaveAndClose ;
Vapi->InGetKey = InGetKey ;
Vapi->InSetKey = InSetKey ;
Vapi->InGetOrSetKey = InGetOrSetKey ;
Vapi->InGetKeyFromFile = InGetKeyFromFile ;
/* MEM Interface */
if ( MachineInfo.cpu >= 30L )
{
Vapi->MeSCopyMemory8 = Me030SCopyMemory8 ;
Vapi->MeSCopyMemory16 = Me030SCopyMemory16 ;
Vapi->MeSCopyMemory32 = Me030SCopyMemory32 ;
}
else
{
Vapi->MeSCopyMemory8 = MeSCopyMemory8 ;
Vapi->MeSCopyMemory16 = MeSCopyMemory16 ;
Vapi->MeSCopyMemory32 = MeSCopyMemory32 ;
}
/* Logging Interface */
Vapi->LoDoLog = LoDoLog ;
Vapi->LoGetLogLevel = LoGetLogLevel ;
}
}
return( Vapi ) ;
}
int LDVSetValueFromString(char *buf, int type, LDV_BASICPARAM *p)
{
int set = 1 ;
switch( type )
{
case LDVT_SHORT : p->s = atoi( buf ) ;
break ;
case LDVT_FLOAT : p->f = atof( buf ) ;
break ;
default : set = 0 ;
break ;
}
return( set ) ;
}
int LDVGetIniSpec(char *base_path, LDV_MODULE *ldv_module)
{
HINI hini ;
int err = 0 ;
int i, max_len ;
char name[PATH_MAX] ;
char *point ;
char short_name[16] ;
char long_name[32] ;
char description[80] ;
char buf[200] ;
point = strrchr( ldv_module->FileName, '.' ) ;
if ( point ) *point = 0 ;
sprintf( name, "%s\\%s\\%s.INI", base_path, config.language, ldv_module->FileName ) ;
if ( !FileExist( name ) ) sprintf( name, "%s\\%s.INI", base_path, ldv_module->FileName ) ;
hini = OpenIni( name ) ;
if ( ( hini != NULL ) && FileExist( name ) )
{
/* ShortName */
buf[0] = 0 ;
GetIniKey( hini, "Informations", "ShortName", buf ) ;
max_len = (int) sizeof(short_name) - 1 ;
if ( strlen( buf ) > max_len ) buf[max_len] = 0 ;
strcpy( short_name, buf ) ;
/* LongName */
buf[0] = 0 ;
GetIniKey( hini, "Informations", "LongName", buf ) ;
max_len = (int) sizeof(long_name) - 1 ;
if ( strlen( buf ) > max_len ) buf[max_len] = 0 ;
strcpy( long_name, buf ) ;
/* Description */
buf[0] = 0 ;
GetIniKey( hini, "Informations", "Description", buf ) ;
max_len = (int) sizeof(description) - 1 ;
if ( strlen( buf ) > max_len ) buf[max_len] = 0 ;
strcpy( description, buf ) ;
ldv_module->IniSpec.ShortName = NULL ;
ldv_module->IniSpec.LongName = NULL ;
ldv_module->IniSpec.Description = NULL ;
max_len = 1 + (int) strlen( short_name ) ;
max_len += 1 + (int) strlen( long_name ) ;
max_len += 1 + (int) strlen( description ) ;
ldv_module->IniSpec.ShortName = (char *) Xalloc( max_len ) ;
if ( ldv_module->IniSpec.ShortName )
{
strcpy( ldv_module->IniSpec.ShortName, short_name ) ;
strcpy( ldv_module->IniSpec.ShortName + 1 + strlen( short_name ), long_name ) ;
strcpy( ldv_module->IniSpec.ShortName + 1 + strlen( short_name ) + 1 + strlen( long_name ), description ) ;
ldv_module->IniSpec.LongName = ldv_module->IniSpec.ShortName + 1 + strlen( short_name ) ;
ldv_module->IniSpec.Description = ldv_module->IniSpec.LongName + 1 + strlen( long_name ) ;
}
/* Parameters */
for ( i = 0; i < LDVNBMAX_PARAMETERS; i++ )
{
/* Name */
buf[0] = 0 ;
sprintf( name, "Parameter%d", 1 + i ) ;
GetIniKey( hini, name, "Name", buf ) ;
max_len = (int) sizeof(ldv_module->IniSpec.Params[i].Name) - 1 ;
if ( strlen( buf ) > max_len ) buf[max_len] = 0 ;
strcpy( ldv_module->IniSpec.Params[i].Name, buf ) ;
/* Type */
buf[0] = 0 ;
GetIniKey( hini, name, "Type", buf ) ;
ldv_module->IniSpec.Params[i].Type = atoi( buf ) ;
/* MinValue */
buf[0] = 0 ;
GetIniKey( hini, name, "MinValue", buf ) ;
LDVSetValueFromString( buf, ldv_module->IniSpec.Params[i].Type, &ldv_module->IniSpec.Params[i].MinValue ) ;
/* DefaultValue */
buf[0] = 0 ;
GetIniKey( hini, name, "DefaultValue", buf ) ;
LDVSetValueFromString( buf, ldv_module->IniSpec.Params[i].Type, &ldv_module->IniSpec.Params[i].DefaultValue ) ;
/* MaxValue */
buf[0] = 0 ;
GetIniKey( hini, name, "MaxValue", buf ) ;
LDVSetValueFromString( buf, ldv_module->IniSpec.Params[i].Type, &ldv_module->IniSpec.Params[i].MaxValue ) ;
/* FloatIncrement */
buf[0] = 0 ;
GetIniKey( hini, name, "FloatIncrement", buf ) ;
ldv_module->IniSpec.Params[i].FloatIncrement = atof( buf ) ;
/* Verification de la validite */
if ( ldv_module->IniSpec.Params[i].MinValue.s == ldv_module->IniSpec.Params[i].MaxValue.s )
ldv_module->IniSpec.Params[i].Name[0] = 0 ; /* Ignorer ce parametre */
}
CloseIni( hini ) ;
}
else err = 1 ;
if ( point ) *point ='.' ;
return( err ) ;
}
void LDVReleaseInterface(LDV_MODULE *mod, int iid)
{
void *old_interface = NULL ;
if ( mod && ( mod->Infos.Type & iid ) )
{
switch( iid )
{
case TLDV_MODIFYIMG : old_interface = mod->IModifImg ;
mod->IModifImg = NULL ;
break ;
case TLDV_LOADIMG : old_interface = mod->ILoadImg ;
mod->ILoadImg = NULL ;
break ;
case TLDV_SAVEIMG : old_interface = mod->ISaveImg ;
mod->ISaveImg = NULL ;
break ;
}
}
if ( old_interface )
{
Xfree( old_interface ) ;
mod->NbReferences-- ;
}
}
void *LDVGetInterface(LDV_MODULE *mod, int iid)
{
LDG *ldg ;
void *interface = NULL ;
if ( mod && ( mod->Infos.Type & iid ) )
{
ldg = mod->Ldg ;
switch( iid )
{
case TLDV_MODIFYIMG : if ( mod->IModifImg ) LDVReleaseInterface( mod, iid ) ;
mod->IModifImg = (ILDVModifImg *) Xcalloc( 1, sizeof(ILDVModifImg) ) ;
if ( mod->IModifImg )
{
mod->IModifImg->PreRun = ldg_find( "PreRun", ldg ) ;
mod->IModifImg->Run = ldg_find( "Run", ldg ) ;
mod->IModifImg->Preview = ldg_find( "Preview", ldg ) ;
mod->IModifImg->GetParams = ldg_find( "GetParams", ldg ) ;
}
interface = mod->IModifImg ;
break ;
case TLDV_LOADIMG : if ( mod->ILoadImg ) LDVReleaseInterface( mod, iid ) ;
mod->ILoadImg = (ILDVLoadImg *) Xcalloc( 1, sizeof(ILDVLoadImg) ) ;
if ( mod->ILoadImg )
{
}
interface = mod->ILoadImg ;
break ;
case TLDV_SAVEIMG : if ( mod->ISaveImg ) LDVReleaseInterface( mod, iid ) ;
mod->ISaveImg = (ILDVSaveImg *) Xcalloc( 1, sizeof(ILDVSaveImg) ) ;
if ( mod->ISaveImg )
{
}
interface = mod->ISaveImg ;
break ;
}
}
if ( interface ) mod->NbReferences++ ;
return( interface ) ;
}
void LDVReleaseAllInterfaces(LDV_MODULE *ldv_module)
{
short index ;
for ( index = 0; index < sizeof(ListTypes)/sizeof(short); index++ )
LDVReleaseInterface( ldv_module, ListTypes[index] ) ;
}
void LDVGetAllInterfaces(LDV_MODULE *ldv_module)
{
short index ;
for ( index = 0; index < sizeof(ListTypes)/sizeof(short); index++ )
LDVGetInterface( ldv_module, ListTypes[index] ) ;
}
void LDVUnloadFunctions(LDV_MODULE *ldv_module)
{
LDVReleaseAllInterfaces( ldv_module ) ;
ldg_term( ap_id, ldv_module->Ldg ) ;
ldv_module->Ldg = NULL ;
}
LDV_STATUS LDVInit(char *file, LDV_MODULE *ldv_module, int minimal_infos)
{
LDV_INFOS *ldv_infos ;
LDG *ldg ;
LDV_STATUS err = ELDV_NOERROR ;
#if !defined(__NO_LOGGING)
short ver ;
#endif
char *slash, *lname = file ;
char base_path[PATH_MAX] ;
if ( minimal_infos )
{
if ( ldv_module->FileName ) Xfree( ldv_module->FileName ) ;
memset( ldv_module, 0, sizeof(LDV_MODULE) ) ;
}
slash = strrchr( file, '\\' ) ;
if ( slash )
{
*slash = 0 ;
strcpy( base_path, file ) ;
*slash = '\\' ;
lname = 1 + slash ;
}
if ( ldv_module->FileName )
{
if ( strlen( ldv_module->FileName ) < strlen( lname ) )
{
Xfree( ldv_module->FileName ) ;
ldv_module->FileName = Xalloc( 1 + strlen( lname ) ) ;
if ( ldv_module->FileName == NULL ) return( ELDV_NOTENOUGHMEMORY ) ;
}
strcpy( ldv_module->FileName, lname ) ;
}
else
{
ldv_module->FileName = Xalloc( 1 + strlen( lname ) ) ;
if ( ldv_module->FileName == NULL ) return( ELDV_NOTENOUGHMEMORY ) ;
strcpy( ldv_module->FileName, lname ) ;
}
/* Workaround for Mint/Aranym: if libpng is not closed, ldg_exec will freeze */
cpu_png_terminate() ;
ldg = ldg_exec( ap_id, file ) ;
if ( ldg )
{
ldv_module->Ldg = ldg ;
ldv_module->GetLDVCapabilities = ldg_find( "GetLDVCapabilities", ldg ) ;
ldv_module->Infos.StrSize = sizeof(ldv_module->Infos) ;
if ( ldv_module->GetLDVCapabilities ) ldv_infos = ldv_module->GetLDVCapabilities( Vapi ) ;
else err = ELDV_GENERALFAILURE ;
if ( LDV_SUCCESS( err ) && ldv_infos )
{
if ( ldv_infos->StrSize <= ldv_module->Infos.StrSize ) memcpy( &ldv_module->Infos, ldv_infos, ldv_infos->StrSize ) ;
else err = ELDV_GENERALFAILURE ;
}
else
err = ELDV_GENERALFAILURE ;
ldv_module->Version = ldg->vers ;
#if !defined(__NO_LOGGING)
ver = ldg->vers ;
#endif
}
else LoggingDo(LL_ERROR, "Failed to exec ldg %s", file);
if ( !err )
{
if ( minimal_infos )
{
LDVGetIniSpec( base_path, ldv_module ) ;
LDVUnloadFunctions( ldv_module ) ;
}
else LDVGetAllInterfaces( ldv_module ) ;
}
#if !defined(__NO_LOGGING)
if (err)
LoggingDo(LL_INFO, "Loading LDV %12s returned %ld", lname, err) ;
else
LoggingDo(LL_INFO, "Loading LDV %12s(v%x.%02x)...OK", lname, ver >> 8, ver & 0xFF) ;
#endif
return( err ) ;
}
LDV_STATUS LDVLoadFunctions(char *path, LDV_MODULE *mod)
{
char filename[PATH_MAX] ;
sprintf( filename, "%s\\%s", path, mod->FileName ) ;
return( LDVInit( filename, mod, 0 ) ) ;
}
LDV_CAPS *LDVGetNPlanesCaps(LDV_MODULE *mod, int nplanes)
{
LDV_CAPS *caps ;
caps = &mod->Infos.Caps[0] ;
while ( caps->NbPlanes )
{
if ( caps->NbPlanes == nplanes ) break ;
else caps++ ;
}
if ( caps->NbPlanes == 0 ) caps = NULL ;
return( caps ) ;
}
int add_ldv(FR_CDATA* fr_cdata)
{
/* Should always be true */
if ( NumModule < NbModules )
if ( LDVInit( fr_cdata->filename, &Modules[NumModule], 1 ) == 0 ) NumModule++ ;
return 0 ;
}
LDV_MODULE *LDVGetModuleList(char *path, int *nb_ldv)
{
FR_DATA fr_data ;
fr_data.long_names = 0 ; /* Better not use long filenames here, old OSes would report no files */
fr_data.path = path ;
fr_data.mask = "*.LDV" ;
fr_data.log_file = NULL ;
fr_data.user_func = NULL ;
fr_data.user_data = NULL ;
Modules = NULL ;
NbModules = (int) count_files( 0, &fr_data ) ;
if ( NbModules > 0 )
{
Vapi = LDVInitVAPI() ;
/* Last module (not valid) will be zeroed */
NumModule = 0 ;
Modules = (LDV_MODULE *) Xcalloc( 1+NbModules, sizeof(LDV_MODULE) ) ;
fr_data.long_names = 0 ;
fr_data.path = path ;
fr_data.mask = "*.LDV" ;
fr_data.log_file = NULL ;
fr_data.user_func = add_ldv ;
fr_data.user_data = NULL ;
if ( Modules ) find_files( &fr_data ) ;
else NbModules = 0 ;
}
if ( nb_ldv ) *nb_ldv = NbModules ;
return( Modules ) ;
}
void LDVFreeModuleList(LDV_MODULE *module_list)
{
LDV_MODULE *mod ;
int i ;
mod = module_list ;
for ( i = 0; i < NbModules; i++, mod++ )
{
if ( mod->IniSpec.ShortName ) Xfree( mod->IniSpec.ShortName ) ;
if ( mod->FileName ) Xfree( mod->FileName ) ;
if ( mod->Ldg ) LDVUnloadFunctions( mod ) ;
}
Xfree( module_list ) ;
if ( Vapi ) Xfree( Vapi ) ;
Vapi = NULL ;
}
LDV_MODULE *GetLdvByLdg(LDV_MODULE *ldv_list, LDG *ldg)
{
LDV_MODULE *ldv_module = NULL ;
LDV_MODULE *cldv = ldv_list ;
if ( ldv_list )
{
while ( cldv->Ldg && ( ldv_module == NULL ) )
{
if ( cldv->Ldg == ldg ) ldv_module = cldv ;
else cldv++ ;
}
}
return( ldv_module ) ;
}
LDV_STATUS LDVAlloc(LDV_IMAGE *img)
{
LDV_STATUS err = ELDV_NOERROR ;
if ( img->Raster.fd_w && img->Raster.fd_h )
{
img->Raster.fd_addr = img_alloc( img->Raster.fd_w, img->Raster.fd_h,img->Raster.fd_nplanes ) ;
if ( img->Raster.fd_addr == NULL )
err = ELDV_NOTENOUGHMEMORY ;
else
{
img->Raster.fd_wdwidth = img->Raster.fd_w / 16 ;
if ( img->Raster.fd_w % 16 ) img->Raster.fd_wdwidth++ ;
}
}
if ( img->Palette.NbColors > 0 )
{
img->Palette.Pal = Xcalloc( img->Palette.NbColors, sizeof(VDI_ELEMENTPAL) ) ;
if ( img->Palette.Pal == NULL ) err = ELDV_NOTENOUGHMEMORY ;
}
return( err ) ;
}
int GetBestImgFormat(LDV_CAPS *caps)
{
int img_format ;
switch( caps->NbPlanes )
{
case 1 :
case 2 :
case 4 :
case 8 : if ( caps->Flags & LDVF_SPECFORMAT ) img_format = (int)LDVF_SPECFORMAT ;
else
if ( caps->Flags & LDVF_STDFORMAT ) img_format = (int)LDVF_STDFORMAT ;
else
if ( caps->Flags & LDVF_ATARIFORMAT ) img_format = (int)LDVF_ATARIFORMAT ;
else img_format = (int)LDVF_ATARIFORMAT ;
break ;
case 16 :
case 24 :
case 32 : if ( caps->Flags & LDVF_SPECFORMAT ) img_format = (int)LDVF_SPECFORMAT ;
else
if ( caps->Flags & LDVF_ATARIFORMAT ) img_format = (int)LDVF_ATARIFORMAT ;
else img_format = (int)LDVF_ATARIFORMAT ;
break ;
default : img_format = (int)LDVF_SPECFORMAT ;
break ;
}
return( img_format ) ;
}
LDV_STATUS FormatLdvImgFromSpec(LDV_IMAGE *ldv_img, int new_format)
{
MFDB previous_img, std_img ;
LDV_STATUS err = ELDV_NOERROR ;
/* ldv_img->raster doit valoir LDVF_SPECFORMAT */
if ( ldv_img->RasterFormat != LDVF_SPECFORMAT ) return( ELDV_GENERALFAILURE ) ;
memcpy( &previous_img, &ldv_img->Raster, sizeof(MFDB) ) ;
if ( ldv_img->RasterFormat != new_format )
{
switch( new_format )
{
case LDVF_STDFORMAT : if ( ldv_img->Raster.fd_nplanes <= 8 )
{
memcpy( &std_img, &ldv_img->Raster, sizeof(MFDB) ) ;
std_img.fd_addr = img_alloc( std_img.fd_w, std_img.fd_h, std_img.fd_nplanes ) ;
if ( std_img.fd_addr == NULL ) err = ELDV_NOTENOUGHMEMORY ;
if ( LDV_SUCCESS( err ) )
{
std_img.fd_stand = 1 ;
vr_trnfm( handle, &ldv_img->Raster, &std_img ) ;
Xfree( ldv_img->Raster.fd_addr ) ;
memcpy( &ldv_img->Raster, &std_img, sizeof(MFDB) ) ;
}
}
else
err = ELDV_GENERALFAILURE ;
break ;
case LDVF_ATARIFORMAT : if ( ldv_img->Raster.fd_nplanes <= 8 )
{
if ( MakeMFDBClassicAtari( &ldv_img->Raster, NULL ) != 0 )
err = ELDV_NOTENOUGHMEMORY ;
}
else if ( UseStdVDI ) tc_invconvert( &ldv_img->Raster ) ;
break ;
default : err = ELDV_GENERALFAILURE ;
break ;
}
if ( LDV_SUCCESS( err ) ) ldv_img->RasterFormat = (short)new_format ;
}
return( err ) ;
}
LDV_STATUS FormatLdvImgToSpec(LDV_IMAGE *ldv_img)
{
MFDB img ;
LDV_STATUS err = ELDV_NOERROR ;
switch( ldv_img->RasterFormat )
{
case LDVF_SPECFORMAT : err = ELDV_NOERROR ;
break ;
case LDVF_STDFORMAT : if ( ldv_img->Raster.fd_nplanes <= 8 )
{
memcpy( &img, &ldv_img->Raster, sizeof(MFDB) ) ;
img.fd_addr = img_alloc( img.fd_w, img.fd_h, img.fd_nplanes ) ;
if ( img.fd_addr == NULL ) err = ELDV_NOTENOUGHMEMORY ;
if ( LDV_SUCCESS( err ) )
{
img.fd_stand = 0 ;
vr_trnfm( handle, &ldv_img->Raster, &img ) ;
Xfree( ldv_img->Raster.fd_addr ) ;
memcpy( &ldv_img->Raster, &img, sizeof(MFDB) ) ;
}
}
else
err = ELDV_GENERALFAILURE ;
break ;
case LDVF_ATARIFORMAT : if ( UseStdVDI && ( ldv_img->Raster.fd_nplanes <= 8 ) )
{
memcpy( &img, &ldv_img->Raster, sizeof(MFDB) ) ;
img.fd_addr = img_alloc( img.fd_w, img.fd_h, img.fd_nplanes ) ;
if ( img.fd_addr )
{
img.fd_stand = 1 ;
ClassicAtari2StdVDI( &ldv_img->Raster, &img ) ;
ldv_img->Raster.fd_stand = 0 ;
vr_trnfm( handle, &img, &ldv_img->Raster ) ;
Xfree( img.fd_addr ) ;
}
else
err = ELDV_NOTENOUGHMEMORY ;
}
else if ( UseStdVDI ) tc_convert( &ldv_img->Raster ) ;
break ;
default : err = ELDV_GENERALFAILURE ;
break ;
}
if ( LDV_SUCCESS( err ) ) ldv_img->RasterFormat = (int)LDVF_SPECFORMAT ;
return( err ) ;
}
LDV_STATUS LDVDo(LDV_MODULE *ldv, LDV_PARAMS *pldv_params, LDV_IMAGE *pldv_img, int preview, LDV_PERF *perfs)
{
LDV_PARAMS ldv_params ;
LDV_CAPS *caps ;
ILDVModifImg *IModifImg = ldv->IModifImg ;
LDV_IMAGE *ldv_img, img_sel, out ;
LDV_STATUS err ;
size_t t0, t00 ;
int img_format ;
if ( IModifImg == NULL ) return( ELDV_BADINTERFACE ) ;
if ( preview ) perfs = NULL ;
if ( perfs ) t00 = clock() ;
ldv_img = pldv_img ;
memcpy( &ldv_params, pldv_params, sizeof(LDV_PARAMS) ) ;
caps = LDVGetNPlanesCaps( ldv, ldv_img->Raster.fd_nplanes ) ;
if ( caps == NULL ) return( ELDV_NBPLANESNOTSUPPORTED ) ;
if (
( ( ldv_params.x1 != 0 ) || ( ldv_params.y1 != 0 ) ||
( ldv_params.x2 != ldv_img->Raster.fd_w -1 ) || ( ldv_params.y2 != ldv_img->Raster.fd_h -1 )
) &&
( caps->Flags & LDVF_NOSELECTION )
)
{
int xy[8] ;
/* Dupliquer la selection, le LDV ne peut pas travailler sur une partie d'image */
memcpy( &img_sel, ldv_img, sizeof(LDV_IMAGE) ) ;
img_sel.Raster.fd_w = 1 + ldv_params.x2 - ldv_params.x1 ;
img_sel.Raster.fd_h = 1 + ldv_params.y2 - ldv_params.y1 ;
RaRasterAlloc( &img_sel.Raster ) ;
if ( img_sel.Raster.fd_addr == NULL ) return( ELDV_NOTENOUGHMEMORY ) ;
xy[0] = ldv_params.x1 ; xy[1] = ldv_params.y1 ;
xy[2] = ldv_params.x2 ; xy[3] = ldv_params.y2 ;
xy[4] = xy[5] = 0 ;
xy[6] = img_sel.Raster.fd_w - 1 ;
xy[7] = img_sel.Raster.fd_h - 1 ;
vro_cpyfm( handle, S_ONLY, xy, &ldv_img->Raster, &img_sel.Raster ) ;
ldv_img = &img_sel ;
ldv_params.x1 = ldv_params.y1 = 0 ;
ldv_params.x2 = img_sel.Raster.fd_w - 1 ;
ldv_params.y2 = img_sel.Raster.fd_h - 1 ;
}
else memset( &img_sel, 0, sizeof(LDV_IMAGE) ) ;
if ( perfs ) t0 = clock() ;
img_format = GetBestImgFormat( caps ) ;
err = FormatLdvImgFromSpec( ldv_img, img_format ) ;
if ( perfs ) perfs->pre_ldv_ms = (1000L * (clock() - t0) ) / CLK_TCK ;
if ( !LDV_SUCCESS( err ) ) return( err ) ;
memset( &out, 0, sizeof(LDV_IMAGE) ) ;
out.Raster.fd_nplanes = caps->NbPlanesOut ;
out.RasterFormat = img_format ;
if ( perfs ) t0 = clock() ;
err = IModifImg->PreRun( ldv_img, &ldv_params, &out ) ;
if ( perfs )
{
perfs->prerun_ms = (1000L * (clock() - t0) ) / CLK_TCK ;
t0 = clock() ;
}
if ( LDV_SUCCESS( err ) )
{
if ( caps->Flags & LDVF_OPINPLACE )
{
memcpy( &out, ldv_img, sizeof(LDV_IMAGE) ) ;
out.Raster.fd_nplanes = caps->NbPlanesOut ;
}
else
{
err = LDVAlloc( &out ) ;
if ( !LDV_SUCCESS( err ) ) RaRasterFree( &img_sel.Raster ) ;
}
}
if ( perfs ) perfs->pre_ldv_ms += (1000L * (clock() - t0) ) / CLK_TCK ;
if ( LDV_SUCCESS( err ) )
{
#if !defined(__NO_LOGGING)
int perf2log = ( LoggingGetLevel() >= LL_PERF ) ;
if (perf2log)
{
char tmp[300], buf[100] ;
int n ;
sprintf(tmp, "Running LDV with w=%d, h=%d", out.Raster.fd_w, out.Raster.fd_h) ;
for (n=0; n < ldv_params.NbParams; n++ )
{
sprintf(buf, ", P%d=%d", n, ldv_params.Param[n].s) ;
strcat(tmp, buf) ;
}
LoggingDo(LL_DEBUG, tmp) ;
}
#endif
if ( preview )
{
#if !defined(__NO_LOGGING)
if (perf2log) t0 = clock() ;
#endif
if ( IModifImg->Preview ) err = IModifImg->Preview( ldv_img, &ldv_params, &out ) ;
else err = ELDV_PREVIEWNOTSUPPORTED ;
#if !defined(__NO_LOGGING)
if (perf2log)
LoggingDo(LL_PERF, "LDV Preview took %ldms", (1000L * (clock() - t0) ) / CLK_TCK) ;
#endif
}
else
{
if ( IModifImg->Run )
{
int nflags ;
if ( caps->Flags & LDVF_SUPPORTCANCEL ) nflags = 0 ;
else nflags = CLOSER ; /* Pas d'annulation possible par defaut */
if ( ( caps->Flags & LDVF_SUPPORTPROG ) && ( LdvProg == NULL ) )
LdvProg = DisplayStdProg( "", "", "", nflags ) ;
if ( LdvProg ) GWSetWindowCaption( LdvProg, "LDV ..." ) ;
if ( perfs ) t0 = clock() ;
#if !defined(__NO_LOGGING)
if ( perf2log ) t0 = clock() ;
#endif
err = IModifImg->Run( ldv_img, &ldv_params, &out ) ;
if ( perfs ) perfs->run_ms = (1000L * (clock() - t0) ) / CLK_TCK ;
#if !defined(__NO_LOGGING)
if (perf2log)
LoggingDo(LL_PERF, "LDV Run took %ldms", (1000L * (clock() - t0) ) / CLK_TCK) ;
#endif
if ( ( caps->Flags & LDVF_SUPPORTPROG ) && LdvProg )
GWDestroyWindow( LdvProg ) ;
LdvProg = NULL ;
}
else
err = ELDV_RUNNOTSUPPORTED ;
}
if ( LDV_SUCCESS( err ) )
{
if ( perfs ) t0 = clock() ;
err = FormatLdvImgToSpec( &out ) ;
if ( LDV_SUCCESS( err ) )
{
if ( img_sel.Raster.fd_addr )
{
int xy[8] ;
int xs0, ys0, xd0, yd0, ws, hs, wd, hd, w, h ;
int mode = S_ONLY ;
if (mode_vswr == MD_TRANS) mode = S_OR_D ;
else if (mode_vswr == MD_XOR) mode = S_XOR_D ;
else if (mode_vswr == MD_ERASE) mode = NOTS_AND_D ;
/* Replacer la selection dupliquee */
/* Centrer le resultat sur le centre du bloc d'origine */
wd = 1 + pldv_params->x2 - pldv_params->x1 ;
hd = 1 + pldv_params->y2 - pldv_params->y1 ;
ws = out.Raster.fd_w ;
hs = out.Raster.fd_h ;
if ( ws > wd )
{
w = wd ;
xs0 = ( ws - w ) / 2 ;
xd0 = 0 ;
}
else
{
w = ws ;
xs0 = 0 ;
xd0 = ( wd - w ) / 2 ;
}
if ( hs > hd )
{
h = hd ;
ys0 = ( hs - h ) / 2 ;
yd0 = 0 ;
}
else
{
h = hs ;
ys0 = 0 ;
yd0 = ( hd - h ) / 2 ;
}
xy[0] = xs0 ;
xy[1] = ys0 ;
xy[2] = xy[0] + w - 1 ;
xy[3] = xy[1] + h - 1 ;
xy[4] = pldv_params->x1 + xd0 ;
xy[5] = pldv_params->y1 + yd0 ;
xy[6] = xy[4] + w - 1 ;
xy[7] = xy[5] + h - 1 ;
vro_cpyfm( handle, mode, xy, &out.Raster, &pldv_img->Raster ) ;
RaRasterFree( &img_sel.Raster ) ;
if ( ( caps->Flags & LDVF_OPINPLACE ) == 0 ) Xfree( out.Raster.fd_addr ) ;
}
else
{
if ( ( caps->Flags & LDVF_OPINPLACE ) == 0 ) Xfree( ldv_img->Raster.fd_addr ) ;
memcpy( &ldv_img->Raster, &out.Raster, sizeof(MFDB) ) ;
}
}
if ( perfs ) perfs->post_ldv_ms = (1000L * (clock() - t0) ) / CLK_TCK ;
}
else
{
if ( ( caps->Flags & LDVF_OPINPLACE ) == 0 ) Xfree( out.Raster.fd_addr ) ;
if ( out.Palette.Pal ) Xfree( out.Palette.Pal ) ;
}
}
if ( perfs ) perfs->total_ms = (1000L * (clock() - t00) ) / CLK_TCK ;
/* Run peut avoir modifie les valeurs des parametres */
memcpy( &pldv_params->Param[0], &ldv_params.Param[0], LDVNBMAX_PARAMETERS*sizeof(LDV_BASICPARAM) ) ;
return( err ) ;
}