Changeset 3532


Ignore:
Timestamp:
May 27, 2009 7:04:48 AM (5 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.