automatic commit - 25-11-2022

This commit is contained in:
firebee
2022-11-25 03:00:01 +01:00
parent 8363fcee3f
commit 87010339e0
355 changed files with 8487 additions and 3317 deletions

View File

@@ -0,0 +1,856 @@
#define PCGEMLIB 1 /* Set to 1 if PureC is used */
#if PCGEMLIB
#include <aes.h>
#include <vdi.h>
#else
#include <aesbind.h>
#include <vdibind.h>
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "..\..\ldg.h"
#include "..\..\vapi.h"
#include "..\..\ldv.h"
/* Prototypes */
LDV_INFOS* cdecl GetLDVCapabilities(VAPI* vapi) ;
LDV_STATUS cdecl PreRun(LDV_IMAGE* in, LDV_PARAMS* params, LDV_IMAGE* out) ;
LDV_STATUS cdecl Run(LDV_IMAGE* in, LDV_PARAMS* params, LDV_IMAGE* out) ;
/* Global variables */
PROC Proc[] = {
"GetLDVCapabilities", "LDV capabilities", (void*)GetLDVCapabilities,
"PreRun", "Run initialization", (void*)PreRun,
"Run", "LDV operation", (void*)Run,
} ;
char Info[] = "LDV" ;
LDGLIB Ldg[] = {
0x0107, /* Lib version */
3, /* Number of functions in lib */
Proc, /* Pointers to our functions */
Info, /* Lib information */
0x0, /* Lib flags */
NULL, /* On exit, free VDI handle (unused) */
} ;
#define CAPS (LDVF_ATARIFORMAT | LDVF_SUPPORTPROG | LDVF_OPINPLACE | LDVF_SUPPORTCANCEL | LDVF_NOSELECTION | LDVF_NOCHANGE)
LDV_INFOS LdvInfos = {
(short) sizeof(LDV_INFOS), /* size of this structure */
TLDV_MODIFYIMG, /* LDV Type */
"Jean Lusetti/Seedy", /* Authors */
{
{ 1, 1, CAPS }, /* 1 bitplane capabilities */
{ 2, 2, CAPS }, /* 2 bitplane capabilities */
{ 4, 4, CAPS }, /* 4 bitplane capabilities */
{ 8, 8, CAPS }, /* 8 bitplane capabilities */
{ 16, 16, CAPS }, /* 16 bitplane capabilities */
/* Not yet { 24, 24, CAPS }, */
{ 32, 32, CAPS }, /* 32 bitplane capabilities */
{ 0, 0, 0UL } /* End of this list */
},
} ;
VAPI* Vapi = NULL ;
unsigned char VapiLog = 0 ;
unsigned char UseVAlloc ; /* Use VISION's allocation routines if possible */
unsigned char NbBitsIn[256] ; /* Number of bits set to 1 for every integer in [0;255] */
typedef struct _CNTCOL_DATA
{
/* Input data */
LDV_IMAGE* in ;
LDV_PARAMS* params ;
FILE* report_file ;
short method ; /* 0: auto, 1: bit array of colors, 2: sorted colors */
}
CNTCOL_DATA, *PCNTCOL_DATA ;
typedef struct _CC1_CONTEXT
{
void* line_colors ;
unsigned long so_line_colors ;
unsigned char* unique_colors_bits ;
unsigned long so_unique_colors_bits ;
short nplanes ;
unsigned char* indexes ; /* Allocated only if nplanes <= 8 */
unsigned long so_indexes ;
unsigned long used_bytes ;
}
CC1_CONTEXT, *PCC1_CONTEXT ;
typedef struct _CC2_CONTEXT
{
unsigned char* line_sorted ;
unsigned char* img_sorted ;
unsigned long nb_img_colors ;
unsigned long nb_img_colors_max ;
short nplanes ;
unsigned char* indexes ; /* Allocated only if nplanes <= 8 */
unsigned long so_indexes ;
unsigned long used_bytes ;
}
CC2_CONTEXT, *PCC2_CONTEXT ;
typedef struct _CC3_CONTEXT
{
unsigned char* line_sorted ;
unsigned long so_line_colors ;
unsigned char* unique_colors_bits ;
unsigned long so_unique_colors_bits ;
short nplanes ;
unsigned char* indexes ; /* Allocated only if nplanes <= 8 */
unsigned long so_indexes ;
unsigned long used_bytes ;
}
CC3_CONTEXT, *PCC3_CONTEXT ;
typedef union _CC_CONTEXT
{
/* Specific data for each method */
CC1_CONTEXT c1 ; /* color table for a line and bitcolor array globally */
CC2_CONTEXT c2 ; /* sort/reduce each line and globally */
CC3_CONTEXT c3 ; /* sort/reduce each line and bitcolor array globally */
}
CC_CONTEXT, *PCC_CONTEXT ;
typedef struct _CC_INTERFACE
{
LDV_STATUS (*Init)(CC_CONTEXT* vc, CNTCOL_DATA* data) ;
unsigned long (*CountColors)(CC_CONTEXT* vc, void* addr, unsigned long so_line) ;
unsigned long (*CountColorsEnd)(CC_CONTEXT* vc) ;
unsigned long (*Exit)(CC_CONTEXT* vc) ;
}
CC_INTERFACE, *PCC_INTERFACE ;
/* Helper function to call best progress routine depending on VAPI progress function availability */
/* Return value: */
/* 1: Cencel requested by user */
/* 0: Progress update done */
/* -1: Progress update not made to screen () */
static short Prog(long current, long max)
{
short status = 0 ;
if ( Vapi->PrSetProgRange ) status = (short) Vapi->PrSetProgRange( current, max ) ;
else if ( max && ( ( current & 0x0F ) == 0 ) )
{
short pc ;
/* Call progress routine only once on 16 */
pc = (short) ( ( 100L * ( current - max ) ) / max ) ;
if ( Vapi->PrSetProgEx ) status = Vapi->PrSetProgEx( pc ) ;
else Vapi->PrSetProg( pc ) ;
}
return status ;
}
/* Wrappers to abstract dynamic allocation routines */
static void* localCalloc(unsigned long size)
{
void* p ;
if ( UseVAlloc ) p = Vapi->MeXcalloc( 1, size ) ;
else p = calloc( 1, size ) ;
return p ;
}
static void* localAlloc(unsigned long size)
{
void* p ;
if ( UseVAlloc ) p = Vapi->MeXalloc( size ) ;
else p = malloc( size ) ;
return p ;
}
static void localFree(void* p)
{
if ( p )
{
if ( UseVAlloc ) Vapi->MeXfree( p ) ;
else free( p ) ;
}
}
LDV_INFOS* cdecl GetLDVCapabilities(VAPI* vapi)
{
Vapi = vapi ;
VapiLog = Vapi && Vapi->LoDoLog ;
return( &LdvInfos ) ;
}
#pragma warn -par
LDV_STATUS cdecl PreRun(LDV_IMAGE* in, LDV_PARAMS* params, LDV_IMAGE* out)
{
return ELDV_NOERROR ;
}
#pragma warn +par
static FILE* CreateReportFile(CNTCOL_DATA* data)
{
FILE* stream ;
char* filename ;
if ( data->params->Param[1].str ) filename = data->params->Param[1].str ;
else filename = "cntcol.txt" ;
stream = fopen( filename, "wb" ) ;
if ( VapiLog )
{
if ( stream ) Vapi->LoDoLog(LL_INFO, "cntcol.ldv will generate report file %s", filename) ;
else Vapi->LoDoLog(LL_ERROR, "cntcol.ldv failed to create report file %s", filename) ;
}
if ( stream )
{
fprintf( stream, "cntcol LDV running on image %dx%d, %d bitplanes:\r\n", data->in->Raster.fd_w, data->in->Raster.fd_h, data->in->Raster.fd_nplanes ) ;
fprintf( stream, "-------|--------------------\r\n" ) ;
fprintf( stream, "| Line | # unique colors |\r\n" ) ;
}
return stream ;
}
static unsigned long CountBits(unsigned char* pt, unsigned long nb_bytes)
{
unsigned char* p = pt ;
unsigned long nb_bits = 0 ;
while ( p < pt+nb_bytes )
{
nb_bits += NbBitsIn[*p] ;
p++ ;
}
return nb_bits ;
}
static LDV_STATUS check_prog(short y, short ymax, unsigned long nb_unique_colors_on_line)
{
short status ;
status = Prog( y, ymax ) ;
if ( status == 0 ) /* GUI updated */
{
if ( Vapi->PrSetText )
{
char buf[128] ;
sprintf( buf, "%lu unique colors on line %d", nb_unique_colors_on_line, y ) ;
Vapi->PrSetText( 1, buf ) ;
}
}
return LDVPROG_CANCEL( status ) ? ELDV_CANCELLED:ELDV_NOERROR ;
}
static short add_pixel_if_not_present16(unsigned short pixel, unsigned short* line_colors, unsigned long nb_colors)
{
unsigned long i ;
for ( i = 0; i < nb_colors; i++ )
if ( line_colors[i] == pixel ) break ;
if ( i == nb_colors ) { line_colors[nb_colors++] = pixel ; return 1 ; }
return 0 ;
}
static short add_pixel_if_not_present32(unsigned long pixel, unsigned long* line_colors, unsigned long nb_colors)
{
unsigned long i ;
for ( i = 0; i < nb_colors; i++ )
if ( line_colors[i] == pixel ) break ;
if ( i == nb_colors ) { line_colors[nb_colors++] = pixel ; return 1 ; }
return 0 ;
}
static unsigned long CC1(CC_CONTEXT* vc, void* addr, unsigned long so_line)
{
CC1_CONTEXT* c = (CC1_CONTEXT*) &vc->c1 ;
unsigned char* line = (unsigned char*) addr ;
unsigned long offset, nb_colors = 0 ;
unsigned short bit ;
if ( c->nplanes <= 8 ) /* Bit planes */
{
unsigned char unique_colors_bits_line[256/8] ; /* 256 bits --> 256/8 bytes */
unsigned short x ;
memset( unique_colors_bits_line, 0, sizeof(unique_colors_bits_line) ) ;
Vapi->RaRaster2Ind( addr, c->so_indexes, c->nplanes, c->indexes ) ;
for ( x = 0; x < c->so_indexes; x++ )
{
bit = c->indexes[x] & 0x07 ;
offset = c->indexes[x] >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
unique_colors_bits_line[offset] |= (1 << bit) ;
}
nb_colors = CountBits( unique_colors_bits_line, sizeof(unique_colors_bits_line) ) ;
}
else if ( c->nplanes == 16 ) /* TC16 */
{
unsigned short* p ;
unsigned short pixel ;
for ( p = (unsigned short*)line; p < (unsigned short*) (line+so_line); p++ )
{
pixel = *p ;
nb_colors += add_pixel_if_not_present16( pixel, c->line_colors, nb_colors ) ;
bit = pixel & 0x07 ;
offset = pixel >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
}
}
else if ( c->nplanes == 32 ) /* TC32 */
{
unsigned char* p ;
unsigned long pixel ;
for ( p = line; p < line+so_line; p += 4 )
{
pixel = p[0] ;
pixel |= ( (unsigned long)p[1] << 8 ) ;
pixel |= ( (unsigned long)p[2] << 16 ) ;
nb_colors += add_pixel_if_not_present32( pixel, c->line_colors, nb_colors ) ;
bit = (unsigned short)pixel & 0x07 ;
offset = pixel >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
}
}
return nb_colors ;
}
static unsigned long CC1Exit(CC_CONTEXT* vc)
{
CC1_CONTEXT* c = &vc->c1 ;
localFree( c->unique_colors_bits ) ;
localFree( c->line_colors ) ;
localFree( c->indexes ) ;
return c->used_bytes ;
}
static unsigned long Getso_unique_colors_bits(MFDB* img)
{
unsigned long so_unique_colors_bits ;
if ( img->fd_nplanes > 8 )
{
if ( img->fd_nplanes == 16 ) so_unique_colors_bits = 1UL << 16 ;
else so_unique_colors_bits = 1UL << 24 ; /* TC24 or TC32 */
}
else so_unique_colors_bits = 256 ;
so_unique_colors_bits >>= 3 ; /* #bits --> #bytes */
if ( so_unique_colors_bits == 0 ) so_unique_colors_bits = 1 ;
return so_unique_colors_bits ;
}
static LDV_STATUS CC1Init(CC_CONTEXT* vc, CNTCOL_DATA* data)
{
MFDB* img = &data->in->Raster ;
CC1_CONTEXT* c = &vc->c1 ;
memset( c, 0, sizeof(*c) ) ;
c->nplanes = img->fd_nplanes ;
if ( img->fd_nplanes > 8 )
{
/* True Color */
/* Size of bit array for each unique color depending on the number of planes */
c->so_line_colors = Vapi->RaGetImgSize( img->fd_w, 1, img->fd_nplanes ) ;
c->line_colors = localAlloc( c->so_line_colors ) ;
if ( c->line_colors == NULL ) return ELDV_NOTENOUGHMEMORY ;
}
else
{
/* Bit planes */
c->so_indexes = 16*img->fd_wdwidth ; /* Max for 8 planes */
c->indexes = (unsigned char*) localAlloc( c->so_indexes ) ;
c->so_line_colors = 0 ;
if ( c->indexes == NULL ) return ELDV_NOTENOUGHMEMORY ;
}
c->so_unique_colors_bits = Getso_unique_colors_bits( img ) ;
c->unique_colors_bits = localCalloc( c->so_unique_colors_bits ) ;
if ( c->unique_colors_bits == NULL ) { CC1Exit( vc ) ; return ELDV_NOTENOUGHMEMORY ; }
c->used_bytes = c->so_unique_colors_bits + c->so_line_colors + c->so_indexes ;
return ELDV_NOERROR ;
}
static unsigned long CC1End(CC_CONTEXT* vc)
{
CC1_CONTEXT* c = &vc->c1 ;
return CountBits( c->unique_colors_bits, c->so_unique_colors_bits ) ;
}
static int cmp8(const void* a, const void* b)
{
unsigned char* e1 = (unsigned char*) a ;
unsigned char* e2 = (unsigned char*) b ;
return (int)( *e1 - *e2 ) ;
}
static int cmp16(const void* a, const void* b)
{
unsigned short* e1 = (unsigned short*) a ;
unsigned short* e2 = (unsigned short*) b ;
return ( *e1 - *e2 ) ;
}
static int cmp32(const void* a, const void* b)
{
unsigned long* e1 = (unsigned long*) a ;
unsigned long* e2 = (unsigned long*) b ;
if ( *e1 < *e2 ) return -1 ;
if ( *e1 == *e2 ) return 0 ;
return 1 ;
}
static unsigned long reduce8(unsigned char* array, unsigned long nb_items)
{
unsigned long nb_unique = 0 ;
unsigned char* pread ;
unsigned char* pwrite ;
unsigned char val ;
pread = pwrite = array ;
while ( pread < array + nb_items )
{
val = *pread++ ;
while ( (pread < array + nb_items) && (*pread == val) ) pread++ ;
nb_unique++ ;
*pwrite++ = val ;
}
return nb_unique ;
}
static unsigned long reduce16(unsigned short* array, unsigned long nb_items)
{
unsigned long nb_unique = 0 ;
unsigned short* pread ;
unsigned short* pwrite ;
unsigned short val ;
pread = pwrite = array ;
while ( pread < array + nb_items )
{
val = *pread++ ;
while ( (pread < array + nb_items) && (*pread == val) ) pread++ ;
nb_unique++ ;
*pwrite++ = val ;
}
return nb_unique ;
}
static unsigned long reduce32(unsigned long* array, unsigned long nb_items)
{
unsigned long nb_unique = 0 ;
unsigned long* pread ;
unsigned long* pwrite ;
unsigned long val ;
pread = pwrite = array ;
while ( pread < array + nb_items )
{
val = *pread++ ;
while ( (pread < array + nb_items) && (*pread == val) ) pread++ ;
nb_unique++ ;
*pwrite++ = val ;
}
return nb_unique ;
}
static unsigned long CC2(CC_CONTEXT* vc, void* addr, unsigned long so_line)
{
CC2_CONTEXT* c = (CC2_CONTEXT*) &vc->c2 ;
unsigned long nb_colors = 0 ;
if ( c->nplanes <= 8 ) /* Bit planes */
{
Vapi->RaRaster2Ind( addr, c->so_indexes, c->nplanes, c->indexes ) ;
qsort( c->indexes, c->so_indexes, sizeof(unsigned char), cmp8 ) ;
nb_colors = reduce8( c->indexes, c->so_indexes ) ;
/* Add new line of unique colors to current image unique colors */
memmove( c->img_sorted + c->nb_img_colors, c->indexes, nb_colors*sizeof(unsigned char) ) ;
c->nb_img_colors += nb_colors ;
}
else if ( c->nplanes == 16 ) /* TC16 */
{
memmove( c->line_sorted, addr, so_line ) ;
qsort( c->line_sorted, so_line >> 1, sizeof(unsigned short), cmp16 ) ;
nb_colors = reduce16( (unsigned short*) c->line_sorted, so_line >> 1 ) ;
/* Add new line of unique colors to current image unique colors */
memmove( c->img_sorted + 2*c->nb_img_colors, c->line_sorted, nb_colors*sizeof(unsigned short) ) ;
c->nb_img_colors += nb_colors ;
}
else if ( c->nplanes == 32 ) /* TC32 */
{
memmove( c->line_sorted, addr, so_line ) ;
qsort( c->line_sorted, so_line >> 2, sizeof(unsigned long), cmp32 ) ;
nb_colors = reduce32( (unsigned long*) c->line_sorted, so_line >> 2 ) ;
/* Add new line of unique colors to current image unique colors */
memmove( c->img_sorted + 4*c->nb_img_colors, c->line_sorted, nb_colors*sizeof(unsigned long) ) ;
c->nb_img_colors += nb_colors ;
}
return nb_colors ;
}
static unsigned long CC2Exit(CC_CONTEXT* vc)
{
CC2_CONTEXT* c = &vc->c2 ;
localFree( c->indexes ) ;
localFree( c->img_sorted ) ;
localFree( c->line_sorted ) ;
return c->used_bytes ;
}
static LDV_STATUS CC2Init(CC_CONTEXT* vc, CNTCOL_DATA* data)
{
MFDB* img = &data->in->Raster ;
CC2_CONTEXT* c = &vc->c2 ;
short pixel_in_bytes ;
memset( c, 0, sizeof(*c) ) ;
c->nplanes = img->fd_nplanes ;
/* Use VISION's checked allocation routine for safety as VISION performs bounduary checks */
/* Allocate memory to duplicate a line and sort it out */
if ( img->fd_nplanes > 8 )
{
c->line_sorted = (unsigned char*) localAlloc( Vapi->RaGetImgSize( img->fd_w, 1, img->fd_nplanes ) ) ;
if ( c->line_sorted == NULL ) return ELDV_NOTENOUGHMEMORY ;
if ( img->fd_nplanes == 16 ) pixel_in_bytes = 2 ;
else pixel_in_bytes = 4 ;
}
else
{
/* Bit planes: we need an index array */
c->so_indexes = 16*img->fd_wdwidth ; /* Max for 8 planes */
c->indexes = (unsigned char*) localAlloc( c->so_indexes ) ;
if ( c->indexes == NULL ) { CC2Exit( vc ) ; return ELDV_NOTENOUGHMEMORY ; }
pixel_in_bytes = 1 ;
}
/* Allocate memory to store all colors used for all the image */
/* There can't be more colors than pixels in the image, so let's go with that */
c->nb_img_colors_max = (unsigned long)img->fd_w * (unsigned long)img->fd_h ;
c->img_sorted = (unsigned char*) localAlloc( c->nb_img_colors_max*pixel_in_bytes ) ;
if ( c->img_sorted == NULL ) { CC2Exit( vc ) ; return ELDV_NOTENOUGHMEMORY ; }
c->used_bytes = c->so_indexes + c->nb_img_colors_max*pixel_in_bytes ;
return ELDV_NOERROR ;
}
static unsigned long CC2End(CC_CONTEXT* vc)
{
CC2_CONTEXT* c = &vc->c2 ;
if ( c->nplanes <= 8 ) /* Bit planes */
{
/* Sort the new array */
qsort( c->img_sorted, c->nb_img_colors, sizeof(unsigned char), cmp8 ) ;
/* And reduce it */
c->nb_img_colors = reduce8( c->img_sorted, c->nb_img_colors ) ;
}
else if ( c->nplanes == 16 ) /* TC16 */
{
/* Sort the new array */
qsort( c->img_sorted, c->nb_img_colors, sizeof(unsigned short), cmp16 ) ;
/* And reduce it */
c->nb_img_colors = reduce16( (unsigned short*) c->img_sorted, c->nb_img_colors ) ;
}
else if ( c->nplanes == 32 ) /* TC32 */
{
/* Sort the new array */
qsort( c->img_sorted, c->nb_img_colors, sizeof(unsigned long), cmp32 ) ;
/* And reduce it */
c->nb_img_colors = reduce32( (unsigned long*) c->img_sorted, c->nb_img_colors ) ;
}
return c->nb_img_colors ;
}
static unsigned long CC3Exit(CC_CONTEXT* vc)
{
CC3_CONTEXT* c = &vc->c3 ;
localFree( c->unique_colors_bits ) ;
localFree( c->line_sorted ) ;
localFree( c->indexes ) ;
return c->used_bytes ;
}
static LDV_STATUS CC3Init(CC_CONTEXT* vc, CNTCOL_DATA* data)
{
MFDB* img = &data->in->Raster ;
CC3_CONTEXT* c = &vc->c3 ;
memset( c, 0, sizeof(*c) ) ;
c->nplanes = img->fd_nplanes ;
if ( img->fd_nplanes > 8 )
{
/* True Color */
/* Size of bit array for each unique color depending on the number of planes */
c->so_line_colors = Vapi->RaGetImgSize( img->fd_w, 1, img->fd_nplanes ) ;
/* Allocate memory for a line to get sorted */
c->line_sorted = localAlloc( c->so_line_colors ) ;
if ( c->line_sorted == NULL ) return ELDV_NOTENOUGHMEMORY ;
}
else
{
/* Bit planes */
c->so_indexes = 16*img->fd_wdwidth ; /* Max for 8 planes */
c->indexes = (unsigned char*) localAlloc( c->so_indexes ) ;
if ( c->indexes == NULL ) return ELDV_NOTENOUGHMEMORY ;
}
c->so_unique_colors_bits = Getso_unique_colors_bits( img ) ;
c->unique_colors_bits = localCalloc( c->so_unique_colors_bits ) ;
if ( c->unique_colors_bits == NULL ) { CC3Exit( vc ) ; return ELDV_NOTENOUGHMEMORY ; }
c->used_bytes = c->so_line_colors + c->so_indexes + c->so_unique_colors_bits ;
return ELDV_NOERROR ;
}
static unsigned long CC3End(CC_CONTEXT* vc)
{
CC3_CONTEXT* c = &vc->c3 ;
return CountBits( c->unique_colors_bits, c->so_unique_colors_bits ) ;
}
static unsigned long CC3(CC_CONTEXT* vc, void* addr, unsigned long so_line)
{
CC3_CONTEXT* c = (CC3_CONTEXT*) &vc->c3 ;
unsigned char* line = (unsigned char*) addr ;
unsigned long offset, nb_colors = 0 ;
unsigned short bit ;
if ( c->nplanes <= 8 ) /* Bit planes */
{
unsigned short x ;
/* Sort/reduce this line */
Vapi->RaRaster2Ind( addr, c->so_indexes, c->nplanes, c->indexes ) ;
qsort( c->indexes, c->so_indexes, sizeof(unsigned char), cmp8 ) ;
nb_colors = reduce8( c->indexes, c->so_indexes ) ;
/* Update global bitarray */
for ( x = 0; x < c->so_indexes; x++ )
{
bit = c->indexes[x] & 0x07 ;
offset = c->indexes[x] >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
}
}
else if ( c->nplanes == 16 ) /* TC16 */
{
unsigned short* p ;
unsigned short pixel ;
/* Sort/reduce this line */
memmove( c->line_sorted, addr, so_line ) ;
qsort( c->line_sorted, so_line >> 1, sizeof(unsigned short), cmp16 ) ;
nb_colors = reduce16( (unsigned short*) c->line_sorted, so_line >> 1 ) ;
/* Update global bitarray */
for ( p = (unsigned short*)line; p < (unsigned short*) (line+so_line); p++ )
{
pixel = *p ;
bit = pixel & 0x07 ;
offset = pixel >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
}
}
else if ( c->nplanes == 32 ) /* TC32 */
{
unsigned char* p ;
unsigned long pixel ;
/* Sort/reduce this line */
memmove( c->line_sorted, addr, so_line ) ;
qsort( c->line_sorted, so_line >> 2, sizeof(unsigned long), cmp32 ) ;
nb_colors = reduce32( (unsigned long*) c->line_sorted, so_line >> 2 ) ;
for ( p = line; p < line+so_line; p += 4 )
{
pixel = p[0] ;
pixel |= ( (unsigned long)p[1] << 8 ) ;
pixel |= ( (unsigned long)p[2] << 16 ) ;
bit = (unsigned short)pixel & 0x07 ;
offset = pixel >> 3 ;
c->unique_colors_bits[offset] |= (1 << bit) ;
}
}
return nb_colors ;
}
static LDV_STATUS LDVOperation(CNTCOL_DATA* data)
{
CC_INTERFACE cci ;
CC_CONTEXT c ;
LDV_STATUS status ;
MFDB* img = &data->in->Raster ;
unsigned char* line ;
unsigned long so_line ;
short method, l = 0 ;
unsigned long nb_unique_colors_on_line, used_ram ;
unsigned char* pt_after_img ;
so_line = Vapi->RaGetImgSize( img->fd_w, 1, img->fd_nplanes ) ;
method = data->method ;
if ( method == 0 )
{
/* Let me decide */
if ( img->fd_nplanes <= 8 ) method = 1 ; /* qsort/reduce is too costy when there are not so many colors */
else method = 3 ;
}
switch( method )
{
case 1: cci.Init = CC1Init ;
cci.CountColors = CC1 ;
cci.CountColorsEnd = CC1End ;
cci.Exit = CC1Exit ;
break ;
case 2: cci.Init = CC2Init ;
cci.CountColors = CC2 ;
cci.CountColorsEnd = CC2End ;
cci.Exit = CC2Exit ;
break ;
default: cci.Init = CC3Init ;
cci.CountColors = CC3 ;
cci.CountColorsEnd = CC3End ;
cci.Exit = CC3Exit ;
method = 3 ;
break ;
}
if ( VapiLog )
{
Vapi->LoDoLog(LL_DEBUG, "cntcol.ldv: Image is %dx%dx%d, wd_width=%d", img->fd_w, img->fd_h, img->fd_nplanes, img->fd_wdwidth ) ;
Vapi->LoDoLog(LL_DEBUG, "cntcol.ldv: using %s's memory allocation routines", UseVAlloc ? "VISION":"compiler" ) ;
Vapi->LoDoLog(LL_DEBUG, "cntcol.ldv: using method %d for counting colors", method ) ;
}
status = cci.Init( &c, data ) ;
if ( !LDV_SUCCESS( status ) ) return status ;
if ( VapiLog ) Vapi->LoDoLog(LL_DEBUG, "cntcol.ldv: init done" ) ;
line = img->fd_addr ;
pt_after_img = line + (unsigned long)img->fd_h*so_line ;
while ( LDV_SUCCESS( status ) && (line < pt_after_img) )
{
nb_unique_colors_on_line = cci.CountColors( &c, line, so_line ) ;
if ( nb_unique_colors_on_line > 0 )
{
fprintf( data->report_file, "|%6d|%17lu|\r\n", l, nb_unique_colors_on_line ) ;
line += so_line ;
status = check_prog( l++, img->fd_h, nb_unique_colors_on_line ) ;
}
else status = ELDV_NOTENOUGHMEMORY ;
}
if ( status == ELDV_CANCELLED ) fprintf( data->report_file, "---- Operation cancelled by user ----\r\n" ) ;
else if ( status == ELDV_NOTENOUGHMEMORY ) fprintf( data->report_file, "---- Not enough memory ----\r\n" ) ;
else
{
unsigned long nb_unique_colors ;
if ( VapiLog ) Vapi->LoDoLog(LL_DEBUG, "cntcol.ldv: finishing counting..." ) ;
fprintf( data->report_file, "-------|------------------\r\n" ) ;
nb_unique_colors = cci.CountColorsEnd( &c ) ;
fprintf( data->report_file, "|Total |%17lu|\r\n", nb_unique_colors ) ;
if ( VapiLog ) Vapi->LoDoLog(LL_INFO, "cntcol.ldv: %lu unique colors on image", nb_unique_colors ) ;
if ( Vapi->Header.Version >= 0x0106 )
{
/* LDV_PARAMS provides storage for returning */
/* A free text to be displayed in VISION */
if ( VapiLog ) Vapi->LoDoLog(LL_INFO, "cntcol.ldv: returning #unique colors to VISION" ) ;
sprintf( data->params->ldv_txt_out, "%lu unique colors", nb_unique_colors ) ;
}
}
fprintf( data->report_file, "-------|------------------\r\n" ) ;
used_ram = cci.Exit( &c ) ;
fprintf( data->report_file, "RAM used: %lu KB\r\n", used_ram/1024UL ) ;
return status ;
}
#pragma warn -par
LDV_STATUS cdecl Run(LDV_IMAGE* in, LDV_PARAMS* params, LDV_IMAGE* out)
{
CNTCOL_DATA data ;
LDV_STATUS status ;
clock_t t0 ;
if ( (in->RasterFormat & CAPS) == 0 ) return ELDV_IMGFORMATMISMATCH ;
UseVAlloc = Vapi && Vapi->MeXcalloc && Vapi->MeXfree ;
data.in = in ;
data.params = params ;
data.method = data.params->Param[0].s ;
data.report_file = CreateReportFile( &data ) ;
if ( data.report_file == NULL ) return ELDV_GENERALFAILURE ;
t0 = clock() ;
status = LDVOperation( &data ) ;
fprintf( data.report_file, "Computation time: %lu ms\r\n", (1000L*(clock()-t0))/CLK_TCK ) ;
fclose( data.report_file ) ;
return status ;
}
#pragma warn +par
static void init_bit_counts(void)
{
unsigned short i, mask ;
for ( i = 0; i <= 255; i++ )
for ( mask = 1; mask < 256; mask <<= 1 )
if ( i & mask ) NbBitsIn[i]++ ;
}
int main(void)
{
ldg_init( Ldg ) ;
init_bit_counts() ;
return 0 ;
}

Binary file not shown.

View File

@@ -0,0 +1,12 @@
CNTCOL.LDV
.C [ ]
.S [ ]
.L [ ]
=
pcstart.o
CNTCOL.C
pcgemlib.lib
pcstdlib.lib
pctoslib.lib
..\..\ldg.lib
..\..\mt_aes.lib