Make clang build as silent as possible
[fvs_assignment_project.git] / img_base.c
blob41f377b93233304bc3e8f02d5c6d4b0c73219bca
1 /*########################################################################
3 * Copyright(C) 2002-2007. All Rights Reserved.
5 * Authors: Shivang Patel
6 * Jaap de Haan(jdh)
8 * Changes: jdh -> Added support for ImageMagick that enables
9 * to export files to more than 40 formats.
10 * This is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2, or (at your option) any later
13 * version.
15 * This is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
20 * You should have received a copy of the GNU General Public License with
21 * the fvs source package as the
22 * file COPYING. If not, write to the Free Software Foundation, Inc.,
23 * 59 Temple Place - Suite 330, Boston, MA
24 * 02111-1307, USA.
25 ########################################################################*/
27 #include "fvs.h"
28 #include "img_base.h"
30 #include <math.h>
31 #include <stdlib.h>
32 #include <string.h>
35 /* Transform the gray image into a black & white binary image */
36 FvsError_t ImageBinarize(FvsImage_t image, const FvsByte_t limit)
38 FvsInt_t n;
39 FvsByte_t *pimg = ImageGetBuffer(image);
40 FvsInt_t size = ImageGetSize(image);
41 if (pimg==NULL)
42 return FvsMemory;
43 /* loop through each pixel */
44 for (n = 0; n < size; n++, pimg++)
46 /* now a do some math to decided if its white or black */
47 *pimg = (*pimg < limit)?(FvsByte_t)0xFF:(FvsByte_t)0x00;
49 return ImageSetFlag(image, FvsImageBinarized);
53 /* Invert image pixel values */
54 FvsError_t ImageInvert(FvsImage_t image)
56 FvsByte_t* pimg = ImageGetBuffer(image);
57 FvsInt_t size = ImageGetSize(image);
58 FvsInt_t n;
59 if (pimg==NULL)
60 return FvsMemory;
61 for (n = 0; n < size; n++, pimg++)
63 *pimg = 0xFF - *pimg;
65 return FvsOK;
69 /* compute the average of 2 images */
70 FvsError_t ImageAverage(FvsImage_t image1, const FvsImage_t image2)
72 FvsByte_t* p1 = ImageGetBuffer(image1);
73 FvsByte_t* p2 = ImageGetBuffer(image2);
74 FvsInt_t size1 = ImageGetSize(image1);
75 FvsInt_t size2 = ImageGetSize(image2);
76 FvsInt_t i;
78 if (p1==NULL || p2==NULL)
79 return FvsMemory;
80 if (size1!=size2)
81 return FvsBadParameter;
83 for (i = 0; i < size1; i++, p1++)
85 *p1 = (*p1+*p2++)>>1;
87 return FvsOK;
91 /* compute a logical operation */
92 FvsError_t ImageLogical
94 FvsImage_t image1,
95 const FvsImage_t image2,
96 const FvsLogical_t operation
99 FvsByte_t* p1 = ImageGetBuffer(image1);
100 FvsByte_t* p2 = ImageGetBuffer(image2);
101 FvsInt_t size1 = ImageGetSize(image1);
102 FvsInt_t i;
104 if (p1==NULL || p2==NULL)
105 return FvsMemory;
106 if (ImageCompareSize(image1, image2)==FvsFalse)
107 return FvsBadParameter;
109 switch (operation)
111 case FvsLogicalOr:
112 for (i = 0; i < size1; i++, p1++)
113 *p1 = (*p1) | (*p2++);
114 break;
115 case FvsLogicalAnd:
116 for (i = 0; i < size1; i++, p1++)
117 *p1 = (*p1) & (*p2++);
118 break;
119 case FvsLogicalXor:
120 for (i = 0; i < size1; i++, p1++)
121 *p1 = (*p1) ^ (*p2++);
122 break;
123 case FvsLogicalNAnd:
124 for (i = 0; i < size1; i++, p1++)
125 *p1 = ~((*p1) & (*p2++));
126 break;
127 case FvsLogicalNOr:
128 for (i = 0; i < size1; i++, p1++)
129 *p1 = ~((*p1) | (*p2++));
130 break;
131 case FvsLogicalNXor:
132 for (i = 0; i < size1; i++, p1++)
133 *p1 = ~((*p1) ^ (*p2++));
134 break;
136 return FvsOK;
140 /* compute the average of 2 images modulo 256 */
141 FvsError_t ImageAverageModulo(FvsImage_t image1, const FvsImage_t image2)
143 FvsByte_t* p1 = ImageGetBuffer(image1);
144 FvsByte_t* p2 = ImageGetBuffer(image2);
145 FvsInt_t size1 = ImageGetSize(image1);
146 FvsInt_t size2 = ImageGetSize(image2);
147 FvsInt_t i;
148 FvsByte_t v1, v2;
150 if (size1!=size2)
151 return FvsBadParameter;
153 if (p1==NULL || p2==NULL)
154 return FvsMemory;
156 for (i = 0; i < size1; i++)
158 v1 = *p1;
159 v2 = *p2;
160 if (v1<128) v1+=256;
161 if (v2<128) v2+=256;
162 v1 += v2;
163 v1 >>=1;
164 v1 = v1%256;
165 *p1++ = (uint8_t)v1;
167 return FvsOK;
170 #define P(x,y) p[((x)+(y)*pitch)]
173 /* create a test image composed of stripes */
174 FvsError_t ImageStripes(FvsImage_t image, const FvsBool_t horizontal)
176 FvsByte_t* p = ImageGetBuffer(image);
177 FvsInt_t w = ImageGetWidth (image);
178 FvsInt_t h = ImageGetHeight(image);
179 FvsInt_t pitch = ImageGetPitch (image);
180 FvsInt_t x,y;
181 if (p==NULL)
182 return FvsMemory;
183 if (horizontal==FvsFalse)
185 for (y = 0; y < h; y++)
186 for (x = 0; x < w; x++)
187 P(x,y) = (FvsByte_t)x%256;
189 else
191 for (y = 0; y < h; y++)
192 for (x = 0; x < w; x++)
193 P(x,y) = (FvsByte_t)y%256;
195 return FvsOK;
199 /*rewritten by petertu */
200 /* Normalize an image pixel-wise so that it gets a maximum local variance */
201 FvsError_t ImagePixelNormalize(FvsImage_t image, const FvsInt_t size)
203 FvsByte_t* p1 = ImageGetBuffer(image);
204 FvsByte_t* p2;
205 FvsInt_t w = ImageGetWidth (image);
206 FvsInt_t h = ImageGetHeight(image);
207 FvsInt_t pitch = ImageGetPitch (image);
208 FvsInt_t pitch2;
209 FvsInt_t x,y,s,p,q, min, max;
210 FvsFloat_t fgray;
211 FvsImage_t im2;
213 im2 = ImageCreate();
215 if (im2==NULL || p1==NULL)
216 return FvsMemory;
218 s = size/2; /* size */
219 if (size<=0)
220 return FvsBadParameter;
222 /* copy image to make the computation */
223 ImageCopy(im2, image);
224 p2 = ImageGetBuffer(im2);
225 if (p2==NULL)
227 ImageDestroy(im2);
228 return FvsMemory;
230 pitch2 = ImageGetPitch (im2);
232 for (y = 0; y < h; y++)
233 for (x = 0; x < w; x++)
235 min=255;
236 max=0;
237 for (q=-s;q<=s;q++)
238 for (p=-s;p<=s;p++)
240 if(x+p >= 0 && x+p < w && y+q >= 0 && y+q < h) {
241 max = p2[(x+p)+(y+q)*pitch2] > max ? p2[(x+p)+(y+q)*pitch2] : max;
242 min = p2[(x+p)+(y+q)*pitch2] < min ? p2[(x+p)+(y+q)*pitch2] : min;
245 // fgray = (FvsFloat_t)p2[x + y*pitch2]*255.0/(FvsFloat_t)max*(1.0-(FvsFloat_t)min/255.0);
246 fgray = ((FvsFloat_t)(p2[x + y*pitch2] - min))/((FvsFloat_t)(max-min)) * 255;
247 if(fgray > 255.0)
248 fgray = 255.0;
249 if (fgray < 0)
250 fgray = 0;
252 p1[x + y*pitch] = fgray;
255 ImageDestroy(im2);
256 return FvsOK;
262 /* change the luminosity of an image argument ranging [-255..255] */
263 FvsError_t ImageLuminosity(FvsImage_t image, const FvsInt_t luminosity)
265 FvsByte_t* p = ImageGetBuffer(image);
266 FvsInt_t w = ImageGetWidth (image);
267 FvsInt_t h = ImageGetHeight(image);
268 FvsInt_t pitch = ImageGetPitch (image);
269 FvsInt_t x,y;
270 FvsFloat_t fgray, a, b;
271 if (p==NULL)
272 return FvsMemory;
273 if (luminosity>0)
275 a = (255.0 - abs(luminosity)) / 255.0;
276 b = (FvsFloat_t)luminosity;
278 else
280 a = (255.0 - abs(luminosity)) / 255.0;
281 b = 0.0;
283 for (y = 0; y < h; y++)
284 for (x = 0; x < w; x++)
286 fgray = (FvsFloat_t)P(x,y);
287 fgray = b + a*fgray;
288 if (fgray < 0.0) fgray = 0.0;
289 if (fgray > 255.0) fgray = 255.0;
290 P(x,y)= (uint8_t)fgray;
292 return FvsOK;
296 /* change the contrast of an image argument ranging [-127..127] */
297 FvsError_t ImageContrast(FvsImage_t image, const FvsInt_t contrast)
299 FvsByte_t* p = ImageGetBuffer(image);
300 FvsInt_t w = ImageGetWidth (image);
301 FvsInt_t h = ImageGetHeight(image);
302 FvsInt_t pitch = ImageGetPitch (image);
303 FvsInt_t x,y;
304 FvsFloat_t fgray, a, b;
305 if (p==NULL)
306 return FvsMemory;
307 a = (FvsFloat_t)((127.0 + contrast) / 127.0);
308 b = (FvsFloat_t)(-contrast);
309 for (y = 0; y < h; y++)
310 for (x = 0; x < w; x++)
312 fgray = (FvsFloat_t)P(x,y);
313 fgray = b + a*fgray;
314 if (fgray < 0.0) fgray = 0.0;
315 if (fgray > 255.0) fgray = 255.0;
316 P(x,y)= (uint8_t)fgray;
318 return FvsOK;
322 FvsError_t ImageSoftenMean(FvsImage_t image, const FvsInt_t size)
324 FvsByte_t* p1 = ImageGetBuffer(image);
325 FvsByte_t* p2;
326 FvsInt_t w = ImageGetWidth (image);
327 FvsInt_t h = ImageGetHeight(image);
328 FvsInt_t pitch = ImageGetPitch (image);
329 FvsInt_t pitch2;
330 FvsInt_t x,y,s,p,q,a,c;
331 FvsImage_t im2;
333 im2 = ImageCreate();
335 if (im2==NULL || p1==NULL)
336 return FvsMemory;
338 s = size/2; /* size */
339 a = size*size; /* area */
340 if (a==0)
341 return FvsBadParameter;
343 /* copy image to make the computation */
344 ImageCopy(im2, image);
345 p2 = ImageGetBuffer(im2);
346 if (p2==NULL)
348 ImageDestroy(im2);
349 return FvsMemory;
351 pitch2 = ImageGetPitch (im2);
353 for (y = s; y < h-s; y++)
354 for (x = s; x < w-s; x++)
356 c = 0;
357 for (q=-s;q<=s;q++)
358 for (p=-s;p<=s;p++)
360 c += p2[(x+p)+(y+q)*pitch2];
362 p1[x+y*pitch] = c/a;
365 ImageDestroy(im2);
366 return FvsOK;
372 /* Use a structural operator to dilate the image
373 ** X
374 ** X X X
375 ** X
377 FvsError_t ImageDilate(FvsImage_t image)
379 FvsInt_t w = ImageGetWidth (image);
380 FvsInt_t h = ImageGetHeight(image);
381 FvsInt_t pitch = ImageGetPitch (image);
382 FvsInt_t size = ImageGetSize (image);
383 FvsByte_t* p = ImageGetBuffer(image);
384 FvsInt_t x,y;
386 if (p==NULL)
387 return FvsMemory;
389 for (y=1; y<h-1; y++)
390 for (x=1; x<w-1; x++)
392 if (P(x,y)==0xFF)
394 P(x-1, y) |= 0x80;
395 P(x+1, y) |= 0x80;
396 P(x, y-1) |= 0x80;
397 P(x, y+1) |= 0x80;
401 for (y=0; y<size; y++)
402 if (p[y])
403 p[y] = 0xFF;
405 return FvsOK;
408 FvsError_t ImageErode(FvsImage_t image)
410 FvsInt_t w = ImageGetWidth (image);
411 FvsInt_t h = ImageGetHeight(image);
412 FvsInt_t pitch = ImageGetPitch (image);
413 FvsInt_t size = ImageGetSize (image);
414 FvsByte_t* p = ImageGetBuffer(image);
415 FvsInt_t x,y;
417 if (p==NULL)
418 return FvsMemory;
420 for (y=1; y<h-1; y++)
421 for (x=1; x<w-1; x++)
423 if (P(x,y)==0x0)
425 P(x-1, y) &= 0x80;
426 P(x+1, y) &= 0x80;
427 P(x, y-1) &= 0x80;
428 P(x, y+1) &= 0x80;
432 for (y=0; y<size; y++)
433 if (p[y]!=0xFF)
434 p[y] = 0x0;
436 return FvsOK;