Ticket #7130: scale2x icon scaling 3.diff

File scale2x icon scaling 3.diff, 3.1 KB (added by jscipione, 13 years ago)

Assume both src and dst have 4 BPP, remove the case statement. Tiny style fix

  • src/libs/icon/IconUtils.cpp

    diff --git a/src/libs/icon/IconUtils.cpp b/src/libs/icon/IconUtils.cpp
    index 83a99f3..1e7deb2 100644
    a b scale_bilinear(uint8* bits, int32 srcWidth, int32 srcHeight, int32 dstWidth,  
    100100}
    101101
    102102
     103static void
     104scale2x(const uint8* srcBits, uint8* dstBits, int32 srcWidth, int32 srcHeight,
     105    int32 srcBPR, int32 dstBPR)
     106{
     107    /*
     108     * This implements the AdvanceMAME Scale2x algorithm found on:
     109     * http://scale2x.sourceforge.net/
     110     *
     111     * It is an incredibly simple and powerful image doubling routine that does
     112     * an astonishing job of doubling game graphic data while interpolating out
     113     * the jaggies.
     114     *
     115     * Derived from the (public domain) SDL version of the library by Pete
     116     * Shinners
     117     */
     118
     119    // Assume that both src and dst are 4 BPP (B_RGBA32)
     120    for(int32 looph = 0; looph < srcHeight; ++looph) {
     121        for(int32 loopw = 0; loopw < srcWidth; ++loopw) {
     122            uint32 b = *(uint32*)(srcBits + (MAX(0, looph - 1) * srcBPR)
     123                + (4 * loopw));
     124            uint32 d = *(uint32*)(srcBits + (looph * srcBPR)
     125                + (4 * MAX(0, loopw - 1)));
     126            uint32 e = *(uint32*)(srcBits + (looph * srcBPR)
     127                + (4 * loopw));
     128            uint32 f = *(uint32*)(srcBits + (looph * srcBPR)
     129                + (4 * MIN(srcWidth - 1,loopw + 1)));
     130            uint32 h =
     131                *(uint32*)(srcBits + (MIN(srcHeight - 1, looph + 1)
     132                * srcBPR) + (4 * loopw));
     133
     134            uint32 e0 = d == b && b != f && d != h ? d : e;
     135            uint32 e1 = b == f && b != d && f != h ? f : e;
     136            uint32 e2 = d == h && d != b && h != f ? d : e;
     137            uint32 e3 = h == f && d != h && b != f ? f : e;
     138
     139            *(uint32*)(dstBits + looph * 2 * dstBPR
     140                + loopw * 2 * 4) = e0;
     141            *(uint32*)(dstBits + looph * 2 * dstBPR
     142                + (loopw * 2 + 1) * 4) = e1;
     143            *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     144                + loopw * 2 * 4) = e2;
     145            *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     146                + (loopw * 2 + 1) * 4) = e3;
     147        }
     148    }
     149}
     150
     151
    103152//  #pragma mark -
    104153
    105154
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    464513
    465514    const rgb_color* colorMap = system_colors()->color_list;
    466515
     516    const uint8* srcStart = src;
     517    uint8* dstStart = dst;
     518
    467519    for (uint32 y = 0; y < height; y++) {
    468520        uint32* d = (uint32*)dst;
    469521        const uint8* s = src;
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    480532        dst += dstBPR;
    481533    }
    482534
     535    // reset src and dst back to their original locations
     536    src = srcStart;
     537    dst = dstStart;
     538
    483539    if (dstWidth > width || dstHeight > height) {
    484         // up scaling
    485         scale_bilinear((uint8*)result->Bits(), width, height, dstWidth,
    486             dstHeight, dstBPR);
     540        if (dstWidth == 2 * width && dstHeight == 2 * height) {
     541            // scale using the scale2x algorithm
     542            BBitmap* converted = new BBitmap(BRect(0, 0, width - 1, height - 1),
     543                result->ColorSpace());
     544            converted->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
     545            uint8* convertedBits = (uint8*)converted->Bits();
     546            int32 convertedBPR = converted->BytesPerRow();
     547            scale2x(convertedBits, dst, width, height, convertedBPR, dstBPR);
     548        } else {
     549            // bilinear scaling
     550            scale_bilinear(dst, width, height, dstWidth, dstHeight, dstBPR);
     551        }
    487552    }
    488553
    489554    return B_OK;