| 100 | } |
| 101 | |
| 102 | static int FitCodes( u8 const* rgba, int mask, u8 const* codes, u8* indices ) |
| 103 | { |
| 104 | // fit each alpha value to the codebook |
| 105 | int err = 0; |
| 106 | for( int i = 0; i < 16; ++i ) |
| 107 | { |
| 108 | // check this pixel is valid |
| 109 | int bit = 1 << i; |
| 110 | if( ( mask & bit ) == 0 ) |
| 111 | { |
| 112 | // use the first code |
| 113 | indices[i] = 0; |
| 114 | continue; |
| 115 | } |
| 116 | |
| 117 | // find the least error and corresponding index |
| 118 | int value = rgba[4*i + 3]; |
| 119 | int least = INT_MAX; |
| 120 | int index = 0; |
| 121 | for( int j = 0; j < 8; ++j ) |
| 122 | { |
| 123 | // get the squared error from this code |
| 124 | int dist = ( int )value - ( int )codes[j]; |
| 125 | dist *= dist; |
| 126 | |
| 127 | // compare with the best so far |
| 128 | if( dist < least ) |
| 129 | { |
| 130 | least = dist; |
| 131 | index = j; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // save this index and accumulate the error |
| 136 | indices[i] = ( u8 )index; |
| 137 | err += least; |
| 138 | } |
| 139 | |
| 140 | // return the total error |
| 141 | return err; |
| 142 | } |
| 143 | |
| 144 | static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block ) |
| 145 | { |