diff options
author | saurabhb17 | 2020-02-26 16:40:14 +0530 |
---|---|---|
committer | GitHub | 2020-02-26 16:40:14 +0530 |
commit | 02c614b4e64b68758f223391cb5357b3eec78cac (patch) | |
tree | ad18839d8b4eb1f13419d07878cc4ec4c9b70032 /potrace/greymap.cpp | |
parent | b77f5d9d8097c38159c6f60917995d6af13bbe1c (diff) | |
parent | 07a8c86216b6b1f694b136ec64c281d62941952e (diff) | |
download | KiCad-eSim-02c614b4e64b68758f223391cb5357b3eec78cac.tar.gz KiCad-eSim-02c614b4e64b68758f223391cb5357b3eec78cac.tar.bz2 KiCad-eSim-02c614b4e64b68758f223391cb5357b3eec78cac.zip |
Merge pull request #6 from saurabhb17/master
minor additions
Diffstat (limited to 'potrace/greymap.cpp')
-rw-r--r-- | potrace/greymap.cpp | 1108 |
1 files changed, 1108 insertions, 0 deletions
diff --git a/potrace/greymap.cpp b/potrace/greymap.cpp new file mode 100644 index 0000000..203fa1a --- /dev/null +++ b/potrace/greymap.cpp @@ -0,0 +1,1108 @@ +/* Copyright (C) 2001-2007 Peter Selinger. + * This file is part of Potrace. It is free software and it is covered + * by the GNU General Public License. See the file COPYING for details. */ + +/* $Id: greymap.c 147 2007-04-09 00:44:09Z selinger $ */ + +/* Routines for manipulating greymaps, including reading pgm files. We + * only deal with greymaps of depth 8 bits. */ + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <cmath> + +#include <greymap.h> + +#define INTBITS ( 8 * sizeof(int) ) + +#define mod( a, n ) ( (a)>=(n) ? (a) % (n) : (a)>=0 ? (a) : (n) - 1 - ( -1 - (a) ) % (n) ) + +static int gm_readbody_pnm( FILE* f, greymap_t** gmp, int magic ); +static int gm_readbody_bmp( FILE* f, greymap_t** gmp ); + +/* ---------------------------------------------------------------------- */ +/* basic greymap routines */ + +/* return new un-initialized greymap. NULL with errno on error */ + +greymap_t* gm_new( int w, int h ) +{ + greymap_t* gm; + int errno_save; + + gm = (greymap_t*) malloc( sizeof(greymap_t) ); + if( !gm ) + { + return NULL; + } + gm->w = w; + gm->h = h; + gm->map = (signed short int*) malloc( w * h * sizeof(signed short int) ); + if( !gm->map ) + { + errno_save = errno; + free( gm ); + errno = errno_save; + return NULL; + } + return gm; +} + + +/* free the given greymap */ +void gm_free( greymap_t* gm ) +{ + if( gm ) + { + free( gm->map ); + } + free( gm ); +} + + +/* duplicate the given greymap. Return NULL on error with errno set. */ +greymap_t* gm_dup( greymap_t* gm ) +{ + greymap_t* gm1 = gm_new( gm->w, gm->h ); + + if( !gm1 ) + { + return NULL; + } + memcpy( gm1->map, gm->map, gm->w * gm->h * 2 ); + return gm1; +} + + +/* clear the given greymap to color b. */ +void gm_clear( greymap_t* gm, int b ) +{ + int i; + + if( b==0 ) + { + memset( gm->map, 0, gm->w * gm->h * 2 ); + } + else + { + for( i = 0; i<gm->w * gm->h; i++ ) + { + gm->map[i] = b; + } + } +} + + +/* ---------------------------------------------------------------------- */ +/* routines for reading pnm streams */ + +/* read next character after whitespace and comments. Return EOF on + * end of file or error. */ +static int fgetc_ws( FILE* f ) +{ + int c; + + while( 1 ) + { + c = fgetc( f ); + if( c=='#' ) + { + while( 1 ) + { + c = fgetc( f ); + if( c=='\n' || c==EOF ) + { + break; + } + } + } + /* space, tab, line feed, carriage return, form-feed */ + if( c!=' ' && c!='\t' && c!='\r' && c!='\n' && c!=12 ) + { + return c; + } + } +} + + +/* skip whitespace and comments, then read a non-negative decimal + * number from a stream. Return -1 on EOF. Tolerate other errors (skip + * bad characters). Do not the read any characters following the + * number (put next character back into the stream) */ + +static int readnum( FILE* f ) +{ + int c; + int acc; + + /* skip whitespace and comments */ + while( 1 ) + { + c = fgetc_ws( f ); + if( c==EOF ) + { + return -1; + } + if( c>='0' && c<='9' ) + { + break; + } + } + + /* first digit is already in c */ + acc = c - '0'; + while( 1 ) + { + c = fgetc( f ); + if( c==EOF ) + { + break; + } + if( c<'0' || c>'9' ) + { + ungetc( c, f ); + break; + } + acc *= 10; + acc += c - '0'; + } + + return acc; +} + + +/* similar to readnum, but read only a single 0 or 1, and do not read + * any characters after it. */ + +static int readbit( FILE* f ) +{ + int c; + + /* skip whitespace and comments */ + while( 1 ) + { + c = fgetc_ws( f ); + if( c==EOF ) + { + return -1; + } + if( c>='0' && c<='1' ) + { + break; + } + } + + return c - '0'; +} + + +/* ---------------------------------------------------------------------- */ + +/* read a PNM stream: P1-P6 format (see pnm(5)), or a BMP stream, and + * convert the output to a greymap. Return greymap in *gmp. Return 0 + * on success, -1 on error with errno set, -2 on bad file format (with + * error message in gm_read_error), and 1 on premature end of file, -3 + * on empty file (including files with only whitespace and comments), + * -4 if wrong magic number. If the return value is >=0, *gmp is + * valid. */ + +const char* gm_read_error = NULL; + +int gm_read( FILE* f, greymap_t** gmp ) +{ + int magic[2]; + + /* read magic number. We ignore whitespace and comments before the + * magic, for the benefit of concatenated files in P1-P3 format. + * Multiple P1-P3 images in a single file are not formally allowed + * by the PNM standard, but there is no harm in being lenient. */ + + magic[0] = fgetc_ws( f ); + if( magic[0] == EOF ) + { + /* files which contain only comments and whitespace count as "empty" */ + return -3; + } + magic[1] = fgetc( f ); + if( magic[0] == 'P' && magic[1] >= '1' && magic[1] <= '6' ) + { + return gm_readbody_pnm( f, gmp, magic[1] ); + } + if( magic[0] == 'B' && magic[1] == 'M' ) + { + return gm_readbody_bmp( f, gmp ); + } + return -4; +} + + +/* ---------------------------------------------------------------------- */ +/* read PNM format */ + +/* read PNM stream after magic number. Return values as for gm_read */ +static int gm_readbody_pnm( FILE* f, greymap_t** gmp, int magic ) +{ + greymap_t* gm; + int x, y, i, j, b, b1, sum; + int bpr; /* bytes per row (as opposed to 4*gm->c) */ + int w, h, max; + + gm = NULL; + + w = readnum( f ); + if( w<0 ) + { + goto format_error; + } + + h = readnum( f ); + if( h<0 ) + { + goto format_error; + } + + /* allocate greymap */ + gm = gm_new( w, h ); + if( !gm ) + { + return -1; + } + + /* zero it out */ + gm_clear( gm, 0 ); + + switch( magic ) + { + default: + /* not reached */ + goto format_error; + + case '1': + /* read P1 format: PBM ascii */ + + for( y = h - 1; y>=0; y-- ) + { + for( x = 0; x<w; x++ ) + { + b = readbit( f ); + if( b<0 ) + { + goto eof; + } + GM_UPUT( gm, x, y, b ? 0 : 255 ); + } + } + + break; + + case '2': + /* read P2 format: PGM ascii */ + + max = readnum( f ); + if( max<1 ) + { + goto format_error; + } + + for( y = h - 1; y>=0; y-- ) + { + for( x = 0; x<w; x++ ) + { + b = readnum( f ); + if( b<0 ) + { + goto eof; + } + GM_UPUT( gm, x, y, b * 255 / max ); + } + } + + break; + + case '3': + /* read P3 format: PPM ascii */ + + max = readnum( f ); + if( max<1 ) + { + goto format_error; + } + + for( y = h - 1; y>=0; y-- ) + { + for( x = 0; x<w; x++ ) + { + sum = 0; + for( i = 0; i<3; i++ ) + { + b = readnum( f ); + if( b<0 ) + { + goto eof; + } + sum += b; + } + + GM_UPUT( gm, x, y, sum * (255 / 3) / max ); + } + } + + break; + + case '4': + /* read P4 format: PBM raw */ + + b = fgetc( f ); /* read single white-space character after height */ + if( b==EOF ) + { + goto format_error; + } + + bpr = (w + 7) / 8; + + for( y = h - 1; y>=0; y-- ) + { + for( i = 0; i<bpr; i++ ) + { + b = fgetc( f ); + if( b==EOF ) + { + goto eof; + } + for( j = 0; j<8; j++ ) + { + GM_PUT( gm, i * 8 + j, y, b & (0x80 >> j) ? 0 : 255 ); + } + } + } + + break; + + case '5': + /* read P5 format: PGM raw */ + + max = readnum( f ); + if( max<1 ) + { + goto format_error; + } + + b = fgetc( f ); /* read single white-space character after max */ + if( b==EOF ) + { + goto format_error; + } + + for( y = h - 1; y>=0; y-- ) + { + for( x = 0; x<w; x++ ) + { + b = fgetc( f ); + if( b==EOF ) + goto eof; + if( max>=256 ) + { + b <<= 8; + b1 = fgetc( f ); + if( b1==EOF ) + goto eof; + b |= b1; + } + GM_UPUT( gm, x, y, b * 255 / max ); + } + } + + break; + + case '6': + /* read P6 format: PPM raw */ + + max = readnum( f ); + if( max<1 ) + { + goto format_error; + } + + b = fgetc( f ); /* read single white-space character after max */ + if( b==EOF ) + { + goto format_error; + } + + for( y = h - 1; y>=0; y-- ) + { + for( x = 0; x<w; x++ ) + { + sum = 0; + for( i = 0; i<3; i++ ) + { + b = fgetc( f ); + if( b==EOF ) + { + goto eof; + } + if( max>=256 ) + { + b <<= 8; + b1 = fgetc( f ); + if( b1==EOF ) + goto eof; + b |= b1; + } + sum += b; + } + + GM_UPUT( gm, x, y, sum * (255 / 3) / max ); + } + } + + break; + } + + *gmp = gm; + return 0; + +eof: + *gmp = gm; + return 1; + +format_error: + gm_free( gm ); + if( magic == '1' || magic == '4' ) + { + gm_read_error = "invalid pbm file"; + } + else if( magic == '2' || magic == '5' ) + { + gm_read_error = "invalid pgm file"; + } + else + { + gm_read_error = "invalid ppm file"; + } + return -2; +} + + +/* ---------------------------------------------------------------------- */ +/* read BMP format */ + +struct bmp_info_s +{ + unsigned int FileSize; + unsigned int reserved; + unsigned int DataOffset; + unsigned int InfoSize; + unsigned int w; /* width */ + unsigned int h; /* height */ + unsigned int Planes; + unsigned int bits; /* bits per sample */ + unsigned int comp; /* compression mode */ + unsigned int ImageSize; + unsigned int XpixelsPerM; + unsigned int YpixelsPerM; + unsigned int ncolors; /* number of colors in palette */ + unsigned int ColorsImportant; + unsigned int ctbits; /* sample size for color table */ +}; +typedef struct bmp_info_s bmp_info_t; + +/* auxiliary */ + +static int bmp_count = 0; /* counter for byte padding */ +static int bmp_pos = 0; /* counter from start of BMP data */ + +/* read n-byte little-endian integer. Return 1 on EOF or error, else + * 0. Assume n<=4. */ +static int bmp_readint( FILE* f, int n, unsigned int* p ) +{ + int i; + unsigned int sum = 0; + int b; + + for( i = 0; i<n; i++ ) + { + b = fgetc( f ); + if( b==EOF ) + { + return 1; + } + sum += b << (8 * i); + } + + bmp_count += n; + bmp_pos += n; + *p = sum; + return 0; +} + + +/* reset padding boundary */ +static void bmp_pad_reset( void ) +{ + bmp_count = 0; +} + + +/* read padding bytes to 4-byte boundary. Return 1 on EOF or error, + * else 0. */ +static int bmp_pad( FILE* f ) +{ + int c, i, b; + + c = (-bmp_count) & 3; + for( i = 0; i<c; i++ ) + { + b = fgetc( f ); + if( b==EOF ) + { + return 1; + } + } + + bmp_pos += c; + bmp_count = 0; + return 0; +} + + +/* forward to the new file position. Return 1 on EOF or error, else 0 */ +static int bmp_forward( FILE* f, int pos ) +{ + int b; + + while( bmp_pos < pos ) + { + b = fgetc( f ); + if( b==EOF ) + { + return 1; + } + bmp_pos++; + bmp_count++; + } + + return 0; +} + + +#define TRY( x ) if( x ) \ + goto try_error +#define TRY_EOF( x ) if( x ) \ + goto eof + +/* read BMP stream after magic number. Return values as for gm_read. + * We choose to be as permissive as possible, since there are many + * programs out there which produce BMP. For instance, ppmtobmp can + * produce codings with anywhere from 1-8 or 24 bits per sample, + * although most specifications only allow 1,4,8,24,32. We can also + * read both the old and new OS/2 BMP formats in addition to the + * Windows BMP format. */ +static int gm_readbody_bmp( FILE* f, greymap_t** gmp ) +{ + bmp_info_t bmpinfo; + int* coltable; + unsigned int b, c; + unsigned int i, j; + greymap_t* gm; + unsigned int x, y; + int col[2]; + unsigned int bitbuf; + unsigned int n; + + gm_read_error = NULL; + gm = NULL; + coltable = NULL; + + bmp_pos = 2; /* set file position */ + + /* file header (minus magic number) */ + TRY( bmp_readint( f, 4, &bmpinfo.FileSize ) ); + TRY( bmp_readint( f, 4, &bmpinfo.reserved ) ); + TRY( bmp_readint( f, 4, &bmpinfo.DataOffset ) ); + + /* info header */ + TRY( bmp_readint( f, 4, &bmpinfo.InfoSize ) ); + if( bmpinfo.InfoSize == 40 || bmpinfo.InfoSize == 64 ) + { + /* Windows or new OS/2 format */ + bmpinfo.ctbits = 32; /* sample size in color table */ + TRY( bmp_readint( f, 4, &bmpinfo.w ) ); + TRY( bmp_readint( f, 4, &bmpinfo.h ) ); + TRY( bmp_readint( f, 2, &bmpinfo.Planes ) ); + TRY( bmp_readint( f, 2, &bmpinfo.bits ) ); + TRY( bmp_readint( f, 4, &bmpinfo.comp ) ); + TRY( bmp_readint( f, 4, &bmpinfo.ImageSize ) ); + TRY( bmp_readint( f, 4, &bmpinfo.XpixelsPerM ) ); + TRY( bmp_readint( f, 4, &bmpinfo.YpixelsPerM ) ); + TRY( bmp_readint( f, 4, &bmpinfo.ncolors ) ); + TRY( bmp_readint( f, 4, &bmpinfo.ColorsImportant ) ); + } + else if( bmpinfo.InfoSize == 12 ) + { + /* old OS/2 format */ + bmpinfo.ctbits = 24; /* sample size in color table */ + TRY( bmp_readint( f, 2, &bmpinfo.w ) ); + TRY( bmp_readint( f, 2, &bmpinfo.h ) ); + TRY( bmp_readint( f, 2, &bmpinfo.Planes ) ); + TRY( bmp_readint( f, 2, &bmpinfo.bits ) ); + bmpinfo.comp = 0; + bmpinfo.ncolors = 0; + } + else + { + goto format_error; + } + + /* forward to color table (i.e., if bmpinfo.InfoSize == 64) */ + TRY( bmp_forward( f, 14 + bmpinfo.InfoSize ) ); + + if( bmpinfo.Planes != 1 ) + { + gm_read_error = "cannot handle bmp planes"; + goto format_error; /* can't handle planes */ + } + + if( bmpinfo.ncolors == 0 ) + { + bmpinfo.ncolors = 1 << bmpinfo.bits; + } + + /* color table, present only if bmpinfo.bits <= 8. */ + if( bmpinfo.bits <= 8 ) + { + coltable = (int*) malloc( bmpinfo.ncolors * sizeof(int) ); + if( !coltable ) + { + goto std_error; + } + + /* NOTE: since we are reading a greymap, we can immediately convert + * the color table entries to grey values. */ + for( i = 0; i<bmpinfo.ncolors; i++ ) + { + TRY( bmp_readint( f, bmpinfo.ctbits / 8, &c ) ); + c = ( (c >> 16) & 0xff ) + ( (c >> 8) & 0xff ) + (c & 0xff); + coltable[i] = c / 3; + } + } + + /* forward to data */ + if( bmpinfo.InfoSize != 12 ) /* not old OS/2 format */ + { + TRY( bmp_forward( f, bmpinfo.DataOffset ) ); + } + + /* allocate greymap */ + gm = gm_new( bmpinfo.w, bmpinfo.h ); + if( !gm ) + { + goto std_error; + } + + /* zero it out */ + gm_clear( gm, 0 ); + + switch( bmpinfo.bits + 0x100 * bmpinfo.comp ) + { + default: + goto format_error; + break; + + case 0x001: /* monochrome palette */ + + /* raster data */ + for( y = 0; y<bmpinfo.h; y++ ) + { + bmp_pad_reset(); + for( i = 0; 8 * i<bmpinfo.w; i++ ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); + for( j = 0; j<8; j++ ) + { + GM_PUT( gm, i * 8 + j, y, b & (0x80 >> j) ? coltable[1] : coltable[0] ); + } + } + + TRY( bmp_pad( f ) ); + } + + break; + + case 0x002: /* 2-bit to 8-bit palettes */ + case 0x003: + case 0x004: + case 0x005: + case 0x006: + case 0x007: + case 0x008: + for( y = 0; y<bmpinfo.h; y++ ) + { + bmp_pad_reset(); + bitbuf = 0; /* bit buffer: bits in buffer are high-aligned */ + n = 0; /* number of bits currently in bitbuffer */ + for( x = 0; x<bmpinfo.w; x++ ) + { + if( n < bmpinfo.bits ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); + bitbuf |= b << (INTBITS - 8 - n); + n += 8; + } + b = bitbuf >> (INTBITS - bmpinfo.bits); + bitbuf <<= bmpinfo.bits; + n -= bmpinfo.bits; + GM_UPUT( gm, x, y, coltable[b] ); + } + + TRY( bmp_pad( f ) ); + } + + break; + + case 0x010: /* 16-bit encoding */ + + /* can't do this format because it is not well-documented and I + * don't have any samples */ + gm_read_error = "cannot handle bmp 16-bit coding"; + goto format_error; + break; + + case 0x018: /* 24-bit encoding */ + case 0x020: /* 32-bit encoding */ + for( y = 0; y<bmpinfo.h; y++ ) + { + bmp_pad_reset(); + for( x = 0; x<bmpinfo.w; x++ ) + { + TRY_EOF( bmp_readint( f, bmpinfo.bits / 8, &c ) ); + c = ( (c >> 16) & 0xff ) + ( (c >> 8) & 0xff ) + (c & 0xff); + GM_UPUT( gm, x, y, c / 3 ); + } + + TRY( bmp_pad( f ) ); + } + + break; + + case 0x204: /* 4-bit runlength compressed encoding (RLE4) */ + x = 0; + y = 0; + while( 1 ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */ + TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */ + if( b>0 ) + { + /* repeat count */ + col[0] = coltable[(c >> 4) & 0xf]; + col[1] = coltable[c & 0xf]; + for( i = 0; i<b && x<bmpinfo.w; i++ ) + { + if( x>=bmpinfo.w ) + { + x = 0; + y++; + } + if( y>=bmpinfo.h ) + { + break; + } + GM_UPUT( gm, x, y, col[i & 1] ); + x++; + } + } + else if( c == 0 ) + { + /* end of line */ + y++; + x = 0; + } + else if( c == 1 ) + { + /* end of greymap */ + break; + } + else if( c == 2 ) + { + /* "delta": skip pixels in x and y directions */ + TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */ + TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */ + x += b; + y += c; + } + else + { + /* verbatim segment */ + for( i = 0; i<c; i++ ) + { + if( (i & 1)==0 ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); + } + if( x>=bmpinfo.w ) + { + x = 0; + y++; + } + if( y>=bmpinfo.h ) + { + break; + } + GM_PUT( gm, x, y, coltable[( b >> ( 4 - 4 * (i & 1) ) ) & 0xf] ); + x++; + } + + if( (c + 1) & 2 ) + { + /* pad to 16-bit boundary */ + TRY_EOF( bmp_readint( f, 1, &b ) ); + } + } + } + + break; + + case 0x108: /* 8-bit runlength compressed encoding (RLE8) */ + x = 0; + y = 0; + while( 1 ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */ + TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */ + if( b>0 ) + { + /* repeat count */ + for( i = 0; i<b; i++ ) + { + if( x>=bmpinfo.w ) + { + x = 0; + y++; + } + if( y>=bmpinfo.h ) + { + break; + } + GM_UPUT( gm, x, y, coltable[c] ); + x++; + } + } + else if( c == 0 ) + { + /* end of line */ + y++; + x = 0; + } + else if( c == 1 ) + { + /* end of greymap */ + break; + } + else if( c == 2 ) + { + /* "delta": skip pixels in x and y directions */ + TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */ + TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */ + x += b; + y += c; + } + else + { + /* verbatim segment */ + for( i = 0; i<c; i++ ) + { + TRY_EOF( bmp_readint( f, 1, &b ) ); + if( x>=bmpinfo.w ) + { + x = 0; + y++; + } + if( y>=bmpinfo.h ) + { + break; + } + GM_PUT( gm, x, y, coltable[b] ); + x++; + } + + if( c & 1 ) + { + /* pad input to 16-bit boundary */ + TRY_EOF( bmp_readint( f, 1, &b ) ); + } + } + } + + break; + } /* switch */ + + /* skip any potential junk after the data section, but don't + * complain in case EOF is encountered */ + bmp_forward( f, bmpinfo.FileSize ); + + free( coltable ); + *gmp = gm; + return 0; + +eof: + free( coltable ); + *gmp = gm; + return 1; + +format_error: +try_error: + free( coltable ); + free( gm ); + if( !gm_read_error ) + { + gm_read_error = "invalid bmp file"; + } + return -2; + +std_error: + free( coltable ); + free( gm ); + return -1; +} + + +/* ---------------------------------------------------------------------- */ + +/* write a pgm stream, either P2 or (if raw != 0) P5 format. Include + * one-line comment if non-NULL. Mode determines how out-of-range + * color values are converted. Gamma is the desired gamma correction, + * if any (set to 2.2 if the image is to look optimal on a CRT monitor, + * 2.8 for LCD). Set to 1.0 for no gamma correction */ + +int gm_writepgm( FILE* f, greymap_t* gm, char* comment, int raw, int mode, double gamma ) +{ + int x, y, v; + int gammatable[256]; + + /* prepare gamma correction lookup table */ + if( gamma != 1.0 ) + { + gammatable[0] = 0; + for( v = 1; v<256; v++ ) + { + gammatable[v] = (int) ( 255 * exp( log( v / 255.0 ) / gamma ) + 0.5 ); + } + } + else + { + for( v = 0; v<256; v++ ) + { + gammatable[v] = v; + } + } + + fprintf( f, raw ? "P5\n" : "P2\n" ); + if( comment && *comment ) + { + fprintf( f, "# %s\n", comment ); + } + fprintf( f, "%d %d 255\n", gm->w, gm->h ); + for( y = gm->h - 1; y>=0; y-- ) + { + for( x = 0; x<gm->w; x++ ) + { + v = GM_UGET( gm, x, y ); + if( mode == GM_MODE_NONZERO ) + { + if( v > 255 ) + { + v = 510 - v; + } + if( v < 0 ) + { + v = 0; + } + } + else if( mode == GM_MODE_ODD ) + { + v = mod( v, 510 ); + if( v > 255 ) + { + v = 510 - v; + } + } + else if( mode == GM_MODE_POSITIVE ) + { + if( v < 0 ) + { + v = 0; + } + else if( v > 255 ) + { + v = 255; + } + } + else if( mode == GM_MODE_NEGATIVE ) + { + v = 510 - v; + if( v < 0 ) + { + v = 0; + } + else if( v > 255 ) + { + v = 255; + } + } + v = gammatable[v]; + + if( raw ) + { + fputc( v, f ); + } + else + { + fprintf( f, x == gm->w - 1 ? "%d\n" : "%d ", v ); + } + } + } + + return 0; +} + + +/* ---------------------------------------------------------------------- */ +/* output - for primitive debugging purposes only! */ + +/* print greymap to screen */ +int gm_print( FILE* f, greymap_t* gm ) +{ + int x, y; + int xx, yy; + int d, t; + int sw, sh; + + sw = gm->w < 79 ? gm->w : 79; + sh = gm->w < 79 ? gm->h : gm->h * sw * 44 / (79 * gm->w); + + for( yy = sh - 1; yy>=0; yy-- ) + { + for( xx = 0; xx<sw; xx++ ) + { + d = 0; + t = 0; + for( x = xx * gm->w / sw; x<(xx + 1) * gm->w / sw; x++ ) + { + for( y = yy * gm->h / sh; y<(yy + 1) * gm->h / sh; y++ ) + { + d += GM_GET( gm, x, y ); + t += 256; + } + } + + if( t ) + fputc( "*#=- "[5 * d / t], f ); /* what a cute trick :) */ + } + + fputc( '\n', f ); + } + + return 0; +} |