Changeset 3532


Ignore:
Timestamp:
May 27, 2009 7:04:48 AM (6 years ago)
Author:
sam
Message:

Another img2twit space optimisation: if we have remaining bits at the end
of the cell allocation, we try to use them to improve the RGB precision as
well as the inner-grid coordinates.

File:
1 edited

Legend:

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

    r3531 r3532  
    6666#define RANGE_H 4000
    6767
    68 /* How does the algorithm work: one point per cell, or two */
     68/* How does the algorithm work: one point per cell, or two? XXX: changing
     69 * this value breaks compatibility with other images. */
    6970#define POINTS_PER_CELL 2
    7071
     
    128129/* Global triangulation */
    129130static Delaunay_triangulation dt;
     131
     132/*
     133 * Bit allocation handling
     134 */
     135
     136void compute_ranges(int width, int height)
     137{
     138    TOTAL_BITS = MAX_MSG_LEN * logf(NUM_CHARACTERS) / logf(2);
     139    HEADER_BITS = logf(RANGE_W * RANGE_H) / logf(2);
     140    DATA_BITS = TOTAL_BITS - HEADER_BITS;
     141#if POINTS_PER_CELL == 1
     142    CELL_BITS = logf(RANGE_SYXRGB) / logf(2);
     143#else
     144    // TODO: implement the following shit
     145    //float coord_bits = logf((RANGE_Y * RANGE_X) * (RANGE_Y * RANGE_X + 1) / 2);
     146    //float other_bits = logf(RANGE_R * RANGE_G * RANGE_B * RANGE_S);
     147    //CELL_BITS = (coord_bits + 2 * other_bits) / logf(2);
     148    CELL_BITS = 2 * logf(RANGE_SYXRGB) / logf(2);
     149#endif
     150    TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS);
     151    MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS;
     152
     153    /* Compute "best" w/h ratio */
     154    dw = 1; dh = TOTAL_CELLS;
     155    for(unsigned int i = 1; i <= TOTAL_CELLS; i++)
     156    {
     157        int j = TOTAL_CELLS / i;
     158
     159        float r = (float)width / (float)height;
     160        float ir = (float)i / (float)j;
     161        float dwr = (float)dw / (float)dh;
     162
     163        if(fabs(logf(r / ir)) < fabs(logf(r / dwr)))
     164        {
     165            dw = i;
     166            dh = TOTAL_CELLS / dw;
     167        }
     168    }
     169    while((dh + 1) * dw <= TOTAL_CELLS) dh++;
     170    while(dh * (dw + 1) <= TOTAL_CELLS) dw++;
     171}
    130172
    131173/*
     
    445487static inline void index2cell(int index, int *dx, int *dy)
    446488{
    447     // This check will be used once we add points to our list
    448     //if(index < dw * dh * POINTS_PER_CELL)
    449     {
    450         *dx = (index / POINTS_PER_CELL) % dw;
    451         *dy = (index / POINTS_PER_CELL) / dw;
    452     }
     489    *dx = (index / POINTS_PER_CELL) % dw;
     490    *dy = (index / POINTS_PER_CELL) / dw;
    453491}
    454492
     
    10221060    }
    10231061
    1024     TOTAL_BITS = MAX_MSG_LEN * logf(NUM_CHARACTERS) / logf(2);
    1025     HEADER_BITS = logf(RANGE_W * RANGE_H) / logf(2);
    1026     DATA_BITS = TOTAL_BITS - HEADER_BITS;
    1027 #if POINTS_PER_CELL == 1
    1028     CELL_BITS = logf(RANGE_SYXRGB) / logf(2);
    1029 #else
    1030     // TODO: implement the following shit
    1031     //float coord_bits = logf((RANGE_Y * RANGE_X) * (RANGE_Y * RANGE_X + 1) / 2);
    1032     //float other_bits = logf(RANGE_R * RANGE_G * RANGE_B * RANGE_S);
    1033     //CELL_BITS = (coord_bits + 2 * other_bits) / logf(2);
    1034     CELL_BITS = 2 * logf(RANGE_SYXRGB) / logf(2);
    1035 #endif
    1036     TOTAL_CELLS = (int)(DATA_BITS / CELL_BITS);
    1037     MAX_ITERATIONS = ITERATIONS_PER_POINT * POINTS_PER_CELL * TOTAL_CELLS;
    1038 
    1039     /* Compute "best" w/h ratio */
    1040     dw = 1; dh = TOTAL_CELLS;
    1041     for(unsigned int i = 1; i <= TOTAL_CELLS; i++)
    1042     {
    1043         int j = TOTAL_CELLS / i;
    1044 
    1045         float r = (float)width / (float)height;
    1046         float ir = (float)i / (float)j;
    1047         float dwr = (float)dw / (float)dh;
    1048 
    1049         if(fabs(logf(r / ir)) < fabs(logf(r / dwr)))
    1050         {
    1051             dw = i;
    1052             dh = TOTAL_CELLS / dw;
    1053         }
    1054     }
    1055     while((dh + 1) * dw <= TOTAL_CELLS) dh++;
    1056     while(dh * (dw + 1) <= TOTAL_CELLS) dw++;
     1062    compute_ranges(width, height);
     1063
     1064    /* Try to cram some more information into our points as long as it
     1065     * does not change the cell distribution. This cannot be too clever,
     1066     * because we want the computation to depend only on the source image
     1067     * coordinates. */
     1068#define TRY(op, revert) \
     1069    do { \
     1070        unsigned int olddw = dw, olddh = dh; \
     1071        op; compute_ranges(width, height); \
     1072        if(dw != olddw || dh != olddh) \
     1073            { revert; compute_ranges(width, height); } \
     1074    } while(0)
     1075
     1076    for(int i = 0; i < 5; i++)
     1077    {
     1078        TRY(RANGE_G++, RANGE_G--);
     1079        TRY(RANGE_R++, RANGE_R--);
     1080        TRY(RANGE_B++, RANGE_B--);
     1081    }
     1082
     1083    for(int i = 0; i < 10; i++)
     1084    {
     1085        if((float)width / dw >= (float)height / dh)
     1086        {
     1087            TRY(RANGE_X++, RANGE_X--);
     1088            TRY(RANGE_Y++, RANGE_Y--);
     1089        }
     1090        else
     1091        {
     1092            TRY(RANGE_Y++, RANGE_Y--);
     1093            TRY(RANGE_X++, RANGE_X--);
     1094        }
     1095    }
    10571096
    10581097    /* Print debug information */
Note: See TracChangeset for help on using the changeset viewer.