1 #include "AutoPanoSift.h"
2
3 /* This is a replacement for the "GUIImage-Drawing.cs" */
4 /* the code is wrapping a libpano12 Image structure */
5
DisplayImage_new0()6 DisplayImage* DisplayImage_new0() {
7 DisplayImage* self = (DisplayImage*)malloc(sizeof(DisplayImage));
8 self->data = NULL;
9 return self;
10 }
11
DisplayImage_new(char * filename)12 DisplayImage* DisplayImage_new(char* filename) {
13 DisplayImage* self = DisplayImage_new0();
14 fullPath filePath;
15 if (StringtoFullPath(&filePath, filename) != 0) {
16 FatalError("Syntax error: Not a valid pathname");
17 }
18 #ifdef HAS_PANO13
19 if ( panoImageRead(self, &filePath) == FALSE ) {
20 FatalError("Syntax error: Not a valid image");
21 }
22 #else
23 if( readImage(self, &filePath) != 0) {
24 FatalError("Syntax error: Not a valid image");
25 }
26 #endif
27
28 return self;
29 }
30
DisplayImage_delete(DisplayImage * self)31 void DisplayImage_delete(DisplayImage* self) {
32 if (self) {
33 if (self->data) {
34 myfree((void**)self->data);
35 self->data = NULL;
36 }
37 free(self);
38 }
39 }
40
DisplayImage_ScaleSimple(DisplayImage * self,int width,int height)41 DisplayImage* DisplayImage_ScaleSimple(DisplayImage* self, int width, int height)
42 {
43 DisplayImage* im = DisplayImage_new0();
44 memcpy(im, self, sizeof(DisplayImage));
45
46 im->width = width;
47 im->height = height;
48 im->bytesPerLine = im->width * im->bitsPerPixel/8;
49 im->dataSize = im->bytesPerLine * im->height;
50 im->data = (unsigned char**) mymalloc( im->dataSize );
51 if (im->data == NULL) {
52 FatalError("out of memory!");
53 }
54 Image* src = self;
55 Image* dest = im;
56
57
58 /* modified copy from libpano12:filter.c:CopyImageData */
59
60 register unsigned char *in, *out;
61 register int x,y, id, is, i;
62 int bpp_s, bpp_d;
63 double sx, sy;
64
65 in = *(src->data);
66 out = *(dest->data);
67 sx = (double)src->width / (double)dest->width;
68 sy = (double)src->height / (double)dest->height;
69 bpp_s = src->bitsPerPixel / 8;
70 bpp_d = dest->bitsPerPixel / 8;
71
72 for( y = 0; y < dest->height; y++)
73 {
74 for( x = 0; x < dest->width; x++)
75 {
76 is = (int)(y * sy) * src->bytesPerLine + bpp_s * (int)(x * sx);
77 id = y * dest->bytesPerLine + bpp_d * x;
78
79 if( (int)(y * sy) < 0 || (int)(y * sy) >= src->height ||
80 (int)(x * sx) < 0 || (int)(x * sx) >= src->width ) // outside src; set dest = 0
81 {
82 i = bpp_d;
83 while( i-- > 0 ) out[ id++ ] = 0;
84 }
85 else // inside src; set dest = src
86 {
87 switch( bpp_d )
88 {
89 case 8: switch( bpp_s )
90 {
91 case 8: memcpy( out + id, in + is, 8 );
92 break;
93 case 6: out[id++] = 255U; out[id++] = 255U;
94 memcpy( out + id, in + is, 6 );
95 break;
96 case 4: out[id++] = in[ is++ ]; out[id++] = 0;
97 out[id++] = in[ is++ ]; out[id++] = 0;
98 out[id++] = in[ is++ ]; out[id++] = 0;
99 out[id++] = in[ is++ ]; out[id++] = 0;
100 break;
101 case 3: out[id++] = 255U; out[id++] = 255U;
102 out[id++] = in[ is++ ]; out[id++] = 0;
103 out[id++] = in[ is++ ]; out[id++] = 0;
104 out[id++] = in[ is++ ]; out[id++] = 0;
105 break;
106 }
107 break;
108 case 6: switch( bpp_s )
109 {
110 case 8: is += 2;
111 memcpy( out + id, in + is, 6 );
112 break;
113 case 6: memcpy( out + id, in + is, 6 );
114 break;
115 case 4: is++;
116 out[id++] = in[ is++ ]; out[id++] = 0;
117 out[id++] = in[ is++ ]; out[id++] = 0;
118 out[id++] = in[ is++ ]; out[id++] = 0;
119 break;
120 case 3: out[id++] = in[ is++ ]; out[id++] = 0;
121 out[id++] = in[ is++ ]; out[id++] = 0;
122 out[id++] = in[ is++ ]; out[id++] = 0;
123 break;
124 }
125 break;
126
127 case 4: switch( bpp_s )
128 {
129 case 8: out[id++] = in[ is++ ]; is++;
130 out[id++] = in[ is++ ]; is++;
131 out[id++] = in[ is++ ]; is++;
132 out[id++] = in[ is++ ]; is++;
133 break;
134 case 6: out[id++] = 255U;
135 out[id++] = in[ is++ ]; is++;
136 out[id++] = in[ is++ ]; is++;
137 out[id++] = in[ is++ ]; is++;
138 break;
139 case 4: memcpy( out + id, in + is, 4 );
140 break;
141 case 3: out[id++] = 255U;
142 memcpy( out + id, in + is, 3 );
143 break;
144 }
145 break;
146
147 case 3: switch( bpp_s )
148 {
149 case 8: is+=2;
150 out[id++] = in[ is++ ]; is++;
151 out[id++] = in[ is++ ]; is++;
152 out[id++] = in[ is++ ]; is++;
153 break;
154 case 6: out[id++] = in[ is++ ]; is++;
155 out[id++] = in[ is++ ]; is++;
156 out[id++] = in[ is++ ]; is++;
157 break;
158 case 4: is++;
159 memcpy( out + id, in + is, 3 );
160 break;
161 case 3: memcpy( out + id, in + is, 3 );
162 break;
163 }
164 break;
165
166 }
167 }
168 }
169 }
170
171 return im;
172 }
173
DisplayImage_ScaleWithin(DisplayImage * self,int dim)174 double DisplayImage_ScaleWithin(DisplayImage* self, int dim) {
175
176 if (self->width <= dim && self->height <= dim)
177 return (1.0);
178
179 double xScale = ((double) dim / self->width);
180 double yScale = ((double) dim / self->height);
181 double smallestScale = xScale <= yScale ? xScale : yScale;
182
183 DisplayImage* scaled = DisplayImage_ScaleSimple (self,
184 (int) (self->width * smallestScale+0.0001),
185 (int) (self->height * smallestScale+0.0001));
186
187 if (self->data) {
188 myfree((void**)self->data);
189 }
190 memmove(self, scaled, sizeof(DisplayImage));
191 free(scaled);
192
193 return (smallestScale);
194 }
195
DisplayImage_Carve(DisplayImage * self,int dx,int dy,int width,int height)196 DisplayImage* DisplayImage_Carve(DisplayImage* self, int dx, int dy, int width, int height)
197 {
198 DisplayImage* result = DisplayImage_new0();
199 memcpy(result, self, sizeof(DisplayImage));
200
201 result->width = width;
202 result->height = height;
203 result->bytesPerLine = result->width * result->bitsPerPixel/8;
204 result->dataSize = result->bytesPerLine * result->height;
205 result->data = (unsigned char**) mymalloc( result->dataSize );
206 if (result->data == NULL) {
207 FatalError("out of memory!");
208 }
209
210 Image* src = self;
211 Image* dest = result;
212
213 /* modified copy from libpano12:filter.c:CopyImageData */
214 register unsigned char *in, *out;
215 register int x,y, id, is, i;
216 int bpp_s, bpp_d;
217
218 in = *(src->data);
219 out = *(dest->data);
220 //dx = (src->width - dest->width) / 2;
221 //dy = (src->height - dest->height) / 2;
222 bpp_s = src->bitsPerPixel / 8;
223 bpp_d = dest->bitsPerPixel / 8;
224
225 for( y = 0; y < dest->height; y++)
226 {
227 for( x = 0; x < dest->width; x++)
228 {
229 is = (y + dy) * src->bytesPerLine + bpp_s * (x + dx);
230 id = y * dest->bytesPerLine + bpp_d * x;
231
232 if( y + dy < 0 || y + dy >= src->height ||
233 x + dx < 0 || x + dx >= src->width ) // outside src; set dest = 0
234 {
235 i = bpp_d;
236 while( i-- > 0 ) out[ id++ ] = 0;
237 }
238 else // inside src; set dest = src
239 {
240 switch( bpp_d )
241 {
242 case 8: switch( bpp_s )
243 {
244 case 8: memcpy( out + id, in + is, 8 );
245 break;
246 case 6: out[id++] = 255U; out[id++] = 255U;
247 memcpy( out + id, in + is, 6 );
248 break;
249 case 4: out[id++] = in[ is++ ]; out[id++] = 0;
250 out[id++] = in[ is++ ]; out[id++] = 0;
251 out[id++] = in[ is++ ]; out[id++] = 0;
252 out[id++] = in[ is++ ]; out[id++] = 0;
253 break;
254 case 3: out[id++] = 255U; out[id++] = 255U;
255 out[id++] = in[ is++ ]; out[id++] = 0;
256 out[id++] = in[ is++ ]; out[id++] = 0;
257 out[id++] = in[ is++ ]; out[id++] = 0;
258 break;
259 }
260 break;
261 case 6: switch( bpp_s )
262 {
263 case 8: is += 2;
264 memcpy( out + id, in + is, 6 );
265 break;
266 case 6: memcpy( out + id, in + is, 6 );
267 break;
268 case 4: is++;
269 out[id++] = in[ is++ ]; out[id++] = 0;
270 out[id++] = in[ is++ ]; out[id++] = 0;
271 out[id++] = in[ is++ ]; out[id++] = 0;
272 break;
273 case 3: out[id++] = in[ is++ ]; out[id++] = 0;
274 out[id++] = in[ is++ ]; out[id++] = 0;
275 out[id++] = in[ is++ ]; out[id++] = 0;
276 break;
277 }
278 break;
279
280 case 4: switch( bpp_s )
281 {
282 case 8: out[id++] = in[ is++ ]; is++;
283 out[id++] = in[ is++ ]; is++;
284 out[id++] = in[ is++ ]; is++;
285 out[id++] = in[ is++ ]; is++;
286 break;
287 case 6: out[id++] = 255U;
288 out[id++] = in[ is++ ]; is++;
289 out[id++] = in[ is++ ]; is++;
290 out[id++] = in[ is++ ]; is++;
291 break;
292 case 4: memcpy( out + id, in + is, 4 );
293 break;
294 case 3: out[id++] = 255U;
295 memcpy( out + id, in + is, 3 );
296 break;
297 }
298 break;
299
300 case 3: switch( bpp_s )
301 {
302 case 8: is+=2;
303 out[id++] = in[ is++ ]; is++;
304 out[id++] = in[ is++ ]; is++;
305 out[id++] = in[ is++ ]; is++;
306 break;
307 case 6: out[id++] = in[ is++ ]; is++;
308 out[id++] = in[ is++ ]; is++;
309 out[id++] = in[ is++ ]; is++;
310 break;
311 case 4: is++;
312 memcpy( out + id, in + is, 3 );
313 break;
314 case 3: memcpy( out + id, in + is, 3 );
315 break;
316 }
317 break;
318
319 }
320 }
321 }
322 }
323 return result;
324 }
325
DisplayImage_ConvertToImageMap(DisplayImage * self)326 ImageMap* DisplayImage_ConvertToImageMap(DisplayImage* self) //// dbl <= float
327 {
328 ImageMap* result = ImageMap_new(self->width, self->height);
329 if (self->bitsPerPixel == 32) {
330 LOOP_IMAGE(self,{
331 /* Data is (alpha,R,G,B) */
332 result->values[x][y] = (float)(((double)idata[1]+idata[2]+idata[3])/(255.0 * 3.0));
333 });
334 } else if (self->bitsPerPixel == 64) {
335 LOOP_IMAGE(self,{
336 unsigned short *udata=(unsigned short *)idata;
337 /* Data is (alpha,R,G,B) */
338 result->values[x][y] = (float)(((double)udata[1]+udata[2]+udata[3])/(65535 * 3.0));
339 });
340 } else {
341 /* It appears that TIFF library calls used (TIFFReadRGBA), will always return 32 or 64-bit, but just in case... */
342 FatalError("DisplayImage: Unsupported pixel size");
343 }
344 return result;
345 }
346