File indexing completed on 2024-12-22 04:04:12
0001 /* Copyright (C) 2001-2019 Peter Selinger. 0002 This file is part of Potrace. It is free software and it is covered 0003 by the GNU General Public License. See the file COPYING for details. */ 0004 0005 0006 #ifndef GREYMAP_H 0007 #define GREYMAP_H 0008 0009 #include <stdio.h> 0010 #include <stdlib.h> 0011 #include <stddef.h> 0012 0013 /* type for greymap samples */ 0014 typedef signed short int gm_sample_t; 0015 0016 #define GM_SAMPLESIZE (sizeof(gm_sample_t)) 0017 0018 /* internal format for greymaps. Note: in this format, rows are 0019 ordered from bottom to top. The pixels in each row are given from 0020 left to right. */ 0021 struct greymap_s { 0022 int w; /* width, in pixels */ 0023 int h; /* height, in pixels */ 0024 int dy; /* offset between scanlines (in samples); 0025 can be negative */ 0026 gm_sample_t *base; /* root of allocated data */ 0027 gm_sample_t *map; /* points to the lower left pixel */ 0028 }; 0029 typedef struct greymap_s greymap_t; 0030 0031 /* macros for accessing pixel at index (x,y). Note that the origin is 0032 in the *lower* left corner. U* macros omit the bounds check. */ 0033 0034 #define gm_scanline(gm, y) ((gm)->map + (ptrdiff_t)(y)*(ptrdiff_t)(gm)->dy) 0035 #define gm_index(gm, x, y) (gm_scanline(gm, y) + (x)) 0036 #define gm_safe(gm, x, y) ((int)(x)>=0 && (int)(x)<(gm)->w && (int)(y)>=0 && (int)(y)<(gm)->h) 0037 #define gm_bound(x, m) ((x)<0 ? 0 : (x)>=(m) ? (m)-1 : (x)) 0038 #define GM_UGET(gm, x, y) (*gm_index(gm, x, y)) 0039 #define GM_UINC(gm, x, y, b) (*gm_index(gm, x, y) += (gm_sample_t)(b)) 0040 #define GM_UINV(gm, x, y) (*gm_index(gm, x, y) = 255 - *gm_index(gm, x, y)) 0041 #define GM_UPUT(gm, x, y, b) (*gm_index(gm, x, y) = (gm_sample_t)(b)) 0042 #define GM_GET(gm, x, y) (gm_safe(gm, x, y) ? GM_UGET(gm, x, y) : 0) 0043 #define GM_INC(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UINC(gm, x, y, b) : 0) 0044 #define GM_INV(gm, x, y) (gm_safe(gm, x, y) ? GM_UINV(gm, x, y) : 0) 0045 #define GM_PUT(gm, x, y, b) (gm_safe(gm, x, y) ? GM_UPUT(gm, x, y, b) : 0) 0046 #define GM_BGET(gm, x, y) ((gm)->w == 0 || (gm)->h == 0 ? 0 : GM_UGET(gm, gm_bound(x, (gm)->w), gm_bound(y, (gm)->h))) 0047 0048 /* modes for cutting off out-of-range values. The following names 0049 refer to winding numbers. I.e., make a pixel black if winding 0050 number is nonzero, odd, or positive, respectively. We assume that 0 0051 winding number corresponds to white (255). */ 0052 #define GM_MODE_NONZERO 1 0053 #define GM_MODE_ODD 2 0054 #define GM_MODE_POSITIVE 3 0055 #define GM_MODE_NEGATIVE 4 0056 0057 extern const char *gm_read_error; 0058 0059 greymap_t *gm_new(int w, int h); 0060 greymap_t *gm_dup(greymap_t *gm); 0061 void gm_free(greymap_t *gm); 0062 void gm_clear(greymap_t *gm, int b); 0063 int gm_read(FILE *f, greymap_t **gmp); 0064 int gm_writepgm(FILE *f, greymap_t *gm, const char *comment, int raw, int mode, double gamma); 0065 int gm_print(FILE *f, greymap_t *gm); 0066 0067 #endif /* GREYMAP_H */