瀏覽代碼

img2twit: change the position of the S component to help decompose points

for a forthcoming optimisation.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@3533 92316355-f0b4-4df1-b90c-862c8a59935f
master
sam 15 年之前
父節點
當前提交
14c3888d21
共有 1 個檔案被更改,包括 63 行新增48 行删除
  1. +63
    -48
      examples/img2twit.cpp

+ 63
- 48
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<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;


Loading…
取消
儲存