1 /*
2 Internal image format.
3
4 The count of pixelels in a pixel depends on the format type.
5 The engine uses a struct that tells where Pixelels are in an internal Pixel.
6 The internal Pixel aggregates color, mask, and map pixelels; for memory locality.
7
8 Copyright (C) 2010, 2011 Lloyd Konneker
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25 // Compiling switch #defines
26 #include "buildSwitches.h"
27 #ifdef SYNTH_USE_GLIB
28 // Use glib via gimp.h
29 #include <libgimp/gimp.h>
30 #else
31 #include "glibProxy.h"
32 #endif
33
34 #include "imageSynthConstants.h"
35 #include "engineParams.h"
36 #include "imageFormat.h"
37 #include "imageFormatIndicies.h"
38
39 extern unsigned int
countPixelelsPerPixelForFormat(TImageFormat format)40 countPixelelsPerPixelForFormat(
41 TImageFormat format // IN
42 )
43 {
44 switch (format) {
45 case T_RGB:
46 return 3;
47 case T_RGBA:
48 return 4;
49 case T_Gray:
50 return 1;
51 case T_GrayA:
52 return 2;
53 default:
54 return 0; // Unhandled format type
55 }
56 }
57
58
59 /*
60 Generate a TFormatIndices struct from a format code.
61
62 This is only for adapting to the SimpleAPI.
63 When adapting from Gimp, formatIndices is generated another way.
64 */
65 extern int
prepareImageFormatIndicesFromFormatType(TFormatIndices * formatIndices,TImageFormat format)66 prepareImageFormatIndicesFromFormatType(
67 TFormatIndices* formatIndices, // OUT
68 TImageFormat format
69 )
70 {
71 switch (format) {
72 case T_RGB:
73 prepareImageFormatIndices( formatIndices,
74 3, // count color pixelels
75 0, // no map colors
76 FALSE, // is_alpha_target,
77 FALSE, // is_alpha_source,
78 FALSE // isMap
79 );
80 break;
81 case T_RGBA:
82 prepareImageFormatIndices( formatIndices,
83 3, // count color pixelels
84 0, // no map colors
85 TRUE, // is_alpha_target,
86 // Since we are adapting by duplicating, if target has alpha, so does source
87 TRUE, // is_alpha_source,
88 FALSE // isMap
89 );
90 break;
91 case T_Gray:
92 prepareImageFormatIndices( formatIndices,
93 1, // count color pixelels
94 0, // no map colors
95 FALSE, // is_alpha_target,
96 FALSE, // is_alpha_source,
97 FALSE // isMap
98 );
99 break;
100 case T_GrayA:
101 prepareImageFormatIndices( formatIndices,
102 1, // count color pixelels
103 0, // no map colors
104 TRUE, // is_alpha_target,
105 TRUE, // is_alpha_source,
106 FALSE // isMap
107 );
108 break;
109 default:
110 return IMAGE_SYNTH_ERROR_INVALID_IMAGE_FORMAT;
111 }
112 return 0;
113 }
114
115
116 void
prepareImageFormatIndices(TFormatIndices * indices,guint count_color_channels_target,guint count_color_channels_map,gboolean is_alpha_target,gboolean is_alpha_source,gboolean isMap)117 prepareImageFormatIndices(
118 TFormatIndices* indices, // OUT
119 guint count_color_channels_target, // Must be same count in source
120 guint count_color_channels_map,
121 gboolean is_alpha_target,
122 gboolean is_alpha_source,
123 gboolean isMap
124 )
125 {
126 /*
127 Dynamic counts and indexes of pixelels. Depends on the in drawables.
128 !!! These are the same for target and corpus, even if the in drawables differ in alphas.
129 !!! See resynth_types.h.
130 bpp means bytes per pixel
131 bip means byte index in pixel
132 !!! Note the end is not the index of the last, but the index after the last
133
134 [0] mask pixelel
135 [1,colorEndBip) image color pixelels, up to 3 (RGB)
136 optional alpha byte
137 [map_start_bip, total_bpp) map color pixelels
138 optional map alpha byte !!! discard
139 [0, total_bpp) entire pixel
140
141 [1, colorEndBip) color pixelels compared
142 [map_start_bip, map_end_bip) map pixelels compared
143
144 Examples:
145 RGBA with RGB maps RGB with GRAY maps RGB with no maps
146 0 Mask (selection) M M
147 1 R FIRST_PIXELEL_INDEX R FIRST_PIXELEL_INDEX R
148 2 G G G
149 3 B B B
150 4 A alpha_bip, colorEndBip W colorEndBip, map_start_bip 4 color_end, map_start, map_end, total
151 5 R map_start_bip 5 map_end_bip, total_bpp
152 6 G
153 7 B
154 8 map_end_bip, total_bpp
155
156 !!! alpha_bip is undefined unless is_alpha_corpus or is_alpha_target
157
158 TODO Possibly pad pixel to size 8 for memory alignment, especially if vectorized.
159 */
160
161 /* !!! Not drawable->bpp because it includes other channels. */
162 /* Don't compare alpha */
163 //img_match_bpp = count_color_channels_target;
164 indices->img_match_bpp = count_color_channels_target;
165
166 /* Index of first color pixelel: 1, follows mask, use constant FIRST_PIXELEL_INDEX */
167 guint colorEndBip = FIRST_PIXELEL_INDEX + indices->img_match_bpp;
168 indices->colorEndBip = colorEndBip;
169
170 if ( is_alpha_target || is_alpha_source )
171 {
172 /* Allocate a pixelel for alpha. */
173 //alpha_bip = colorEndBip;
174 //map_start_bip = 1 + colorEndBip;
175 indices->alpha_bip = colorEndBip;
176 indices->map_start_bip = 1 + colorEndBip;
177 }
178 else
179 /* alpha_bip is undefined. */
180 //map_start_bip = colorEndBip;
181 indices->map_start_bip = colorEndBip;
182
183 /* Count pixelels to compare in maps. */
184 if ( isMap )
185 {
186 /*
187 Either, none, or both maps can have alpha, but it is discarded.
188 Both maps must have same count color pixelels, checked earlier.
189 */
190 //map_match_bpp = count_color_channels_map;
191 indices->map_match_bpp = count_color_channels_map;
192 }
193 else
194 //map_match_bpp =0;
195 indices->map_match_bpp =0;
196
197 //map_end_bip = map_start_bip + map_match_bpp;
198 //total_bpp = map_end_bip;
199 indices->map_end_bip = indices->map_start_bip + indices->map_match_bpp;
200 indices->total_bpp = indices->map_end_bip;
201
202 indices->isAlphaTarget = is_alpha_target;
203 indices->isAlphaSource = is_alpha_source;
204
205 // The patch struct has a limit on pixelels per pixel
206 g_assert( indices->total_bpp <= MAX_IMAGE_SYNTH_BPP);
207 }
208
209
210 // Test harness setter of pixel indices
211 void
prepareDefaultFormatIndices(TFormatIndices * formatIndices)212 prepareDefaultFormatIndices(
213 TFormatIndices* formatIndices
214 )
215 /*
216 Default is RGBA
217 For testing.
218
219 Engine internal pixel is:
220 MRGBA
221 012345
222 */
223 {
224 // !!! MASK_PIXELEL_INDEX is a constant (0); mask pixelel is first, always.
225
226 formatIndices->img_match_bpp = 3; // Match RGB but not A
227 formatIndices->colorEndBip = 4; // Pixelels 1-3 (2nd through 4th)
228 formatIndices->alpha_bip = 4; // Alpha bip must be defined: read but not synthesize
229 formatIndices->map_match_bpp = 0; // No map pixelels
230 formatIndices->map_start_bip = 5;
231 formatIndices->map_end_bip = 5;
232
233 formatIndices->total_bpp = 5;
234
235 formatIndices->isAlphaTarget = TRUE; // Does target have alpha?
236 formatIndices->isAlphaSource = TRUE;
237
238 // !!! isMap is not a field of format indices, use map_match_bpp
239 }
240
241
242