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 6 #ifndef GREYMAP_H 7 #define GREYMAP_H 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <stddef.h> 12 13 /* type for greymap samples */ 14 typedef signed short int gm_sample_t; 15 16 /* internal format for greymaps. Note: in this format, rows are 17 ordered from bottom to top. The pixels in each row are given from 18 left to right. */ 19 struct greymap_s { 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) ((int)(x)>=0 && (int)(x)<(gm)->w && (int)(y)>=0 && (int)(y)<(gm)->h) 35 #define gm_bound(x, m) ((x)<0 ? 0 : (x)>=(m) ? (m)-1 : (x)) 36 #define GM_UGET(gm, x, y) (*gm_index(gm, x, y)) 37 #define GM_UINC(gm, x, y, b) (*gm_index(gm, x, y) += (gm_sample_t)(b)) 38 #define GM_UINV(gm, x, y) (*gm_index(gm, x, y) = 255 - *gm_index(gm, x, y)) 39 #define GM_UPUT(gm, x, y, b) (*gm_index(gm, x, y) = (gm_sample_t)(b)) 40 #define GM_GET(gm, x, y) (gm_safe(gm, x, y) ? GM_UGET(gm, x, y) : 0) 41 #define GM_INC(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UINC(gm, x, y, b) : 0) 42 #define GM_INV(gm, x, y) (gm_safe(gm, x, y) ? GM_UINV(gm, x, y) : 0) 43 #define GM_PUT(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UPUT(gm, x, y, b) : 0) 44 #define GM_BGET(gm, x, y) GM_UGET(gm, gm_bound(x, gm->w), gm_bound(y, gm->h)) 45 46 /* modes for cutting off out-of-range values. The following names 47 refer to winding numbers. I.e., make a pixel black if winding 48 number is nonzero, odd, or positive, respectively. We assume that 0 49 winding number corresponds to white (255). */ 50 #define GM_MODE_NONZERO 1 51 #define GM_MODE_ODD 2 52 #define GM_MODE_POSITIVE 3 53 #define GM_MODE_NEGATIVE 4 54 55 extern const char *gm_read_error; 56 57 greymap_t *gm_new(int w, int h); 58 greymap_t *gm_dup(greymap_t *gm); 59 void gm_free(greymap_t *gm); 60 void gm_clear(greymap_t *gm, int b); 61 int gm_read(FILE *f, greymap_t **gmp); 62 int gm_writepgm(FILE *f, greymap_t *gm, const char *comment, int raw, int mode, double gamma); 63 int gm_print(FILE *f, greymap_t *gm); 64 65 #endif /* GREYMAP_H */ 66