| 148 | static void |
| 149 | scale3x(const uint8* srcBits, uint8* dstBits, int32 srcWidth, int32 srcHeight, |
| 150 | int32 srcBPR, int32 dstBPR) |
| 151 | { |
| 152 | /* |
| 153 | * This implements the AdvanceMAME Scale3x algorithm found on: |
| 154 | * http://scale2x.sourceforge.net/ |
| 155 | * |
| 156 | * It is an incredibly simple and powerful image tripling routine that does |
| 157 | * an astonishing job of tripling game graphic data while interpolating out |
| 158 | * the jaggies. |
| 159 | * |
| 160 | * Derived from the (public domain) SDL version of the library by Pete |
| 161 | * Shinners |
| 162 | */ |
| 163 | |
| 164 | // Assume that both src and dst are 4 BPP (B_RGBA32) |
| 165 | for(int32 y = 0; y < srcHeight; ++y) |
| 166 | { |
| 167 | for(int32 x = 0; x < srcWidth; ++x) |
| 168 | { |
| 169 | uint32 a = *(uint32*)(srcBits + (MAX(0, y - 1) * srcBPR) |
| 170 | + (4 * MAX(0, x - 1))); |
| 171 | uint32 b = *(uint32*)(srcBits + (MAX(0, y - 1) * srcBPR) |
| 172 | + (4 * x)); |
| 173 | uint32 c = *(uint32*)(srcBits + (MAX(0, y - 1) * srcBPR) |
| 174 | + (4 * MIN(srcWidth - 1, x + 1))); |
| 175 | uint32 d = *(uint32*)(srcBits + (y * srcBPR) |
| 176 | + (4 * MAX(0, x - 1))); |
| 177 | uint32 e = *(uint32*)(srcBits + (y * srcBPR) |
| 178 | + (4 * x)); |
| 179 | uint32 f = *(uint32*)(srcBits + (y * srcBPR) |
| 180 | + (4 * MIN(srcWidth - 1,x + 1))); |
| 181 | uint32 g = *(uint32*)(srcBits + (MIN(srcHeight - 1, y + 1) |
| 182 | * srcBPR) + (4 * MAX(0, x - 1))); |
| 183 | uint32 h = *(uint32*)(srcBits + (MIN(srcHeight - 1, y + 1) |
| 184 | * srcBPR) + (4 * x)); |
| 185 | uint32 i = *(uint32*)(srcBits + (MIN(srcHeight - 1, y + 1) |
| 186 | * srcBPR) + (4 * MIN(srcWidth - 1, x + 1))); |
| 187 | |
| 188 | uint32 e0 = d == b && b != f && d != h ? d : e; |
| 189 | uint32 e1 = (d == b && b != f && d != h && e != c) |
| 190 | || (b == f && b != d && f != h && e != a) ? b : e; |
| 191 | uint32 e2 = b == f && b != d && f != h ? f : e; |
| 192 | uint32 e3 = (d == b && b != f && d != h && e != g) |
| 193 | || (d == b && b != f && d != h && e != a) ? d : e; |
| 194 | uint32 e4 = e; |
| 195 | uint32 e5 = (b == f && b != d && f != h && e != i) |
| 196 | || (h == f && d != h && b != f && e != c) ? f : e; |
| 197 | uint32 e6 = d == h && d != b && h != f ? d : e; |
| 198 | uint32 e7 = (d == h && d != b && h != f && e != i) |
| 199 | || (h == f && d != h && b != f && e != g) ? h : e; |
| 200 | uint32 e8 = h == f && d != h && b != f ? f : e; |
| 201 | |
| 202 | *(uint32*)(dstBits + y * 3 * dstBPR + x * 3 * 4) = e0; |
| 203 | *(uint32*)(dstBits + y * 3 * dstBPR + (x * 3 + 1) * 4) = e1; |
| 204 | *(uint32*)(dstBits + y * 3 * dstBPR + (x * 3 + 2) * 4) = e2; |
| 205 | *(uint32*)(dstBits + (y * 3 + 1) * dstBPR + x * 3 * 4) = e3; |
| 206 | *(uint32*)(dstBits + (y * 3 + 1) * dstBPR + (x * 3 + 1) * 4) = e4; |
| 207 | *(uint32*)(dstBits + (y * 3 + 1) * dstBPR + (x * 3 + 2) * 4) = e5; |
| 208 | *(uint32*)(dstBits + (y * 3 + 2) * dstBPR + x * 3 * 4) = e6; |
| 209 | *(uint32*)(dstBits + (y * 3 + 2) * dstBPR + (x * 3 + 1) * 4) = e7; |
| 210 | *(uint32*)(dstBits + (y * 3 + 2) * dstBPR + (x * 3 + 2) * 4) = e8; |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | |
| 216 | static void |
| 217 | scale4x(const uint8* srcBits, uint8* dstBits, int32 srcWidth, int32 srcHeight, |
| 218 | int32 srcBPR, int32 dstBPR) |
| 219 | { |
| 220 | // scale4x is just scale2x twice |
| 221 | BBitmap* tmp = new BBitmap(BRect(0, 0, srcWidth * 2 - 1, |
| 222 | srcHeight * 2 - 1), B_RGBA32); |
| 223 | uint8* tmpBits = (uint8*)tmp->Bits(); |
| 224 | int32 tmpBPR = tmp->BytesPerRow(); |
| 225 | |
| 226 | scale2x(srcBits, tmpBits, srcWidth, srcHeight, srcBPR, tmpBPR); |
| 227 | scale2x(tmpBits, dstBits, srcWidth * 2, srcHeight * 2, tmpBPR, dstBPR); |
| 228 | |
| 229 | delete tmp; |
| 230 | } |
| 231 | |
| 232 | |
| 623 | } else if (dstWidth == 3 * width && dstHeight == 3 * height) { |
| 624 | // scale using the scale3x algorithm |
| 625 | BBitmap* converted = new BBitmap(BRect(0, 0, width - 1, height - 1), |
| 626 | result->ColorSpace()); |
| 627 | converted->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8); |
| 628 | uint8* convertedBits = (uint8*)converted->Bits(); |
| 629 | int32 convertedBPR = converted->BytesPerRow(); |
| 630 | scale3x(convertedBits, dst, width, height, convertedBPR, dstBPR); |
| 631 | } else if (dstWidth == 4 * width && dstHeight == 4 * height) { |
| 632 | // scale using the scale4x algorithm |
| 633 | BBitmap* converted = new BBitmap(BRect(0, 0, width - 1, height - 1), |
| 634 | result->ColorSpace()); |
| 635 | converted->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8); |
| 636 | uint8* convertedBits = (uint8*)converted->Bits(); |
| 637 | int32 convertedBPR = converted->BytesPerRow(); |
| 638 | scale4x(convertedBits, dst, width, height, convertedBPR, dstBPR); |