Rewrote using an algorithm described by Paul Nettle at http://www.gamedev.net/reference/articles/article669.asp.
| 198 | // Rewrote using an algorithm described by Paul Nettle at |
| 199 | // http://www.gamedev.net/reference/articles/article669.asp. |
| 200 | ILimage *iluScale2DBilinear_(ILimage *Image, ILimage *Scaled, ILuint Width, ILuint Height) |
| 201 | { |
| 202 | ILfloat ul, ll, ur, lr; |
| 203 | ILfloat FracX, FracY; |
| 204 | ILfloat SrcX, SrcY; |
| 205 | ILuint iSrcX, iSrcY, iSrcXPlus1, iSrcYPlus1, ulOff, llOff, urOff, lrOff; |
| 206 | |
| 207 | ImgBps = Image->Bps / Image->Bpc; |
| 208 | SclBps = Scaled->Bps / Scaled->Bpc; |
| 209 | |
| 210 | switch (Image->Bpc) |
| 211 | { |
| 212 | case 1: |
| 213 | for (y = 0; y < Height; y++) { |
| 214 | for (x = 0; x < Width; x++) { |
| 215 | // Calculate where we want to choose pixels from in our source image. |
| 216 | SrcX = (ILfloat)x / (ILfloat)ScaleX; |
| 217 | SrcY = (ILfloat)y / (ILfloat)ScaleY; |
| 218 | // Integer part of SrcX and SrcY |
| 219 | iSrcX = (ILuint)floor(SrcX); |
| 220 | iSrcY = (ILuint)floor(SrcY); |
| 221 | // Fractional part of SrcX and SrcY |
| 222 | FracX = SrcX - (ILfloat)(iSrcX); |
| 223 | FracY = SrcY - (ILfloat)(iSrcY); |
| 224 | |
| 225 | // We do not want to go past the right edge of the image or past the last line in the image, |
| 226 | // so this takes care of that. Normally, iSrcXPlus1 is iSrcX + 1, but if this is past the |
| 227 | // right side, we have to bring it back to iSrcX. The same goes for iSrcYPlus1. |
| 228 | if (iSrcX < Image->Width - 1) |
| 229 | iSrcXPlus1 = iSrcX + 1; |
| 230 | else |
| 231 | iSrcXPlus1 = iSrcX; |
| 232 | if (iSrcY < Image->Height - 1) |
| 233 | iSrcYPlus1 = iSrcY + 1; |
| 234 | else |
| 235 | iSrcYPlus1 = iSrcY; |
| 236 | |
| 237 | // Find out how much we want each of the four pixels contributing to the final values. |
| 238 | ul = (1.0f - FracX) * (1.0f - FracY); |
| 239 | ll = (1.0f - FracX) * FracY; |
| 240 | ur = FracX * (1.0f - FracY); |
| 241 | lr = FracX * FracY; |
| 242 | |
| 243 | for (c = 0; c < Scaled->Bpp; c++) { |
| 244 | // We just calculate the offsets for each pixel here... |
| 245 | ulOff = iSrcY * Image->Bps + iSrcX * Image->Bpp + c; |
| 246 | llOff = iSrcYPlus1 * Image->Bps + iSrcX * Image->Bpp + c; |
| 247 | urOff = iSrcY * Image->Bps + iSrcXPlus1 * Image->Bpp + c; |
| 248 | lrOff = iSrcYPlus1 * Image->Bps + iSrcXPlus1 * Image->Bpp + c; |
| 249 | |
| 250 | // ...and then we do the actual interpolation here. |
| 251 | Scaled->Data[y * Scaled->Bps + x * Scaled->Bpp + c] = (ILubyte)( |
| 252 | ul * Image->Data[ulOff] + ll * Image->Data[llOff] + ur * Image->Data[urOff] + lr * Image->Data[lrOff]); |
| 253 | } |
| 254 | } |
| 255 | } |
| 256 | break; |
| 257 |