From b9e07e7b00df83db1a31fc91f414fb7647d41cf3 Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 27 May 2009 05:04:41 +0000 Subject: [PATCH] img2twit: store w+1,h+1 instead of w,h since neither width nor height can be zero. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@3531 92316355-f0b4-4df1-b90c-862c8a59935f --- examples/img2twit.cpp | 77 +++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/examples/img2twit.cpp b/examples/img2twit.cpp index 4fc38ba..0fb5352 100644 --- a/examples/img2twit.cpp +++ b/examples/img2twit.cpp @@ -62,8 +62,8 @@ static const uint32_t unichars_symbols[] = { RANGE_SYMBOLS, RANGE_END }; static const uint32_t *unichars; /* The maximum image size we want to support */ -#define MAX_W 4000 -#define MAX_H 4000 +#define RANGE_W 4000 +#define RANGE_H 4000 /* How does the algorithm work: one point per cell, or two */ #define POINTS_PER_CELL 2 @@ -442,11 +442,22 @@ static inline float int2fullrange(int val, int range) return range > 1 ? (float)val / (float)(range - 1) : 0.0; } +static inline void index2cell(int index, int *dx, int *dy) +{ + // This check will be used once we add points to our list + //if(index < dw * dh * POINTS_PER_CELL) + { + *dx = (index / POINTS_PER_CELL) % dw; + *dy = (index / POINTS_PER_CELL) / dw; + } +} + static inline void set_point(int index, float x, float y, float r, float g, float b, float s) { - int dx = (index / POINTS_PER_CELL) % dw; - int dy = (index / POINTS_PER_CELL) / dw; + int dx, dy; + + index2cell(index, &dx, &dy); float fx = (x - dx * RANGE_X) / RANGE_X; float fy = (y - dy * RANGE_Y) / RANGE_Y; @@ -468,9 +479,9 @@ static inline void get_point(int index, float *x, float *y, float *r, float *g, float *b, float *s, bool final = false) { uint32_t pt = points[index]; + int dx, dy; - unsigned int dx = (index / POINTS_PER_CELL) % dw; - unsigned int dy = (index / POINTS_PER_CELL) / dw; + index2cell(index, &dx, &dy); *s = int2fullrange(pt % RANGE_S, RANGE_S); pt /= RANGE_S; @@ -936,6 +947,9 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } + bitstack b(MAX_MSG_LEN); /* We cannot declare this before, because + * MAX_MSG_LEN wouldn't be defined. */ + /* Autodetect charset if decoding, otherwise switch to CJK. */ if(dstname) { @@ -972,23 +986,6 @@ int main(int argc, char *argv[]) /* Precompute bit allocation */ NUM_CHARACTERS = count_unichars(); - TOTAL_BITS = MAX_MSG_LEN * logf(NUM_CHARACTERS) / logf(2); - HEADER_BITS = logf(MAX_W * MAX_H) / logf(2); - DATA_BITS = TOTAL_BITS - HEADER_BITS; -#if POINTS_PER_CELL == 1 - CELL_BITS = logf(RANGE_SYXRGB) / 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); -#endif - TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS); - MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS; - - bitstack b(MAX_MSG_LEN); /* We cannot declare this before, because - * MAX_MSG_LEN wouldn't be defined. */ if(dstname) { @@ -999,8 +996,8 @@ int main(int argc, char *argv[]) /* Read width and height from bitstream */ src = NULL; - width = b.pop(MAX_W); - height = b.pop(MAX_H); + width = b.pop(RANGE_W) + 1; + height = b.pop(RANGE_H) + 1; } else { @@ -1017,6 +1014,28 @@ int main(int argc, char *argv[]) height = pipi_get_image_height(src); } + if(width <= 0 || height <= 0 || width > RANGE_W || height > RANGE_H) + { + fprintf(stderr, "Error: image size %ix%i is out of bounds\n", + width, height); + return EXIT_FAILURE; + } + + TOTAL_BITS = MAX_MSG_LEN * logf(NUM_CHARACTERS) / logf(2); + 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); +#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); +#endif + TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS); + MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS; + /* Compute "best" w/h ratio */ dw = 1; dh = TOTAL_CELLS; for(unsigned int i = 1; i <= TOTAL_CELLS; i++) @@ -1042,10 +1061,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "Message size: %i\n", MAX_MSG_LEN); fprintf(stderr, "Available characters: %i\n", NUM_CHARACTERS); fprintf(stderr, "Available bits: %f\n", TOTAL_BITS); - fprintf(stderr, "Maximum image resolution: %ix%i\n", MAX_W, MAX_H); + fprintf(stderr, "Width/Height ranges: %ix%i\n", RANGE_W, RANGE_H); fprintf(stderr, "Image resolution: %ix%i\n", width, height); fprintf(stderr, "Header bits: %f\n", HEADER_BITS); fprintf(stderr, "Bits available for data: %f\n", DATA_BITS); + fprintf(stderr, "X/Y/Red/Green/Blue/Extra ranges: %i %i %i %i %i %i\n", + RANGE_X, RANGE_Y, RANGE_R, RANGE_G, RANGE_B, RANGE_S); fprintf(stderr, "Cell bits: %f\n", CELL_BITS); fprintf(stderr, "Available cells: %i\n", TOTAL_CELLS); fprintf(stderr, "Wasted bits: %f\n", @@ -1210,8 +1231,8 @@ int main(int argc, char *argv[]) /* Push our points to the bitstream */ for(int i = 0; i < npoints; i++) b.push(points[i], RANGE_SYXRGB); - b.push(height, MAX_H); - b.push(width, MAX_W); + b.push(height - 1, RANGE_H); + b.push(width - 1, RANGE_W); /* Pop Unicode characters from the bitstream and print them */ for(int i = 0; i < MAX_MSG_LEN; i++)