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