1 /* Copyright (C) 2001-2017 Peter Selinger. 2 * This file is part of Potrace. It is free software and it is covered 3 * by the GNU General Public License. See the file COPYING for details. */ 4 5 #ifndef GREYMAP_H 6 #define GREYMAP_H 7 8 #include <stddef.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 12 /* type for greymap samples */ 13 typedef signed short int gm_sample_t; 14 15 /* internal format for greymaps. Note: in this format, rows are 16 * ordered from bottom to top. The pixels in each row are given from 17 * left to right. */ 18 struct greymap_s 19 { 20 int w; /* width, in pixels */ 21 int h; /* height, in pixels */ 22 int dy; /* offset between scanlines (in samples); 23 * can be negative */ 24 gm_sample_t* base; /* root of allocated data */ 25 gm_sample_t* map; /* points to the lower left pixel */ 26 }; 27 typedef struct greymap_s greymap_t; 28 29 /* macros for accessing pixel at index (x,y). Note that the origin is 30 * in the *lower* left corner. U* macros omit the bounds check. */ 31 32 #define gm_scanline( gm, y ) ( ( gm )->map + (ptrdiff_t) ( y ) * (ptrdiff_t) ( gm )->dy ) 33 #define gm_index( gm, x, y ) ( gm_scanline( gm, y ) + ( x ) ) 34 #define gm_safe( gm, x, y ) \ 35 ( (int) ( x ) >= 0 && (int) ( x ) < ( gm )->w && (int) ( y ) >= 0 && (int) ( y ) < ( gm )->h ) 36 #define gm_bound( x, m ) ( ( x ) < 0 ? 0 : ( x ) >= ( m ) ? (m) - 1 : ( x ) ) 37 #define GM_UGET( gm, x, y ) ( *gm_index( gm, x, y ) ) 38 #define GM_UINC( gm, x, y, b ) ( *gm_index( gm, x, y ) += (gm_sample_t) ( b ) ) 39 #define GM_UINV( gm, x, y ) ( *gm_index( gm, x, y ) = 255 - *gm_index( gm, x, y ) ) 40 #define GM_UPUT( gm, x, y, b ) ( *gm_index( gm, x, y ) = (gm_sample_t) ( b ) ) 41 #define GM_GET( gm, x, y ) ( gm_safe( gm, x, y ) ? GM_UGET( gm, x, y ) : 0 ) 42 #define GM_INC( gm, x, y, b ) ( gm_safe( gm, x, y ) ? GM_UINC( gm, x, y, b ) : 0 ) 43 #define GM_INV( gm, x, y ) ( gm_safe( gm, x, y ) ? GM_UINV( gm, x, y ) : 0 ) 44 #define GM_PUT( gm, x, y, b ) ( gm_safe( gm, x, y ) ? GM_UPUT( gm, x, y, b ) : 0 ) 45 #define GM_BGET( gm, x, y ) \ 46 ( ( gm )->w == 0 || ( gm )->h == 0 ? 0 : GM_UGET( gm, gm_bound( x, ( gm )->w ), \ 47 gm_bound( y, ( gm )->h ) ) ) 48 49 /* modes for cutting off out-of-range values. The following names 50 * refer to winding numbers. I.e., make a pixel black if winding 51 * number is nonzero, odd, or positive, respectively. We assume that 0 52 * winding number corresponds to white (255). */ 53 #define GM_MODE_NONZERO 1 54 #define GM_MODE_ODD 2 55 #define GM_MODE_POSITIVE 3 56 #define GM_MODE_NEGATIVE 4 57 58 extern const char* gm_read_error; 59 60 greymap_t* gm_new( int w, int h ); 61 greymap_t* gm_dup( greymap_t* gm ); 62 void gm_free( greymap_t* gm ); 63 void gm_clear( greymap_t* gm, int b ); 64 int gm_read( FILE* f, greymap_t** gmp ); 65 int gm_writepgm( FILE* f, 66 greymap_t* gm, 67 const char* comment, 68 int raw, 69 int mode, 70 double gamma ); 71 int gm_print( FILE* f, greymap_t* gm ); 72 73 #endif /* GREYMAP_H */ 74