Ticket #7130: scale2x icon scaling.diff

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

scale2x BeOS icon scaling patch

  • src/libs/icon/IconUtils.cpp

    diff --git a/src/libs/icon/IconUtils.cpp b/src/libs/icon/IconUtils.cpp
    index 83a99f3..7f65566 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, int32 bpp)
     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    int looph, loopw;
     120
     121    switch(bpp) {
     122        case 1:
     123        {
     124            uint8 E0, E1, E2, E3, B, D, E, F, H;
     125
     126            for(looph = 0; looph < srcHeight; ++looph) {
     127                for(loopw = 0; loopw < srcWidth; ++ loopw) {
     128                    B = *(uint8*)(srcBits + (MAX(0, looph - 1) * srcBPR)
     129                        + (1 * loopw));
     130                    D = *(uint8*)(srcBits + (looph * srcBPR)
     131                        + (1 * MAX(0, loopw - 1)));
     132                    E = *(uint8*)(srcBits + (looph * srcBPR) + (1 * loopw));
     133                    F = *(uint8*)(srcBits + (looph * srcBPR)
     134                        + (1 * MIN(srcWidth - 1, loopw+1)));
     135                    H = *(uint8*)(srcBits + (MIN(srcHeight - 1, looph + 1)
     136                        * srcBPR) + (1 * loopw));
     137
     138                    E0 = D == B && B != F && D != H ? D : E;
     139                    E1 = B == F && B != D && F != H ? F : E;
     140                    E2 = D == H && D != B && H != F ? D : E;
     141                    E3 = H == F && D != H && B != F ? F : E;
     142
     143                    *(uint8*)(dstBits + looph * 2 * dstBPR
     144                        + loopw * 2 * 1) = E0;
     145                    *(uint8*)(dstBits + looph * 2 * dstBPR
     146                        + (loopw * 2 + 1) * 1) = E1;
     147                    *(uint8*)(dstBits + (looph * 2 + 1) * dstBPR
     148                        + loopw * 2 * 1) = E2;
     149                    *(uint8*)(dstBits + (looph * 2 + 1) * dstBPR
     150                        + (loopw * 2 + 1) * 1) = E3;
     151                }
     152            }
     153            break;
     154        }
     155        case 4:
     156        {
     157            uint32 E0, E1, E2, E3, B, D, E, F, H;
     158
     159            for(looph = 0; looph < srcHeight; ++looph) {
     160                for(loopw = 0; loopw < srcWidth; ++ loopw) {
     161                    B = *(uint32*)(srcBits + (MAX(0, looph - 1) * srcBPR)
     162                        + (4 * loopw));
     163                    D = *(uint32*)(srcBits + (looph * srcBPR)
     164                        + (4 * MAX(0, loopw - 1)));
     165                    E = *(uint32*)(srcBits + (looph * srcBPR) + (4 * loopw));
     166                    F = *(uint32*)(srcBits + (looph * srcBPR)
     167                        + (4 * MIN(srcWidth - 1,loopw + 1)));
     168                    H = *(uint32*)(srcBits + (MIN(srcHeight - 1, looph + 1)
     169                        * srcBPR) + (4 * loopw));
     170
     171                    E0 = D == B && B != F && D != H ? D : E;
     172                    E1 = B == F && B != D && F != H ? F : E;
     173                    E2 = D == H && D != B && H != F ? D : E;
     174                    E3 = H == F && D != H && B != F ? F : E;
     175
     176                    *(uint32*)(dstBits + looph * 2 * dstBPR
     177                        + loopw * 2 * 4) = E0;
     178                    *(uint32*)(dstBits + looph * 2 * dstBPR
     179                        + (loopw * 2 + 1) * 4) = E1;
     180                    *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     181                        + loopw * 2 * 4) = E2;
     182                    *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     183                        + (loopw * 2 + 1) * 4) = E3;
     184                }
     185            }
     186            break;
     187        }
     188    }
     189}
     190
     191
    103192//  #pragma mark -
    104193
    105194
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    464553
    465554    const rgb_color* colorMap = system_colors()->color_list;
    466555
     556    const uint8* srcStart = src;
     557    uint8* dstStart = dst;
     558
    467559    for (uint32 y = 0; y < height; y++) {
    468560        uint32* d = (uint32*)dst;
    469561        const uint8* s = src;
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    480572        dst += dstBPR;
    481573    }
    482574
     575    // reset src and dst back to their original locations
     576    src = srcStart;
     577    dst = dstStart;
     578
    483579    if (dstWidth > width || dstHeight > height) {
    484         // up scaling
    485         scale_bilinear((uint8*)result->Bits(), width, height, dstWidth,
    486             dstHeight, dstBPR);
     580        if (dstWidth == 2 * width && dstHeight == 2 * height) {
     581            // scale using the scale2x algorithm
     582            BBitmap* converted = new BBitmap(BRect(0, 0, width - 1, height - 1),
     583                result->ColorSpace());
     584            converted->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
     585            uint8* convertedBits = (uint8*)converted->Bits();
     586            int32 convertedBPR = converted->BytesPerRow();
     587            scale2x(convertedBits, dst, width, height, convertedBPR, dstBPR, 4);
     588        } else {
     589            // bilinear scaling
     590            scale_bilinear(dst, width, height, dstWidth, dstHeight, dstBPR);
     591        }
    487592    }
    488593
    489594    return B_OK;