diff --git a/examples/img2twit.cpp b/examples/img2twit.cpp index 32fa2b7..ad1c121 100644 --- a/examples/img2twit.cpp +++ b/examples/img2twit.cpp @@ -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 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;