Annotation of frontvm/hardware/scalebit.c, revision 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.