Большая, умная задача

Brute-force DXT encoder, anyone?

Собственно мне крайне любопытно, насколько “качественный” энкодер будет отличаться от “оптимального”.
Подозреваю, что бредовая идея (см ниже) вполне себе оптимизируется на 1-2 порядка, хотя-бы и качественной переписью.
Подозреваю, что на какой-нибудь CUDA это развлечение может оказаться почти жизнеспособным – т-е несколько часов.

Но на самом деле мне было-бы интересно посмотреть на “оптимальную” картинку, хотя-бы и “лену”.

void BruteforceDxtEncoder ( unsigned char * inData, unsigned short * outData )
{
    int rc0 = 0, rc1 = 0, rd = 0x7fffffff;
    for ( int r1=0; r1<256; r1+=8 )
    for ( int g1=0; g1<256; g1+=4 )
    for ( int b1=0; b1<256; b1+=8 )
    {
        for ( int r0=0; r0<=r1; r0+=8 )
        for ( int g0=0; g0<=g1; g0+=4 )
        for ( int b0=0; b0<=b1; b0+=8 )
        {
            int r2 = (2*r0+r1)/3;   int r3 = (2*r1+r0)/3;
            int g2 = (2*g0+g1)/3;   int g3 = (2*g1+g0)/3;
            int b2 = (2*b0+b1)/3;   int b3 = (2*b1+b0)/3;
            int dtot = 0;
            for ( int cidx=0; cidx<64; cidx+=4 )
            {
                int r = inData[cidx+0];
                int g = inData[cidx+1];
                int b = inData[cidx+2];
                int d0 = (r-r0)*(r-r0) + (g-g0)*(g-g0) + (b-b0)*(b-b0);
                int d1 = (r-r1)*(r-r1) + (g-g1)*(g-g1) + (b-b1)*(b-b1);
                int d2 = (r-r2)*(r-r2) + (g-g2)*(g-g2) + (b-b2)*(b-b2);
                int d3 = (r-r3)*(r-r3) + (g-g3)*(g-g3) + (b-b3)*(b-b3);
                int d01 = d0 < d1 ? d0 : d1;
                int d23 = d2 < d3 ? d2 : d3;
                dtot += d01 < d23 ? d01 : d23;
            }
            if ( dtot < rd )
            {
                rd = dtot;
                rc0 = ((r0>>3)<<11) | ((g0>>2)<<5) | (b0>>3);
                rc1 = ((r1>>3)<<11) | ((g1>>2)<<5) | (b1>>3);
            }
        }
    }
    outData[0] = rc0;
    outData[1] = rc1;
}
_Winnie C++ Colorizer
  • Balmer

    Особо красивой картинки не получится. Так как в критерии оптимальности не предусмотрен дизеринг. Впрочем для случая когда тексель сильно больше пикселя дизеринг только вредит. Для случая когда тексель меньше или равен пикселю – дизеринг может уменьшить общую усреднённую ошибку по цвету в несколько раз.