From 7b358424ebad9349421acd533c2fa1cbf6cf3e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 28 Dec 2016 16:52:56 +0100 Subject: Initial import of xtrkcad version 1:4.0.2-2 --- app/help/mkshg.c | 455 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 455 insertions(+) create mode 100644 app/help/mkshg.c (limited to 'app/help/mkshg.c') diff --git a/app/help/mkshg.c b/app/help/mkshg.c new file mode 100644 index 0000000..4c708fa --- /dev/null +++ b/app/help/mkshg.c @@ -0,0 +1,455 @@ +#include +#include +#include "readpng.h" + +#define PROGNAME "mkshg" + + +int verbose = 0; +int dmpcolortab = 0; +int dmpimage = 0; + +#define MAXRUNLEN (2) + +typedef struct { + unsigned char id0, id1, id2; + unsigned short x, y, w, h; + long hash; + char * name; + char * context; + } hotspot_t; + +int samecolor( long color1, long color2 ) +{ + long c1, c2; + int i; + for ( i=0; i<3; i++ ) { + c1 = (color1&0xFF); + c2 = (color2&0xFF); + if ( c1 != c2 ) { + if ( c1 == 0xFF || c2 == 0xFF ) return FALSE; + c1 = (c1+1)&0xFE; + c2 = (c2+1)&0xFE; + if ( c1 != c2 ) return FALSE; + } + color1 >>= 8; + color2 >>= 8; + } + return TRUE; +} + +void conv24to8( long * colorTab, char * buff, unsigned long channels, unsigned long width24, unsigned long width8, unsigned long height ) +{ + long * lastColor, *cp; + long color; + char * ip; + char *op; + unsigned long h, w; + memset( colorTab, 0, 1024 ); + lastColor = colorTab; + *lastColor++ = 0xC0C0C0; + *lastColor++ = 0xFFFFFF; + *lastColor++ = 0x808080; + *lastColor++ = 0x000000; + op = buff; + for (h=0; h MAXRUNLEN || runlen == 0 ) { + while ( norunlen > 0 ) { + if ( norunlen > 0x7F ) + chunk = 0x7F; + else + chunk = norunlen; + *op++ = 0x80|chunk; + memcpy( op, ip-norunlen, chunk ); + op += chunk; + norunlen -= chunk; + } + while ( runlen > MAXRUNLEN ) { + if ( runlen > 0x7F ) + chunk = 0x7F; + else + chunk = runlen; + *op++ = chunk; + *op++ = *ip; + ip += chunk; + runlen -= chunk; + } + } else { + norunlen += runlen; + ip += runlen; + } + } + *osize = op-op0; +} + + +void writeculong( FILE * shgF, unsigned long value ) +{ + unsigned short tmp; + if ( value > 0x7FFF ) { + tmp = (unsigned short)((value&0x7FFF)<<1)+1; + fwrite( &tmp, 2, 1, shgF ); + tmp = (unsigned short)(value>>15); + fwrite( &tmp, 2, 1, shgF ); + } else { + tmp = (unsigned short)(value<<1); + fwrite( &tmp, 2, 1, shgF ); + } +} + +void writecushort( FILE * shgF, unsigned short value ) +{ + unsigned char tmp; + if ( value > 0x7F ) { + tmp = (unsigned short)((value&0x7F)<<1)+1; + fwrite( &tmp, 1, 1, shgF ); + tmp = (unsigned short)(value>>7); + fwrite( &tmp, 1, 1, shgF ); + } else { + tmp = (unsigned short)(value<<1); + fwrite( &tmp, 1, 1, shgF ); + } +} + +void writeShgPic( + FILE * shgF, + unsigned long width, + unsigned long width8, + unsigned long height, + long colorTab[256], + unsigned char * data, + unsigned short hotspotcnt, + hotspot_t * hotspots ) +{ + short int pictype, packmethod; + unsigned long xdpi, ydpi, colorsused, colorsimportant, compressedsize, hotspotsize, compressoffset, hotspotoffset; + unsigned short planes, bitcount; + unsigned char * compressed_data; + unsigned int start_off, offset_off, off; + unsigned short inx; + unsigned char one = 1; + unsigned long macrosize = 0; + + pictype = 6; + packmethod = 1; + xdpi = ydpi = 96; + planes = 1; + bitcount = 8; + colorsused = 256; + colorsimportant = 256; + hotspotsize = (hotspotcnt?7:0); + hotspotoffset = 0; + compressed_data = (unsigned char *)malloc( width8*height ); + compress_data( data, width8*height, compressed_data, &compressedsize ); + for ( inx=0; inx0 ) { + hotspotoffset = ftell( shgF ) - start_off; + fwrite( &one, 1, 1, shgF ); + fwrite( &hotspotcnt, 2, 1, shgF ); + fwrite( ¯osize, 4, 1, shgF ); + for ( inx=0; inx 0 ) { + if ( x < 0 ) + x = ((int)hs_p[hs_c-1].x) - x; + if ( y < 0 ) + y = ((int)hs_p[hs_c-1].y) - y; + } + hs.x = (unsigned short)x; + hs.y = (unsigned short)y; + if ( rc != 5 ) + fprintf( stderr, "Invalid hotspot syntax: %s", line ); + if ( strcasecmp( type, "jump" ) == 0 ) { + hs.id0 = 0xe7; + hs.id1 = 0x04; + hs.id2 = 0x00; + } else if ( strcasecmp( type, "popup" ) == 0 ) { + hs.id0 = 0xe6; + hs.id1 = 0x04; + hs.id2 = 0x00; + } else if ( strcasecmp( type, "ignore" ) == 0 ) { + continue; + } else { + fprintf( stderr, "Invalid hotspot type: %s", line ); + continue; + } + sprintf( name, "Hotspot %d", hs_c+1 ); + hs.name = strdup( name ); + context = line+off; + off = strlen( context ); + if ( context[off-1] == '\n' ) context[off-1] = 0; + hs.context = strdup( context ); + for (hs.hash=0; *context; context++ ) + hs.hash = (hs.hash*43)+hashTable[(unsigned char)*context]; + hs_c++; + hs_p = (hotspot_t*)realloc( hs_p, hs_c * sizeof hs ); + hs_p[hs_c-1] = hs; + } + *hotspotcnt = hs_c; + *hotspotptr = hs_p; +} + + +void PngToShg( + char * pngFile, + char * shgFile ) +{ + FILE * pngF, * shgF; + int rc; + unsigned long image_width, image_height, image_rowbytes, width8, h; + int image_channels; + unsigned char * image_data; + double display_exponent = 1.0; + + long size, fileSize, maxRecSize; + long colorTab[256]; + + short int magic; + short int piccnt; + long int picoff[1]; + + unsigned short hotspotcnt; + hotspot_t * hotspotptr; + + pngF = fopen( pngFile, "r" ); + if ( pngF == NULL ) { + perror( pngFile ); + return; + } + shgF = fopen( shgFile, "w" ); + if ( shgF == NULL ) { + perror( shgFile ); + return; + } + if ((rc = readpng_init(pngF, &image_width, &image_height)) != 0) { + switch (rc) { + case 1: + fprintf(stderr, PROGNAME + ": [%s] is not a PNG file: incorrect signature\n", + pngFile); + break; + case 2: + fprintf(stderr, PROGNAME + ": [%s] has bad IHDR (libpng longjmp)\n", + pngFile); + break; + case 4: + fprintf(stderr, PROGNAME ": insufficient memory\n"); + break; + default: + fprintf(stderr, PROGNAME + ": unknown readpng_init() error\n"); + break; + } + return; + } + + image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes); + width8 = ((image_width+3)/4)*4; + size = width8*image_height; + fileSize = (size+1024)/2 + 70; + maxRecSize = (size+1024)/2 + 34; + + conv24to8( colorTab, image_data, image_channels, image_width*image_channels, width8, image_height ); + + magic = 0x706c; + piccnt = 1; + picoff[0] = 8; + fwrite( &magic, 2, 1, shgF ); + fwrite( &piccnt, 2, 1, shgF ); + fwrite( picoff, 4, piccnt, shgF ); + readHotspots( stdin, &hotspotcnt, &hotspotptr ); + writeShgPic( shgF, image_width, width8, image_height, colorTab, image_data, hotspotcnt, hotspotptr ); + if ( hotspotptr ) + free( hotspotptr ); + + readpng_cleanup(FALSE); + fclose( pngF ); + fclose( shgF ); + free( image_data ); + +} + +int main( argc, argv ) +int argc; char * argv[]; +{ + while ( argc > 1 && argv[1][0] == '-' ) { + switch ( argv[1][1] ) { + case 'v': + verbose++; + break; + case 'c': + dmpcolortab++; + break; + case 'i': + dmpimage++; + break; + default: + fprintf( stderr, "Unknown option: %s\n", argv[1] ); + exit(1); + } + argv++; + argc--; + } + if ( argc != 3 ) { + fprintf( stderr, "Usage: mkshg [-v] [-c] infile.png outfile.shg\n" ); + exit(1); + } + + PngToShg( argv[1], argv[2] ); +} -- cgit v1.2.3