|
|
@@ -109,11 +109,12 @@ static int NUM_CHARACTERS; |
|
|
|
static int MAX_ITERATIONS; |
|
|
|
static unsigned int TOTAL_CELLS; |
|
|
|
|
|
|
|
#define RANGE_SY (RANGE_S*RANGE_Y) |
|
|
|
#define RANGE_SYX (RANGE_S*RANGE_Y*RANGE_X) |
|
|
|
#define RANGE_SYXR (RANGE_S*RANGE_Y*RANGE_X*RANGE_R) |
|
|
|
#define RANGE_SYXRG (RANGE_S*RANGE_Y*RANGE_X*RANGE_R*RANGE_G) |
|
|
|
#define RANGE_SYXRGB (RANGE_S*RANGE_Y*RANGE_X*RANGE_R*RANGE_G*RANGE_B) |
|
|
|
#define RANGE_XY (RANGE_Y*RANGE_X) |
|
|
|
#define RANGE_RXY (RANGE_Y*RANGE_X*RANGE_R) |
|
|
|
#define RANGE_GRXY (RANGE_Y*RANGE_X*RANGE_R*RANGE_G) |
|
|
|
#define RANGE_BGRXY (RANGE_Y*RANGE_X*RANGE_R*RANGE_G*RANGE_B) |
|
|
|
#define RANGE_SBGRXY (RANGE_Y*RANGE_X*RANGE_R*RANGE_G*RANGE_B*RANGE_S) |
|
|
|
#define RANGE_SBGR (RANGE_R*RANGE_G*RANGE_B*RANGE_S) |
|
|
|
|
|
|
|
struct K : CGAL::Exact_predicates_inexact_constructions_kernel {}; |
|
|
|
typedef CGAL::Delaunay_triangulation_2<K> Delaunay_triangulation; |
|
|
@@ -139,13 +140,13 @@ void compute_ranges(int width, int height) |
|
|
|
HEADER_BITS = logf(RANGE_W * RANGE_H) / logf(2); |
|
|
|
DATA_BITS = TOTAL_BITS - HEADER_BITS; |
|
|
|
#if POINTS_PER_CELL == 1 |
|
|
|
CELL_BITS = logf(RANGE_SYXRGB) / logf(2); |
|
|
|
CELL_BITS = logf(RANGE_SBGRXY) / logf(2); |
|
|
|
#else |
|
|
|
// TODO: implement the following shit |
|
|
|
//float coord_bits = logf((RANGE_Y * RANGE_X) * (RANGE_Y * RANGE_X + 1) / 2); |
|
|
|
//float other_bits = logf(RANGE_R * RANGE_G * RANGE_B * RANGE_S); |
|
|
|
//CELL_BITS = (coord_bits + 2 * other_bits) / logf(2); |
|
|
|
CELL_BITS = 2 * logf(RANGE_SYXRGB) / logf(2); |
|
|
|
CELL_BITS = 2 * logf(RANGE_SBGRXY) / logf(2); |
|
|
|
#endif |
|
|
|
TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS); |
|
|
|
MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS; |
|
|
@@ -509,8 +510,8 @@ static inline void set_point(int index, float x, float y, float r, |
|
|
|
int ig = range2int(g, RANGE_G); |
|
|
|
int ib = range2int(b, RANGE_B); |
|
|
|
|
|
|
|
points[index] = is + RANGE_S * (iy + RANGE_Y * (ix + RANGE_X * |
|
|
|
(ib + RANGE_B * (ig + (RANGE_R * ir))))); |
|
|
|
points[index] = iy + RANGE_Y * (ix + RANGE_X * (ib + RANGE_B * |
|
|
|
(ig + (RANGE_R * ir + (RANGE_S * is))))); |
|
|
|
} |
|
|
|
|
|
|
|
static inline void get_point(int index, float *x, float *y, float *r, |
|
|
@@ -521,8 +522,6 @@ static inline void get_point(int index, float *x, float *y, float *r, |
|
|
|
|
|
|
|
index2cell(index, &dx, &dy); |
|
|
|
|
|
|
|
*s = int2fullrange(pt % RANGE_S, RANGE_S); pt /= RANGE_S; |
|
|
|
|
|
|
|
float fy = int2midrange(pt % RANGE_Y, RANGE_Y); pt /= RANGE_Y; |
|
|
|
float fx = int2midrange(pt % RANGE_X, RANGE_X); pt /= RANGE_X; |
|
|
|
|
|
|
@@ -541,6 +540,8 @@ static inline void get_point(int index, float *x, float *y, float *r, |
|
|
|
*g = int2midrange(pt % RANGE_G, RANGE_G); pt /= RANGE_G; |
|
|
|
*r = int2midrange(pt % RANGE_B, RANGE_B); pt /= RANGE_B; |
|
|
|
} |
|
|
|
|
|
|
|
*s = int2fullrange(pt % RANGE_S, RANGE_S); pt /= RANGE_S; |
|
|
|
} |
|
|
|
|
|
|
|
static void add_point(float x, float y, float r, float g, float b, float s) |
|
|
@@ -552,7 +553,7 @@ static void add_point(float x, float y, float r, float g, float b, float s) |
|
|
|
#if 0 |
|
|
|
static void add_random_point() |
|
|
|
{ |
|
|
|
points[npoints] = det_rand(RANGE_SYXRGB); |
|
|
|
points[npoints] = det_rand(RANGE_SBGRXY); |
|
|
|
npoints++; |
|
|
|
} |
|
|
|
#endif |
|
|
@@ -586,27 +587,28 @@ static uint32_t apply_op(uint8_t op, uint32_t val) |
|
|
|
case 1: |
|
|
|
/* Statistics show that this helps often, but does not reduce |
|
|
|
* the error significantly. */ |
|
|
|
return val ^ 1; |
|
|
|
rem = val % RANGE_BGRXY; |
|
|
|
ext = val / RANGE_BGRXY; |
|
|
|
ext ^= 1; |
|
|
|
return ext * RANGE_BGRXY + rem; |
|
|
|
case 2: /* Move up; if impossible, down */ |
|
|
|
rem = val % RANGE_S; |
|
|
|
ext = (val / RANGE_S) % RANGE_Y; |
|
|
|
ext = val % RANGE_Y; |
|
|
|
ext = ext > 0 ? ext - 1 : ext + 1; |
|
|
|
return (val / RANGE_SY * RANGE_Y + ext) * RANGE_S + rem; |
|
|
|
return val / RANGE_Y * RANGE_Y + ext; |
|
|
|
case 3: /* Move down; if impossible, up */ |
|
|
|
rem = val % RANGE_S; |
|
|
|
ext = (val / RANGE_S) % RANGE_Y; |
|
|
|
ext = val % RANGE_Y; |
|
|
|
ext = ext < RANGE_Y - 1 ? ext + 1 : ext - 1; |
|
|
|
return (val / RANGE_SY * RANGE_Y + ext) * RANGE_S + rem; |
|
|
|
return val / RANGE_Y * RANGE_Y + ext; |
|
|
|
case 4: /* Move left; if impossible, right */ |
|
|
|
rem = val % RANGE_SY; |
|
|
|
ext = (val / RANGE_SY) % RANGE_X; |
|
|
|
rem = val % RANGE_Y; |
|
|
|
ext = (val / RANGE_Y) % RANGE_X; |
|
|
|
ext = ext > 0 ? ext - 1 : ext + 1; |
|
|
|
return (val / RANGE_SYX * RANGE_X + ext) * RANGE_SY + rem; |
|
|
|
return (val / RANGE_XY * RANGE_X + ext) * RANGE_Y + rem; |
|
|
|
case 5: /* Move left; if impossible, right */ |
|
|
|
rem = val % RANGE_SY; |
|
|
|
ext = (val / RANGE_SY) % RANGE_X; |
|
|
|
rem = val % RANGE_Y; |
|
|
|
ext = (val / RANGE_Y) % RANGE_X; |
|
|
|
ext = ext < RANGE_X - 1 ? ext + 1 : ext - 1; |
|
|
|
return (val / RANGE_SYX * RANGE_X + ext) * RANGE_SY + rem; |
|
|
|
return (val / RANGE_XY * RANGE_X + ext) * RANGE_Y + rem; |
|
|
|
case 6: /* Corner 1 */ |
|
|
|
return apply_op(2, apply_op(4, val)); |
|
|
|
case 7: /* Corner 2 */ |
|
|
@@ -624,35 +626,35 @@ static uint32_t apply_op(uint8_t op, uint32_t val) |
|
|
|
case 19: /* Double right */ |
|
|
|
return apply_op(5, apply_op(5, val)); |
|
|
|
case 10: /* R-- (or R++) */ |
|
|
|
rem = val % RANGE_SYX; |
|
|
|
ext = (val / RANGE_SYX) % RANGE_R; |
|
|
|
rem = val % RANGE_XY; |
|
|
|
ext = (val / RANGE_XY) % RANGE_R; |
|
|
|
ext = ext > 0 ? ext - 1 : ext + 1; |
|
|
|
return (val / RANGE_SYXR * RANGE_R + ext) * RANGE_SYX + rem; |
|
|
|
return (val / RANGE_RXY * RANGE_R + ext) * RANGE_XY + rem; |
|
|
|
case 11: /* R++ (or R--) */ |
|
|
|
rem = val % RANGE_SYX; |
|
|
|
ext = (val / RANGE_SYX) % RANGE_R; |
|
|
|
rem = val % RANGE_XY; |
|
|
|
ext = (val / RANGE_XY) % RANGE_R; |
|
|
|
ext = ext < RANGE_R - 1 ? ext + 1 : ext - 1; |
|
|
|
return (val / RANGE_SYXR * RANGE_R + ext) * RANGE_SYX + rem; |
|
|
|
return (val / RANGE_RXY * RANGE_R + ext) * RANGE_XY + rem; |
|
|
|
case 12: /* G-- (or G++) */ |
|
|
|
rem = val % RANGE_SYXR; |
|
|
|
ext = (val / RANGE_SYXR) % RANGE_G; |
|
|
|
rem = val % RANGE_RXY; |
|
|
|
ext = (val / RANGE_RXY) % RANGE_G; |
|
|
|
ext = ext > 0 ? ext - 1 : ext + 1; |
|
|
|
return (val / RANGE_SYXRG * RANGE_G + ext) * RANGE_SYXR + rem; |
|
|
|
return (val / RANGE_GRXY * RANGE_G + ext) * RANGE_RXY + rem; |
|
|
|
case 13: /* G++ (or G--) */ |
|
|
|
rem = val % RANGE_SYXR; |
|
|
|
ext = (val / RANGE_SYXR) % RANGE_G; |
|
|
|
rem = val % RANGE_RXY; |
|
|
|
ext = (val / RANGE_RXY) % RANGE_G; |
|
|
|
ext = ext < RANGE_G - 1 ? ext + 1 : ext - 1; |
|
|
|
return (val / RANGE_SYXRG * RANGE_G + ext) * RANGE_SYXR + rem; |
|
|
|
return (val / RANGE_GRXY * RANGE_G + ext) * RANGE_RXY + rem; |
|
|
|
case 14: /* B-- (or B++) */ |
|
|
|
rem = val % RANGE_SYXRG; |
|
|
|
ext = (val / RANGE_SYXRG) % RANGE_B; |
|
|
|
rem = val % RANGE_GRXY; |
|
|
|
ext = (val / RANGE_GRXY) % RANGE_B; |
|
|
|
ext = ext > 0 ? ext - 1 : ext + 1; |
|
|
|
return ext * RANGE_SYXRG + rem; |
|
|
|
return (val / RANGE_BGRXY * RANGE_B + ext) * RANGE_GRXY + rem; |
|
|
|
case 15: /* B++ (or B--) */ |
|
|
|
rem = val % RANGE_SYXRG; |
|
|
|
ext = (val / RANGE_SYXRG) % RANGE_B; |
|
|
|
rem = val % RANGE_GRXY; |
|
|
|
ext = (val / RANGE_GRXY) % RANGE_B; |
|
|
|
ext = ext < RANGE_B - 1 ? ext + 1 : ext - 1; |
|
|
|
return ext * RANGE_SYXRG + rem; |
|
|
|
return (val / RANGE_BGRXY * RANGE_B + ext) * RANGE_GRXY + rem; |
|
|
|
#if 0 |
|
|
|
case 15: /* Brightness-- */ |
|
|
|
return apply_op(9, apply_op(11, apply_op(13, val))); |
|
|
@@ -1268,8 +1270,17 @@ int main(int argc, char *argv[]) |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Push our points to the bitstream */ |
|
|
|
for(int i = 0; i < npoints; i++) |
|
|
|
b.push(points[i], RANGE_SYXRGB); |
|
|
|
for(int i = 0; i < npoints; i += POINTS_PER_CELL) |
|
|
|
{ |
|
|
|
#if POINTS_PER_CELL == 2 |
|
|
|
b.push(points[i] / RANGE_XY, RANGE_SBGR); |
|
|
|
b.push(points[i] % RANGE_XY, RANGE_XY); |
|
|
|
b.push(points[i + 1] / RANGE_XY, RANGE_SBGR); |
|
|
|
b.push(points[i + 1] % RANGE_XY, RANGE_XY); |
|
|
|
#else |
|
|
|
b.push(points[i], RANGE_SBGRXY); |
|
|
|
#endif |
|
|
|
} |
|
|
|
b.push(height - 1, RANGE_H); |
|
|
|
b.push(width - 1, RANGE_W); |
|
|
|
|
|
|
@@ -1284,10 +1295,14 @@ int main(int argc, char *argv[]) |
|
|
|
for(int i = dw * dh; i--; ) |
|
|
|
{ |
|
|
|
#if POINTS_PER_CELL == 2 |
|
|
|
points[i * 2 + 1] = b.pop(RANGE_SYXRGB); |
|
|
|
points[i * 2] = b.pop(RANGE_SYXRGB); |
|
|
|
uint32_t c1 = b.pop(RANGE_XY); |
|
|
|
uint32_t p1 = b.pop(RANGE_SBGR); |
|
|
|
uint32_t c2 = b.pop(RANGE_XY); |
|
|
|
uint32_t p2 = b.pop(RANGE_SBGR); |
|
|
|
points[i * 2 + 1] = p1 * RANGE_XY + c1; |
|
|
|
points[i * 2] = p2 * RANGE_XY + c2; |
|
|
|
#else |
|
|
|
points[i] = b.pop(RANGE_SYXRGB); |
|
|
|
points[i] = b.pop(RANGE_SBGRXY); |
|
|
|
#endif |
|
|
|
} |
|
|
|
npoints = dw * dh * POINTS_PER_CELL; |
|
|
|