KiCad PCB EDA Suite
bitmap.h
Go to the documentation of this file.
1 /* Copyright (C) 2001-2015 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 BITMAP_H
6 #define BITMAP_H
7 
8 #include <string.h>
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <stddef.h>
12 
13 /* The bitmap type is defined in potracelib.h */
14 #include "potracelib.h"
15 
16 /* The present file defines some convenient macros and static inline
17  * functions for accessing bitmaps. Since they only produce inline
18  * code, they can be conveniently shared by the library and frontends,
19  * if desired */
20 
21 /* ---------------------------------------------------------------------- */
22 /* some measurements */
23 
24 #define BM_WORDSIZE ( (int) sizeof(potrace_word) )
25 #define BM_WORDBITS (8 * BM_WORDSIZE)
26 #define BM_HIBIT ( ( (potrace_word) 1 ) << (BM_WORDBITS - 1) )
27 #define BM_ALLBITS (~(potrace_word) 0)
28 
29 /* macros for accessing pixel at index (x,y). U* macros omit the
30  * bounds check. */
31 
32 #define bm_scanline( bm, y ) ( (bm)->map + (ptrdiff_t) (y) * (ptrdiff_t) (bm)->dy )
33 #define bm_index( bm, x, y ) (&bm_scanline( bm, y )[(x) / BM_WORDBITS])
34 #define bm_mask( x ) ( BM_HIBIT >> ( (x) & (BM_WORDBITS - 1) ) )
35 #define bm_range( x, a ) ( (int) (x) >= 0 && (int) (x) < (a) )
36 #define bm_safe( bm, x, y ) ( bm_range( x, (bm)->w ) && bm_range( y, (bm)->h ) )
37 #define BM_UGET( bm, x, y ) ( ( *bm_index( bm, x, y ) & bm_mask( x ) ) != 0 )
38 #define BM_USET( bm, x, y ) ( *bm_index( bm, x, y ) |= bm_mask( x ) )
39 #define BM_UCLR( bm, x, y ) ( *bm_index( bm, x, y ) &= ~bm_mask( x ) )
40 #define BM_UINV( bm, x, y ) ( *bm_index( bm, x, y ) ^= bm_mask( x ) )
41 #define BM_UPUT( bm, x, y, b ) ( (b) ? BM_USET( bm, x, y ) : BM_UCLR( bm, x, y ) )
42 #define BM_GET( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UGET( bm, x, y ) : 0)
43 #define BM_SET( bm, x, y ) (bm_safe( bm, x, y ) ? BM_USET( bm, x, y ) : 0)
44 #define BM_CLR( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UCLR( bm, x, y ) : 0)
45 #define BM_INV( bm, x, y ) (bm_safe( bm, x, y ) ? BM_UINV( bm, x, y ) : 0)
46 #define BM_PUT( bm, x, y, b ) (bm_safe( bm, x, y ) ? BM_UPUT( bm, x, y, b ) : 0)
47 
48 /* free the given bitmap. Leaves errno untouched. */
49 static inline void bm_free( potrace_bitmap_t* bm )
50 {
51  if( bm )
52  {
53  free( bm->map );
54  }
55 
56  free( bm );
57 }
58 
59 
60 /* return new un-initialized bitmap. NULL with errno on error.
61  * Assumes w, h >= 0. */
62 static inline potrace_bitmap_t* bm_new( int w, int h )
63 {
64  potrace_bitmap_t* bm;
65  int dy = w == 0 ? 0 : (w - 1) / BM_WORDBITS + 1;
66  ptrdiff_t size = (ptrdiff_t) dy * (ptrdiff_t) h * (ptrdiff_t) BM_WORDSIZE;
67 
68  /* check for overflow error */
69  if( size < 0 || (h != 0 && dy != 0 && size / h / dy != BM_WORDSIZE) )
70  {
71  errno = ENOMEM;
72  return NULL;
73  }
74 
75  bm = (potrace_bitmap_t*) malloc( sizeof(potrace_bitmap_t) );
76 
77  if( !bm )
78  {
79  return NULL;
80  }
81 
82  bm->w = w;
83  bm->h = h;
84  bm->dy = dy;
85  bm->map = (potrace_word*) malloc( size );
86 
87  if( !bm->map )
88  {
89  free( bm );
90  return NULL;
91  }
92 
93  return bm;
94 }
95 
96 
97 /* clear the given bitmap. Set all bits to c. */
98 static inline void bm_clear( potrace_bitmap_t* bm, int c )
99 {
100  /* Note: if the bitmap was created with bm_new, then it is
101  * guaranteed that size will fit into the ptrdiff_t type. */
102  ptrdiff_t size = (ptrdiff_t) bm->dy * (ptrdiff_t) bm->h * (ptrdiff_t) BM_WORDSIZE;
103 
104  memset( bm->map, c ? -1 : 0, size );
105 }
106 
107 
108 /* duplicate the given bitmap. Return NULL on error with errno set. */
109 static inline potrace_bitmap_t* bm_dup( const potrace_bitmap_t* bm )
110 {
111  potrace_bitmap_t* bm1 = bm_new( bm->w, bm->h );
112  ptrdiff_t size = (ptrdiff_t) bm->dy * (ptrdiff_t) bm->h * (ptrdiff_t) BM_WORDSIZE;
113 
114  if( !bm1 )
115  {
116  return NULL;
117  }
118 
119  memcpy( bm1->map, bm->map, size );
120  return bm1;
121 }
122 
123 
124 /* invert the given bitmap. */
125 static inline void bm_invert( potrace_bitmap_t* bm )
126 {
127  ptrdiff_t i;
128  ptrdiff_t size = (ptrdiff_t) bm->dy * (ptrdiff_t) bm->h;
129 
130  for( i = 0; i < size; i++ )
131  {
132  bm->map[i] ^= BM_ALLBITS;
133  }
134 }
135 
136 
137 #endif /* BITMAP_H */
static void bm_free(potrace_bitmap_t *bm)
Definition: bitmap.h:49
#define BM_WORDSIZE
Definition: bitmap.h:24
static potrace_bitmap_t * bm_dup(const potrace_bitmap_t *bm)
Definition: bitmap.h:109
potrace_word * map
Definition: potracelib.h:63
unsigned long potrace_word
Definition: potracelib.h:53
static potrace_bitmap_t * bm_new(int w, int h)
Definition: bitmap.h:62
static void bm_clear(potrace_bitmap_t *bm, int c)
Definition: bitmap.h:98
static void bm_invert(potrace_bitmap_t *bm)
Definition: bitmap.h:125
#define BM_WORDBITS
Definition: bitmap.h:25
#define BM_ALLBITS
Definition: bitmap.h:27