Merge evaluate() functionnality into find_edges(), get delta for missed edges.
[goir.git] / sImLib / img_path.hh
blob54789f3500af88a5549ad9369a38b51398d4ce81
1 #ifndef _SIMLIB_IMGPATH_HH
2 #define _SIMLIB_IMGPATH_HH
4 #include <algorithm>
5 #include <cstdlib>
7 /*
8 * Walking macros from this file are adapted from CImg drawing
9 * methods.
12 // FIXME: width cropping does not work !?
15 * forline:
17 * Run body_code over all pixels of the (x0,y0)-(x1,y1) line.
19 * Demo example:
20 * sImLib_forline(img, x, y, ptrd,
21 * 0, 0, img.width, img.height,
22 * if (x%2)
23 * *ptrd = blue[k];
24 * else
25 * *ptrd = red[k];
26 * printf("%d,%d ", x, y);
27 * );
29 #define sImLib_forline(img,ptrd,x0,y0,x1,y1,body_code) \
30 do { \
31 int nx0 = (x0), nx1 = (x1), ny0 = (y0), ny1 = (y1); \
33 if (nx0>nx1) { std::swap(nx0,nx1); std::swap(ny0,ny1); } \
34 if (nx1<0 || nx0>=(int)(img)->width) break; \
35 if (nx0<0) { ny0-=nx0*(ny1-ny0)/(nx1-nx0); nx0=0; } \
36 if (nx1>=(int)(img)->width) \
37 { ny1+=(nx1-(img)->width)*(ny0-ny1)/(nx1-nx0); nx1=(img)->width-1;} \
38 if (ny0>ny1) { std::swap(nx0,nx1); std::swap(ny0,ny1); } \
39 if (ny1<0 || ny0>=(int)(img)->height) break; \
40 if (ny0<0) { nx0-=ny0*(nx1-nx0)/(ny1-ny0); ny0=0; } \
41 if (ny1>=(int)(img)->height) \
42 { nx1+=(ny1-(img)->height)*(nx0-nx1)/(ny1-ny0); ny1=(img)->height-1;} \
44 const bool steep = (ny1-ny0)>std::abs(nx1-nx0); \
45 if (steep) { std::swap(nx0,ny0); std::swap(nx1,ny1); } \
46 if (nx0>nx1) { std::swap(nx0,nx1); std::swap(ny0,ny1); } \
47 const int \
48 dx = nx1-nx0, dy = std::abs(ny1-ny0), \
49 offx = steep?(img)->width:1, \
50 offy = (ny0<ny1?1:-1)*(steep?1:(img)->width); \
52 sImLib::pixel *ptrd = steep?(img)->ptr(ny0,nx0):(img)->ptr(nx0,ny0); \
53 for (int error=0, _x=nx0, linechange=0; \
54 _x <= nx1; \
55 _x++, linechange=(((error+=dy)<<1)>=dx), \
56 ptrd+=offx, ptrd+=offy*linechange, error-=dx*linechange) \
57 do { body_code; } while(0); \
58 } while(0)
60 #endif // _SIMLIB_IMGPATH_HH