1 /*
2 Maps i.e. 2D, coordinate addressable, arrays of element.
3
4 lkk I couldn't find a suitable library that implement this.
5 So this is a conventional implementation using pointer arithmentic on a 1-D array.
6 Here, the 1-D array is a GArray.
7
8 In earlier resynthesizer c++ coding, this used templates.
9 That is, a Bitmap was a 2D array class parameterized by the type of the element:
10 Pixel (byte array)
11 Coordinates
12 int
13 boolean (represented by single byte)
14 Here, there are separate functions for creating and indexing each type of map.
15
16 Copyright (C) 2010, 2011 Lloyd Konneker
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
22
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33 // Note, included, not compiled separately
34
35 void
free_map(Map * map)36 free_map (Map *map)
37 {
38 g_array_free(map->data, TRUE);
39 map->data = (GArray *) NULL;
40 }
41
42
43 /* Create new Pixmap having Pixel of depth. IE a 3D array */
44 void
new_pixmap(Map * map,guint width,guint height,guint depth)45 new_pixmap(
46 Map * map,
47 guint width,
48 guint height,
49 guint depth
50 )
51 {
52 map->width = width;
53 map->height = height;
54 map->depth = depth;
55 /*
56 Equivalently, but not if Pixelel size changes.
57 IOW the code now depends on Pixelel equal one byte.
58 guint size = width * height * depth;
59 map->data = g_array_sized_new (FALSE, TRUE, sizeof(Pixelel), size);
60 */
61 map->data = g_array_sized_new (FALSE, TRUE, depth, width * height);
62 }
63
64
65 /* Create dynamic 2-D array of guint. */
66 void
new_intmap(Map * map,guint width,guint height)67 new_intmap(
68 Map * map,
69 guint width,
70 guint height
71 )
72 {
73 map->width = width;
74 map->height = height;
75 map->depth = sizeof(guint); // Not used
76 map->data = g_array_sized_new (FALSE, TRUE, sizeof(guint), width * height);
77 }
78
79 /* Create dynamic 2-D array of Coordinates. */
80 void
new_coordmap(Map * map,guint width,guint height)81 new_coordmap(
82 Map * map,
83 guint width,
84 guint height
85 )
86 {
87 map->width = width;
88 map->height = height;
89 map->depth = sizeof(Coordinates); // Not used
90 map->data = g_array_sized_new (FALSE, TRUE, sizeof(Coordinates), width * height);
91 }
92
93 /* Create dynamic 2-D array of guchar. */
94 void
new_bytemap(Map * map,guint width,guint height)95 new_bytemap(
96 Map * map,
97 guint width,
98 guint height
99 )
100 {
101 /* Implement bytemap as pixmap of depth 1 */
102 new_pixmap(map, width, height, 1);
103 }
104
105
106
107 /* Misc operations on Map. */
108
109 /* Set all elements of bytemap to a value.
110 TODO use memset?
111 */
112 void
set_bytemap(Map * map,guchar value)113 set_bytemap(
114 Map* map,
115 guchar value
116 )
117 {
118 guint y;
119 guint x;
120
121 for (y=0; y<map->height; y++)
122 for (x=0; x<map->width; x++)
123 {
124 Coordinates coords = {x,y};
125 *bytemap_index(map, coords) = value;
126 }
127 }
128
129 void
invert_bytemap(Map * map)130 invert_bytemap(
131 Map* map
132 )
133 {
134 guint y;
135 guint x;
136
137 for (y=0; y<map->height; y++)
138 for (x=0; x<map->width; x++)
139 {
140 Coordinates coords = {x,y};
141 // Ones complement: bitwise negation
142 *bytemap_index(map, coords) = ~ *bytemap_index(map, coords);
143 }
144 }
145
146
147 /*
148 Interleave one pixelel of mask pixmap into pixelels of pixmap.
149
150 lkk Mask bytemap was separate. Interleaved them for better memory locality.
151 The map pixmap was interleaved with the color pixmap, so why not the mask too.
152 */
153 void
interleave_mask(Map * pixmap,Map * mask)154 interleave_mask(
155 Map *pixmap,
156 Map *mask
157 )
158 {
159 guint i;
160
161 guint size = pixmap->height * pixmap->width;
162 g_assert( size == mask->height * mask->width); /* Same dimensions. */
163
164 for (i=0; i < size; i++)
165 /* Copy one byte */
166 g_array_index(pixmap->data, Pixelel, i*pixmap->depth + MASK_PIXELEL_INDEX) =
167 g_array_index(mask->data, Pixelel, i*mask->depth);
168 }
169
170
171
172