Annotation of frontvm/hardware/scalebit.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This file is part of the Scale2x project.
                      3:  *
                      4:  * Copyright (C) 2001-2003 Andrea Mazzoleni
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify
                      7:  * it under the terms of the GNU General Public License as published by
                      8:  * the Free Software Foundation; either version 2 of the License, or
                      9:  * (at your option) any later version.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  * GNU General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with this program; if not, write to the Free Software
                     18:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     19:  */
                     20: 
                     21: /*
                     22:  * This file contains an example implementation of the Scale effect
                     23:  * applyed to a generic bitmap.
                     24:  *
                     25:  * You can find an high level description of the effect at :
                     26:  *
                     27:  * http://scale2x.sourceforge.net/
                     28:  *
                     29:  * Alternatively at the previous license terms, you are allowed to use this
                     30:  * code in your program with these conditions:
                     31:  * - the program is not used in commercial activities.
                     32:  * - the whole source code of the program is released with the binary.
                     33:  * - derivative works of the program are allowed.
                     34:  */
                     35: 
                     36: #if HAVE_CONFIG_H
                     37: #include <config.h>
                     38: #endif
                     39: 
                     40: #include "scale2x.h"
                     41: #include "scale3x.h"
                     42: 
                     43: #if HAVE_ALLOCA_H
                     44: #include <alloca.h>
                     45: #endif
                     46: 
                     47: #include <assert.h>
                     48: #include <stdlib.h>
                     49: 
                     50: /**
                     51:  * Apply the Scale2x effect on a group of rows. Used internally.
                     52:  */
                     53: static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
                     54: {
                     55:        switch (pixel) {
                     56: #if defined(__GNUC__) && defined(__i386__)
                     57:                case 1 : scale2x_8_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     58:                case 2 : scale2x_16_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     59:                case 4 : scale2x_32_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     60: #else
                     61:                case 1 : scale2x_8_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     62:                case 2 : scale2x_16_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     63:                case 4 : scale2x_32_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
                     64: #endif
                     65:        }
                     66: }
                     67: 
                     68: /**
                     69:  * Apply the Scale3x effect on a group of rows. Used internally.
                     70:  */
                     71: static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
                     72: {
                     73:        switch (pixel) {
                     74:                case 1 : scale3x_8_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
                     75:                case 2 : scale3x_16_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
                     76:                case 4 : scale3x_32_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
                     77:        }
                     78: }
                     79: 
                     80: /**
                     81:  * Apply the Scale4x effect on a group of rows. Used internally.
                     82:  */
                     83: static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
                     84: {
                     85:        stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
                     86:        stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
                     87: }
                     88: 
                     89: #define SCDST(i) (dst+(i)*dst_slice)
                     90: #define SCSRC(i) (src+(i)*src_slice)
                     91: #define SCMID(i) (mid[(i)])
                     92: 
                     93: /**
                     94:  * Apply the Scale2x effect on a bitmap.
                     95:  * The destination bitmap is filled with the scaled version of the source bitmap.
                     96:  * The source bitmap isn't modified.
                     97:  * The destination bitmap must be manually allocated before calling the function,
                     98:  * note that the resulting size is exactly 2x2 times the size of the source bitmap.
                     99:  * \param void_dst Pointer at the first pixel of the destination bitmap.
                    100:  * \param dst_slice Size in bytes of a destination bitmap row.
                    101:  * \param void_src Pointer at the first pixel of the source bitmap.
                    102:  * \param src_slice Size in bytes of a source bitmap row.
                    103:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    104:  * \param width Horizontal size in pixels of the source bitmap.
                    105:  * \param height Vertical size in pixels of the source bitmap.
                    106:  */
                    107: static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
                    108: {
                    109:        unsigned char* dst = (unsigned char*)void_dst;
                    110:        const unsigned char* src = (unsigned char*)void_src;
                    111:        unsigned count;
                    112: 
                    113:        assert(height >= 2);
                    114: 
                    115:        count = height;
                    116: 
                    117:        stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
                    118: 
                    119:        dst = SCDST(2);
                    120: 
                    121:        count -= 2;
                    122:        while (count) {
                    123:                stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
                    124: 
                    125:                dst = SCDST(2);
                    126:                src = SCSRC(1);
                    127: 
                    128:                --count;
                    129:        }
                    130: 
                    131:        stage_scale2x(SCDST(0), SCDST(1), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
                    132: 
                    133: #if defined(__GNUC__) && defined(__i386__)
                    134:        scale2x_mmx_emms();
                    135: #endif
                    136: }
                    137: 
                    138: /**
                    139:  * Apply the Scale32x effect on a bitmap.
                    140:  * The destination bitmap is filled with the scaled version of the source bitmap.
                    141:  * The source bitmap isn't modified.
                    142:  * The destination bitmap must be manually allocated before calling the function,
                    143:  * note that the resulting size is exactly 3x3 times the size of the source bitmap.
                    144:  * \param void_dst Pointer at the first pixel of the destination bitmap.
                    145:  * \param dst_slice Size in bytes of a destination bitmap row.
                    146:  * \param void_src Pointer at the first pixel of the source bitmap.
                    147:  * \param src_slice Size in bytes of a source bitmap row.
                    148:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    149:  * \param width Horizontal size in pixels of the source bitmap.
                    150:  * \param height Vertical size in pixels of the source bitmap.
                    151:  */
                    152: static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
                    153: {
                    154:        unsigned char* dst = (unsigned char*)void_dst;
                    155:        const unsigned char* src = (unsigned char*)void_src;
                    156:        unsigned count;
                    157: 
                    158:        assert(height >= 2);
                    159: 
                    160:        count = height;
                    161: 
                    162:        stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
                    163: 
                    164:        dst = SCDST(3);
                    165: 
                    166:        count -= 2;
                    167:        while (count) {
                    168:                stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
                    169: 
                    170:                dst = SCDST(3);
                    171:                src = SCSRC(1);
                    172: 
                    173:                --count;
                    174:        }
                    175: 
                    176:        stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
                    177: }
                    178: 
                    179: /**
                    180:  * Apply the Scale4x effect on a bitmap.
                    181:  * The destination bitmap is filled with the scaled version of the source bitmap.
                    182:  * The source bitmap isn't modified.
                    183:  * The destination bitmap must be manually allocated before calling the function,
                    184:  * note that the resulting size is exactly 4x4 times the size of the source bitmap.
                    185:  * \note This function requires also a small buffer bitmap used internally to store
                    186:  * intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
                    187:  * and a vertical size of 6 rows. The memory of this buffer must not be allocated
                    188:  * in video memory because it's also read and not only written. Generally
                    189:  * a heap (malloc) or a stack (alloca) buffer is the best choices.
                    190:  * \param void_dst Pointer at the first pixel of the destination bitmap.
                    191:  * \param dst_slice Size in bytes of a destination bitmap row.
                    192:  * \param void_mid Pointer at the first pixel of the buffer bitmap.
                    193:  * \param mid_slice Size in bytes of a buffer bitmap row.
                    194:  * \param void_src Pointer at the first pixel of the source bitmap.
                    195:  * \param src_slice Size in bytes of a source bitmap row.
                    196:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    197:  * \param width Horizontal size in pixels of the source bitmap.
                    198:  * \param height Vertical size in pixels of the source bitmap.
                    199:  */
                    200: static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
                    201: {
                    202:        unsigned char* dst = (unsigned char*)void_dst;
                    203:        const unsigned char* src = (unsigned char*)void_src;
                    204:        unsigned count;
                    205:        unsigned char* mid[6];
                    206: 
                    207:        assert(height >= 4);
                    208: 
                    209:        count = height;
                    210: 
                    211:        /* set the 6 buffer pointers */
                    212:        mid[0] = (unsigned char*)void_mid;
                    213:        mid[1] = mid[0] + mid_slice;
                    214:        mid[2] = mid[1] + mid_slice;
                    215:        mid[3] = mid[2] + mid_slice;
                    216:        mid[4] = mid[3] + mid_slice;
                    217:        mid[5] = mid[4] + mid_slice;
                    218: 
                    219:        stage_scale2x(SCMID(-2+6), SCMID(-1+6), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
                    220:        stage_scale2x(SCMID(0), SCMID(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
                    221:        stage_scale2x(SCMID(2), SCMID(3), SCSRC(1), SCSRC(2), SCSRC(3), pixel, width);
                    222:        stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-2+6), SCMID(-2+6), SCMID(-1+6), SCMID(0), pixel, width);
                    223: 
                    224:        dst = SCDST(4);
                    225: 
                    226:        stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-1+6), SCMID(0), SCMID(1), SCMID(2), pixel, width);
                    227: 
                    228:        dst = SCDST(4);
                    229: 
                    230:        count -= 4;
                    231:        while (count) {
                    232:                unsigned char* tmp;
                    233: 
                    234:                stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
                    235:                stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
                    236: 
                    237:                dst = SCDST(4);
                    238:                src = SCSRC(1);
                    239: 
                    240:                tmp = SCMID(0); /* shift by 2 position */
                    241:                SCMID(0) = SCMID(2);
                    242:                SCMID(2) = SCMID(4);
                    243:                SCMID(4) = tmp;
                    244:                tmp = SCMID(1);
                    245:                SCMID(1) = SCMID(3);
                    246:                SCMID(3) = SCMID(5);
                    247:                SCMID(5) = tmp;
                    248: 
                    249:                --count;
                    250:        }
                    251: 
                    252:        stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(3), pixel, width);
                    253:        stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
                    254: 
                    255:        dst = SCDST(4);
                    256: 
                    257:        stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(3), SCMID(4), SCMID(5), SCMID(5), pixel, width);
                    258: 
                    259: #if defined(__GNUC__) && defined(__i386__)
                    260:        scale2x_mmx_emms();
                    261: #endif
                    262: }
                    263: 
                    264: /**
                    265:  * Apply the Scale4x effect on a bitmap.
                    266:  * The destination bitmap is filled with the scaled version of the source bitmap.
                    267:  * The source bitmap isn't modified.
                    268:  * The destination bitmap must be manually allocated before calling the function,
                    269:  * note that the resulting size is exactly 4x4 times the size of the source bitmap.
                    270:  * \note This function operates like ::scale4x_buf() but the intermediate buffer is
                    271:  * automatically allocated in the stack.
                    272:  * \param void_dst Pointer at the first pixel of the destination bitmap.
                    273:  * \param dst_slice Size in bytes of a destination bitmap row.
                    274:  * \param void_src Pointer at the first pixel of the source bitmap.
                    275:  * \param src_slice Size in bytes of a source bitmap row.
                    276:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    277:  * \param width Horizontal size in pixels of the source bitmap.
                    278:  * \param height Vertical size in pixels of the source bitmap.
                    279:  */
                    280: static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
                    281: {
                    282:        unsigned mid_slice;
                    283:        void* mid;
                    284: 
                    285:        mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
                    286: 
                    287:        mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
                    288: 
                    289: #if HAVE_ALLOCA
                    290:        mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
                    291: 
                    292:        assert(mid != 0); /* alloca should never fails */
                    293: #else
                    294:        mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
                    295: 
                    296:        if (!mid)
                    297:                return;
                    298: #endif
                    299: 
                    300:        scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
                    301: 
                    302: #if !HAVE_ALLOCA
                    303:        free(mid);
                    304: #endif
                    305: }
                    306: 
                    307: /**
                    308:  * Check if the scale implementation is applicable at the given arguments.
                    309:  * \param scale Scale factor. 2, 3 or 4.
                    310:  * \param src_slice Size in bytes of a source bitmap row.
                    311:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    312:  * \param width Horizontal size in pixels of the source bitmap.
                    313:  * \return
                    314:  *   - -1 on precondition violated.
                    315:  *   - 0 on success.
                    316:  */
                    317: int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
                    318: {
                    319:        if (scale != 2 && scale != 3 && scale != 4)
                    320:                return -1;
                    321: 
                    322:        if (pixel != 1 && pixel != 2 && pixel != 4)
                    323:                return -1;
                    324: 
                    325:        switch (scale) {
                    326:        case 2 :
                    327:        case 3 :
                    328:                if (height < 2)
                    329:                        return -1;
                    330:        case 4 :
                    331:                if (height < 4)
                    332:                        return -1;
                    333:        }
                    334: 
                    335: #if defined(__GNUC__) && defined(__i386__)
                    336:        switch (scale) {
                    337:        case 2 :
                    338:        case 4 :
                    339:                if (width < (16 / pixel))
                    340:                        return -1;
                    341:                if (width % (8 / pixel) != 0)
                    342:                        return -1;
                    343:        case 3 :
                    344:                if (width < 2)
                    345:                        return -1;
                    346:        }
                    347: #else
                    348:        if (width < 2)
                    349:                return -1;
                    350: #endif
                    351: 
                    352:        return 0;
                    353: }
                    354: 
                    355: /**
                    356:  * Apply the Scale effect on a bitmap.
                    357:  * This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
                    358:  * \param scale Scale factor. 2, 3 or 4.
                    359:  * \param void_dst Pointer at the first pixel of the destination bitmap.
                    360:  * \param dst_slice Size in bytes of a destination bitmap row.
                    361:  * \param void_src Pointer at the first pixel of the source bitmap.
                    362:  * \param src_slice Size in bytes of a source bitmap row.
                    363:  * \param pixel Bytes per pixel of the source and destination bitmap.
                    364:  * \param width Horizontal size in pixels of the source bitmap.
                    365:  * \param height Vertical size in pixels of the source bitmap.
                    366:  */
                    367: void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
                    368: {
                    369:        switch (scale) {
                    370:        case 2 : scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
                    371:        case 3 : scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
                    372:        case 4 : scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
                    373:        }
                    374: }
                    375: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.