Ticket #7130: scale2x icon scaling 2.diff

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

patch with variables declared inline, fixed a style issue

  • src/libs/icon/IconUtils.cpp

    diff --git a/src/libs/icon/IconUtils.cpp b/src/libs/icon/IconUtils.cpp
    index 83a99f3..9d590de 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    switch(bpp) {
     120        case 1:
     121        {
     122            for(int32 looph = 0; looph < srcHeight; ++looph) {
     123                for(int32 loopw = 0; loopw < srcWidth; ++ loopw) {
     124                    uint8 b = *(uint8*)(srcBits + (MAX(0, looph - 1) * srcBPR)
     125                        + (1 * loopw));
     126                    uint8 d = *(uint8*)(srcBits + (looph * srcBPR)
     127                        + (1 * MAX(0, loopw - 1)));
     128                    uint8 e = *(uint8*)(srcBits + (looph * srcBPR)
     129                        + (1 * loopw));
     130                    uint8 f = *(uint8*)(srcBits + (looph * srcBPR)
     131                        + (1 * MIN(srcWidth - 1, loopw+1)));
     132                    uint8 h = *(uint8*)(srcBits + (MIN(srcHeight - 1, looph + 1)
     133                        * srcBPR) + (1 * loopw));
     134
     135                    uint8 e0 = d == b && b != f && d != h ? d : e;
     136                    uint8 e1 = b == f && b != d && f != h ? f : e;
     137                    uint8 e2 = d == h && d != b && h != f ? d : e;
     138                    uint8 e3 = h == f && d != h && b != f ? f : e;
     139
     140                    *(uint8*)(dstBits + looph * 2 * dstBPR
     141                        + loopw * 2 * 1) = e0;
     142                    *(uint8*)(dstBits + looph * 2 * dstBPR
     143                        + (loopw * 2 + 1) * 1) = e1;
     144                    *(uint8*)(dstBits + (looph * 2 + 1) * dstBPR
     145                        + loopw * 2 * 1) = e2;
     146                    *(uint8*)(dstBits + (looph * 2 + 1) * dstBPR
     147                        + (loopw * 2 + 1) * 1) = e3;
     148                }
     149            }
     150            break;
     151        }
     152        case 4:
     153        {
     154            for(int32 looph = 0; looph < srcHeight; ++looph) {
     155                for(int32 loopw = 0; loopw < srcWidth; ++ loopw) {
     156                    uint32 b = *(uint32*)(srcBits + (MAX(0, looph - 1) * srcBPR)
     157                        + (4 * loopw));
     158                    uint32 d = *(uint32*)(srcBits + (looph * srcBPR)
     159                        + (4 * MAX(0, loopw - 1)));
     160                    uint32 e = *(uint32*)(srcBits + (looph * srcBPR)
     161                        + (4 * loopw));
     162                    uint32 f = *(uint32*)(srcBits + (looph * srcBPR)
     163                        + (4 * MIN(srcWidth - 1,loopw + 1)));
     164                    uint32 h =
     165                        *(uint32*)(srcBits + (MIN(srcHeight - 1, looph + 1)
     166                        * srcBPR) + (4 * loopw));
     167
     168                    uint32 e0 = d == b && b != f && d != h ? d : e;
     169                    uint32 e1 = b == f && b != d && f != h ? f : e;
     170                    uint32 e2 = d == h && d != b && h != f ? d : e;
     171                    uint32 e3 = h == f && d != h && b != f ? f : e;
     172
     173                    *(uint32*)(dstBits + looph * 2 * dstBPR
     174                        + loopw * 2 * 4) = e0;
     175                    *(uint32*)(dstBits + looph * 2 * dstBPR
     176                        + (loopw * 2 + 1) * 4) = e1;
     177                    *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     178                        + loopw * 2 * 4) = e2;
     179                    *(uint32*)(dstBits + (looph * 2 + 1) * dstBPR
     180                        + (loopw * 2 + 1) * 4) = e3;
     181                }
     182            }
     183            break;
     184        }
     185    }
     186}
     187
     188
    103189//  #pragma mark -
    104190
    105191
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    464550
    465551    const rgb_color* colorMap = system_colors()->color_list;
    466552
     553    const uint8* srcStart = src;
     554    uint8* dstStart = dst;
     555
    467556    for (uint32 y = 0; y < height; y++) {
    468557        uint32* d = (uint32*)dst;
    469558        const uint8* s = src;
    BIconUtils::ConvertFromCMAP8(const uint8* src, uint32 width, uint32 height,  
    480569        dst += dstBPR;
    481570    }
    482571
     572    // reset src and dst back to their original locations
     573    src = srcStart;
     574    dst = dstStart;
     575
    483576    if (dstWidth > width || dstHeight > height) {
    484         // up scaling
    485         scale_bilinear((uint8*)result->Bits(), width, height, dstWidth,
    486             dstHeight, dstBPR);
     577        if (dstWidth == 2 * width && dstHeight == 2 * height) {
     578            // scale using the scale2x algorithm
     579            BBitmap* converted = new BBitmap(BRect(0, 0, width - 1, height - 1),
     580                result->ColorSpace());
     581            converted->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
     582            uint8* convertedBits = (uint8*)converted->Bits();
     583            int32 convertedBPR = converted->BytesPerRow();
     584            scale2x(convertedBits, dst, width, height, convertedBPR, dstBPR, 4);
     585        } else {
     586            // bilinear scaling
     587            scale_bilinear(dst, width, height, dstWidth, dstHeight, dstBPR);
     588        }
    487589    }
    488590
    489591    return B_OK;