Changeset 3538


Ignore:
Timestamp:
May 30, 2009 6:01:17 PM (6 years ago)
Author:
sam
Message:

Make img2twit's points-per-cell value changeable at runtime.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libpipi/trunk/examples/img2twit.cpp

    r3537 r3538  
    7272#define RANGE_V 10
    7373
    74 /* How does the algorithm work: one point per cell, or two? XXX: changing
    75  * this value breaks compatibility with other images. */
    76 #define POINTS_PER_CELL 2
    77 
    7874/* Start with a random image (1), or with a good estimate (0)? */
    7975#define RANDOM_START 0
     
    9187/* Iterations per point -- larger means slower but nicer */
    9288static int ITERATIONS_PER_POINT = 50;
     89
     90/* Points per cell -- 1 allows to put more cells, but 2 gives better results */
     91static int POINTS_PER_CELL = 2;
    9392
    9493/* The range value for point parameters: X Y, red/green/blue, "strength"
     
    154153    HEADER_BITS = logf(RANGE_W * RANGE_H * RANGE_V) / logf(2);
    155154    DATA_BITS = TOTAL_BITS - HEADER_BITS;
    156 #if POINTS_PER_CELL == 2
    157     CELL_BITS = (2 * logf(RANGE_SBGR) + logf(RANGE_XY2)) / logf(2);
    158     //CELL_BITS = 2 * logf(RANGE_SBGRXY) / logf(2);
    159 #else
    160     CELL_BITS = logf(RANGE_SBGRXY) / logf(2);
    161 #endif
     155    if(version == 0)
     156    {
     157        POINTS_PER_CELL = 1;
     158        CELL_BITS = logf(RANGE_SBGRXY) / logf(2);
     159    }
     160    else if(version == 1)
     161    {
     162        POINTS_PER_CELL = 2;
     163        CELL_BITS = (2 * logf(RANGE_SBGR) + logf(RANGE_XY2)) / logf(2);
     164    }
    162165    TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS);
    163166    MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS;
     
    840843
    841844#if RANDOM_START == 1
    842 #   if POINTS_PER_CELL == 2
    843             add_random_point();
    844 #   endif
    845             add_random_point();
     845            for(int i = 0; i < POINTS_PER_CELL; i++)
     846                add_random_point();
    846847#else
    847848            /* 0.80 and 0.20 were chosen empirically, it gives a 10% better
    848849             * initial distance. Definitely worth it. */
    849 #   if POINTS_PER_CELL == 1
    850             if(total < min + (max - min) / 2)
    851             {
    852 #   endif
    853             add_point(xmin, ymin,
    854                       data[4 * (xmin + ymin * p->w) + 0] * 0.80 + mr * 0.20,
    855                       data[4 * (xmin + ymin * p->w) + 1] * 0.80 + mg * 0.20,
    856                       data[4 * (xmin + ymin * p->w) + 2] * 0.80 + mb * 0.20,
    857                       wmin);
    858 #   if POINTS_PER_CELL == 1
    859             }
    860             else
    861             {
    862 #   endif
    863             add_point(xmax, ymax,
    864                       data[4 * (xmax + ymax * p->w) + 0] * 0.80 + mr * 0.20,
    865                       data[4 * (xmax + ymax * p->w) + 1] * 0.80 + mg * 0.20,
    866                       data[4 * (xmax + ymax * p->w) + 2] * 0.80 + mb * 0.20,
    867                       wmax);
    868 #   if POINTS_PER_CELL == 1
    869             }
    870 #   endif
     850            if(POINTS_PER_CELL == 2 || total < min + (max - min) / 2)
     851                add_point(xmin, ymin,
     852                          data[4 * (xmin + ymin * p->w) + 0] * 0.80 + mr * 0.20,
     853                          data[4 * (xmin + ymin * p->w) + 1] * 0.80 + mg * 0.20,
     854                          data[4 * (xmin + ymin * p->w) + 2] * 0.80 + mb * 0.20,
     855                          wmin);
     856
     857            if(POINTS_PER_CELL == 2 || total >= min + (max - min) / 2)
     858                add_point(xmax, ymax,
     859                          data[4 * (xmax + ymax * p->w) + 0] * 0.80 + mr * 0.20,
     860                          data[4 * (xmax + ymax * p->w) + 1] * 0.80 + mg * 0.20,
     861                          data[4 * (xmax + ymax * p->w) + 2] * 0.80 + mb * 0.20,
     862                          wmax);
    871863#endif
    872864        }
     
    10531045        version = b.pop(RANGE_V);
    10541046
     1047        if(version > 1)
     1048        {
     1049            fprintf(stderr, "Error: unsupported algorithm version %i\n",
     1050                    version);
     1051            return EXIT_FAILURE;
     1052        }
     1053
    10551054        /* Read width and height from bitstream */
    10561055        width = b.pop(RANGE_W) + 1;
     
    10781077        fprintf(stderr, "Error: image size %ix%i is out of bounds\n",
    10791078                width, height);
    1080         return EXIT_FAILURE;
    1081     }
    1082 
    1083     if(version > 1)
    1084     {
    1085         fprintf(stderr, "Error: unsupported algorithm version %i\n", version);
    10861079        return EXIT_FAILURE;
    10871080    }
     
    11481141    {
    11491142        /* Resize and filter image to better state */
    1150         tmp = pipi_gaussian_blur(src, 0.5 * dw * RANGE_X / width);
     1143        tmp = pipi_gaussian_blur(src, 0.25 * dw * RANGE_X / width);
    11511144        pipi_free(src);
    11521145        src = pipi_resize(tmp, dw * RANGE_X, dh * RANGE_Y);
     
    12031196            apply_op(op1, &points[pt]);
    12041197
    1205 #if POINTS_PER_CELL == 2
    12061198            /* Check that two points don't fall at the same place */
    1207             while(points[pt].x == points[pt ^ 1].x
    1208                    && points[pt].y == points[pt ^ 1].y)
    1209             {
    1210                 points[pt] = oldpt;
    1211                 op1 = rand_op();
    1212                 apply_op(op1, &points[pt]);
    1213             }
    1214 #endif
     1199            if(POINTS_PER_CELL == 2)
     1200            {
     1201                while(points[pt].x == points[pt ^ 1].x
     1202                       && points[pt].y == points[pt ^ 1].y)
     1203                {
     1204                    points[pt] = oldpt;
     1205                    op1 = rand_op();
     1206                    apply_op(op1, &points[pt]);
     1207                }
     1208            }
    12151209
    12161210            render(scrap, zonex * RANGE_X, zoney * RANGE_Y,
     
    12811275            fprintf(stderr, "\r                    \r");
    12821276
    1283 #if 1
     1277#if 0
    12841278        dst = pipi_resize(tmp, width, height);
    12851279        pipi_free(tmp);
     
    12931287        for(int i = 0; i < npoints; i += POINTS_PER_CELL)
    12941288        {
    1295 #if POINTS_PER_CELL == 2
    1296             int x1, y1, x2, y2;
    1297             x1 = points[i].x;
    1298             y1 = points[i].y;
    1299             x2 = points[i + 1].x;
    1300             y2 = points[i + 1].y;
    1301 
    1302             bool swap;
    1303             uint32_t pack = pack_coords(x1, y1, x2, y2, &swap);
    1304 
    1305             b.push(points[i + (swap ? 1 : 0)].s, RANGE_S);
    1306             b.push(points[i + (swap ? 1 : 0)].b, RANGE_B);
    1307             b.push(points[i + (swap ? 1 : 0)].g, RANGE_G);
    1308             b.push(points[i + (swap ? 1 : 0)].r, RANGE_R);
    1309             b.push(points[i + (swap ? 0 : 1)].s, RANGE_S);
    1310             b.push(points[i + (swap ? 0 : 1)].b, RANGE_B);
    1311             b.push(points[i + (swap ? 0 : 1)].g, RANGE_G);
    1312             b.push(points[i + (swap ? 0 : 1)].r, RANGE_R);
    1313             b.push(pack, RANGE_XY2);
    1314 #else
    1315             b.push(points[i].s, RANGE_S);
    1316             b.push(points[i].b, RANGE_B);
    1317             b.push(points[i].g, RANGE_G);
    1318             b.push(points[i].r, RANGE_R);
    1319             b.push(points[i].x, RANGE_X);
    1320             b.push(points[i].y, RANGE_Y);
    1321 #endif
     1289            if(POINTS_PER_CELL == 2)
     1290            {
     1291                int x1, y1, x2, y2;
     1292                x1 = points[i].x;
     1293                y1 = points[i].y;
     1294                x2 = points[i + 1].x;
     1295                y2 = points[i + 1].y;
     1296
     1297                bool swap;
     1298                uint32_t pack = pack_coords(x1, y1, x2, y2, &swap);
     1299
     1300                b.push(points[i + (swap ? 1 : 0)].s, RANGE_S);
     1301                b.push(points[i + (swap ? 1 : 0)].b, RANGE_B);
     1302                b.push(points[i + (swap ? 1 : 0)].g, RANGE_G);
     1303                b.push(points[i + (swap ? 1 : 0)].r, RANGE_R);
     1304                b.push(points[i + (swap ? 0 : 1)].s, RANGE_S);
     1305                b.push(points[i + (swap ? 0 : 1)].b, RANGE_B);
     1306                b.push(points[i + (swap ? 0 : 1)].g, RANGE_G);
     1307                b.push(points[i + (swap ? 0 : 1)].r, RANGE_R);
     1308                b.push(pack, RANGE_XY2);
     1309            }
     1310            else
     1311            {
     1312                b.push(points[i].s, RANGE_S);
     1313                b.push(points[i].b, RANGE_B);
     1314                b.push(points[i].g, RANGE_G);
     1315                b.push(points[i].r, RANGE_R);
     1316                b.push(points[i].x, RANGE_X);
     1317                b.push(points[i].y, RANGE_Y);
     1318            }
    13221319        }
    13231320        b.push(height - 1, RANGE_H);
     
    13351332        for(int i = dw * dh; i--; )
    13361333        {
    1337 #if POINTS_PER_CELL == 2
    1338             uint32_t pack = b.pop(RANGE_XY2);
    1339             int x1, y1, x2, y2;
    1340             unpack_coords(pack, &x1, &y1, &x2, &y2);
    1341 
    1342             points[i * 2 + 1].y = y2;
    1343             points[i * 2 + 1].x = x2;
    1344             points[i * 2 + 1].r = b.pop(RANGE_R);
    1345             points[i * 2 + 1].g = b.pop(RANGE_G);
    1346             points[i * 2 + 1].b = b.pop(RANGE_B);
    1347             points[i * 2 + 1].s = b.pop(RANGE_S);
    1348             points[i * 2].y = y1;
    1349             points[i * 2].x = x1;
    1350             points[i * 2].r = b.pop(RANGE_R);
    1351             points[i * 2].g = b.pop(RANGE_G);
    1352             points[i * 2].b = b.pop(RANGE_B);
    1353             points[i * 2].s = b.pop(RANGE_S);
    1354 #else
    1355             points[i].y = b.pop(RANGE_Y);
    1356             points[i].x = b.pop(RANGE_X);
    1357             points[i].r = b.pop(RANGE_R);
    1358             points[i].g = b.pop(RANGE_G);
    1359             points[i].b = b.pop(RANGE_B);
    1360             points[i].s = b.pop(RANGE_S);
    1361 #endif
     1334            if(POINTS_PER_CELL == 2)
     1335            {
     1336                uint32_t pack = b.pop(RANGE_XY2);
     1337                int x1, y1, x2, y2;
     1338                unpack_coords(pack, &x1, &y1, &x2, &y2);
     1339
     1340                points[i * 2 + 1].y = y2;
     1341                points[i * 2 + 1].x = x2;
     1342                points[i * 2 + 1].r = b.pop(RANGE_R);
     1343                points[i * 2 + 1].g = b.pop(RANGE_G);
     1344                points[i * 2 + 1].b = b.pop(RANGE_B);
     1345                points[i * 2 + 1].s = b.pop(RANGE_S);
     1346                points[i * 2].y = y1;
     1347                points[i * 2].x = x1;
     1348                points[i * 2].r = b.pop(RANGE_R);
     1349                points[i * 2].g = b.pop(RANGE_G);
     1350                points[i * 2].b = b.pop(RANGE_B);
     1351                points[i * 2].s = b.pop(RANGE_S);
     1352            }
     1353            else
     1354            {
     1355                points[i].y = b.pop(RANGE_Y);
     1356                points[i].x = b.pop(RANGE_X);
     1357                points[i].r = b.pop(RANGE_R);
     1358                points[i].g = b.pop(RANGE_G);
     1359                points[i].b = b.pop(RANGE_B);
     1360                points[i].s = b.pop(RANGE_S);
     1361            }
    13621362        }
    13631363        npoints = dw * dh * POINTS_PER_CELL;
Note: See TracChangeset for help on using the changeset viewer.