| 155 | } |
| 156 | |
| 157 | void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric ) |
| 158 | { |
| 159 | // fix any bad flags |
| 160 | flags = FixFlags( flags ); |
| 161 | |
| 162 | // initialise the block output |
| 163 | u8* targetBlock = reinterpret_cast< u8* >( blocks ); |
| 164 | int bytesPerBlock = ( ( flags & ( kDxt1 | kBc4 ) ) != 0 ) ? 8 : 16; |
| 165 | |
| 166 | // loop over blocks |
| 167 | for( int y = 0; y < height; y += 4 ) |
| 168 | { |
| 169 | for( int x = 0; x < width; x += 4 ) |
| 170 | { |
| 171 | // build the 4x4 block of pixels |
| 172 | u8 sourceRgba[16*4]; |
| 173 | u8* targetPixel = sourceRgba; |
| 174 | int mask = 0; |
| 175 | for( int py = 0; py < 4; ++py ) |
| 176 | { |
| 177 | for( int px = 0; px < 4; ++px ) |
| 178 | { |
| 179 | // get the source pixel in the image |
| 180 | int sx = x + px; |
| 181 | int sy = y + py; |
| 182 | |
| 183 | // enable if we're in the image |
| 184 | if( sx < width && sy < height ) |
| 185 | { |
| 186 | // copy the rgba value |
| 187 | u8 const* sourcePixel = rgba + 4*( width*sy + sx ); |
| 188 | for( int i = 0; i < 4; ++i ) |
| 189 | *targetPixel++ = *sourcePixel++; |
| 190 | |
| 191 | // enable this pixel |
| 192 | mask |= ( 1 << ( 4*py + px ) ); |
| 193 | } |
| 194 | else |
| 195 | { |
| 196 | // skip this pixel as its outside the image |
| 197 | targetPixel += 4; |
| 198 | } |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | // compress it into the output |
| 203 | CompressMasked( sourceRgba, mask, targetBlock, flags, metric ); |
| 204 | |
| 205 | // advance |
| 206 | targetBlock += bytesPerBlock; |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) |
| 212 | { |
no test coverage detected