Browse Source

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
master
sam 15 years ago
parent
commit
b9e07e7b00
1 changed files with 49 additions and 28 deletions
  1. +49
    -28
      examples/img2twit.cpp

+ 49
- 28
examples/img2twit.cpp View File

@@ -62,8 +62,8 @@ static const uint32_t unichars_symbols[] = { RANGE_SYMBOLS, RANGE_END };
static const uint32_t *unichars; static const uint32_t *unichars;


/* The maximum image size we want to support */ /* 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 */ /* How does the algorithm work: one point per cell, or two */
#define POINTS_PER_CELL 2 #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; 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, static inline void set_point(int index, float x, float y, float r,
float g, float b, float s) 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 fx = (x - dx * RANGE_X) / RANGE_X;
float fy = (y - dy * RANGE_Y) / RANGE_Y; 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) float *g, float *b, float *s, bool final = false)
{ {
uint32_t pt = points[index]; 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; *s = int2fullrange(pt % RANGE_S, RANGE_S); pt /= RANGE_S;


@@ -936,6 +947,9 @@ int main(int argc, char *argv[])
return EXIT_FAILURE; 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. */ /* Autodetect charset if decoding, otherwise switch to CJK. */
if(dstname) if(dstname)
{ {
@@ -972,23 +986,6 @@ int main(int argc, char *argv[])


/* Precompute bit allocation */ /* Precompute bit allocation */
NUM_CHARACTERS = count_unichars(); 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) if(dstname)
{ {
@@ -999,8 +996,8 @@ int main(int argc, char *argv[])


/* Read width and height from bitstream */ /* Read width and height from bitstream */
src = NULL; 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 else
{ {
@@ -1017,6 +1014,28 @@ int main(int argc, char *argv[])
height = pipi_get_image_height(src); 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 */ /* Compute "best" w/h ratio */
dw = 1; dh = TOTAL_CELLS; dw = 1; dh = TOTAL_CELLS;
for(unsigned int i = 1; i <= TOTAL_CELLS; i++) 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, "Message size: %i\n", MAX_MSG_LEN);
fprintf(stderr, "Available characters: %i\n", NUM_CHARACTERS); fprintf(stderr, "Available characters: %i\n", NUM_CHARACTERS);
fprintf(stderr, "Available bits: %f\n", TOTAL_BITS); 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, "Image resolution: %ix%i\n", width, height);
fprintf(stderr, "Header bits: %f\n", HEADER_BITS); fprintf(stderr, "Header bits: %f\n", HEADER_BITS);
fprintf(stderr, "Bits available for data: %f\n", DATA_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, "Cell bits: %f\n", CELL_BITS);
fprintf(stderr, "Available cells: %i\n", TOTAL_CELLS); fprintf(stderr, "Available cells: %i\n", TOTAL_CELLS);
fprintf(stderr, "Wasted bits: %f\n", fprintf(stderr, "Wasted bits: %f\n",
@@ -1210,8 +1231,8 @@ int main(int argc, char *argv[])
/* Push our points to the bitstream */ /* Push our points to the bitstream */
for(int i = 0; i < npoints; i++) for(int i = 0; i < npoints; i++)
b.push(points[i], RANGE_SYXRGB); 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 */ /* Pop Unicode characters from the bitstream and print them */
for(int i = 0; i < MAX_MSG_LEN; i++) for(int i = 0; i < MAX_MSG_LEN; i++)


Loading…
Cancel
Save