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 */