⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rleaccel.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
 * highly optimised. *//* encode 32bpp rgb + a into 16bpp rgb, losing alpha */static int copy_opaque_16(void *dst, Uint32 *src, int n,                          GAL_PixelFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint16 *d = dst;    for(i = 0; i < n; i++) {        unsigned r, g, b;        RGB_FROM_PIXEL(*src, sfmt, r, g, b);        PIXEL_FROM_RGB(*d, dfmt, r, g, b);        src++;        d++;    }    return n * 2;}/* decode opaque pixels from 16bpp to 32bpp rgb + a */static int uncopy_opaque_16(Uint32 *dst, void *src, int n,                            RLEDestFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint16 *s = src;    unsigned alpha = dfmt->Amask ? 255 : 0;    for(i = 0; i < n; i++) {        unsigned r, g, b;        RGB_FROM_PIXEL(*s, sfmt, r, g, b);        PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha);        s++;        dst++;    }    return n * 2;}/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */static int copy_transl_565(void *dst, Uint32 *src, int n,                           GAL_PixelFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint32 *d = dst;    for(i = 0; i < n; i++) {        unsigned r, g, b, a;        Uint16 pix;        RGBA_FROM_8888(*src, sfmt, r, g, b, a);        PIXEL_FROM_RGB(pix, dfmt, r, g, b);        *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0);        src++;        d++;    }    return n * 4;}/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */static int copy_transl_555(void *dst, Uint32 *src, int n,                           GAL_PixelFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint32 *d = dst;    for(i = 0; i < n; i++) {        unsigned r, g, b, a;        Uint16 pix;        RGBA_FROM_8888(*src, sfmt, r, g, b, a);        PIXEL_FROM_RGB(pix, dfmt, r, g, b);        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);        src++;        d++;    }    return n * 4;}/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */static int uncopy_transl_16(Uint32 *dst, void *src, int n,                            RLEDestFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint32 *s = src;    for(i = 0; i < n; i++) {        unsigned r, g, b, a;        Uint32 pix = *s++;        a = (pix & 0x3e0) >> 2;        pix = (pix & ~0x3e0) | pix >> 16;        RGB_FROM_PIXEL(pix, sfmt, r, g, b);        PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);        dst++;    }    return n * 4;}/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */static int copy_32(void *dst, Uint32 *src, int n,                   GAL_PixelFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint32 *d = dst;    for(i = 0; i < n; i++) {        unsigned r, g, b, a;        Uint32 pixel;        RGBA_FROM_8888(*src, sfmt, r, g, b, a);        PIXEL_FROM_RGB(pixel, dfmt, r, g, b);        *d++ = pixel | a << 24;        src++;    }    return n * 4;}/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */static int uncopy_32(Uint32 *dst, void *src, int n,                     RLEDestFormat *sfmt, GAL_PixelFormat *dfmt){    int i;    Uint32 *s = src;    for(i = 0; i < n; i++) {        unsigned r, g, b, a;        Uint32 pixel = *s++;        RGB_FROM_PIXEL(pixel, sfmt, r, g, b);        a = pixel >> 24;        PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a);        dst++;    }    return n * 4;}#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255)#define ISTRANSL(pixel, fmt)        \    ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U)/* convert surface to be quickly alpha-blittable onto dest, if possible */static int RLEAlphaSurface(GAL_Surface *surface){    GAL_Surface *dest;    GAL_PixelFormat *df;    int maxsize = 0;    int max_opaque_run;    int max_transl_run = 65535;    unsigned masksum;    Uint8 *rlebuf, *dst;    int (*copy_opaque)(void *, Uint32 *, int,                       GAL_PixelFormat *, GAL_PixelFormat *);    int (*copy_transl)(void *, Uint32 *, int,                       GAL_PixelFormat *, GAL_PixelFormat *);    dest = surface->map->dst;    if(!dest)        return -1;    df = dest->format;    if(surface->format->BitsPerPixel != 32)        return -1;                /* only 32bpp source supported */    /* find out whether the destination is one we support,       and determine the max size of the encoded result */    masksum = df->Rmask | df->Gmask | df->Bmask;    switch(df->BytesPerPixel) {    case 2:        /* 16bpp: only support 565 and 555 formats */        switch(masksum) {        case 0xffff:            if(df->Gmask == 0x07e0               || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) {                copy_opaque = copy_opaque_16;                copy_transl = copy_transl_565;            } else                return -1;            break;        case 0x7fff:            if(df->Gmask == 0x03e0               || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) {                copy_opaque = copy_opaque_16;                copy_transl = copy_transl_555;            } else                return -1;            break;        default:            return -1;        }        max_opaque_run = 255;        /* runs stored as bytes */        /* worst case is alternating opaque and translucent pixels,           with room for alignment padding between lines */        maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2;        break;    case 4:        if(masksum != 0x00ffffff)            return -1;                /* requires unused high byte */        copy_opaque = copy_32;        copy_transl = copy_32;        max_opaque_run = 255;        /* runs stored as short ints */        /* worst case is alternating opaque and translucent pixels */        maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4;        break;    default:        return -1;                /* anything else unsupported right now */    }    maxsize += sizeof(RLEDestFormat);    rlebuf = (Uint8 *)malloc(maxsize);    if(!rlebuf) {        GAL_OutOfMemory();        return -1;    }    {        /* save the destination format so we can undo the encoding later */        RLEDestFormat *r = (RLEDestFormat *)rlebuf;        r->BytesPerPixel = df->BytesPerPixel;        r->Rloss = df->Rloss;        r->Gloss = df->Gloss;        r->Bloss = df->Bloss;        r->Rshift = df->Rshift;        r->Gshift = df->Gshift;        r->Bshift = df->Bshift;        r->Ashift = df->Ashift;        r->Rmask = df->Rmask;        r->Gmask = df->Gmask;        r->Bmask = df->Bmask;        r->Amask = df->Amask;    }    dst = rlebuf + sizeof(RLEDestFormat);    /* Do the actual encoding */    {        int x, y;        int h = surface->h, w = surface->w;        GAL_PixelFormat *sf = surface->format;        Uint32 *src = (Uint32 *)((Uint8 *)surface->pixels + surface->offset);        Uint8 *lastline = dst;        /* end of last non-blank line */        /* opaque counts are 8 or 16 bits, depending on target depth */#define ADD_OPAQUE_COUNTS(n, m)                        \        if(df->BytesPerPixel == 4) {                \            ((Uint16 *)dst)[0] = n;                \            ((Uint16 *)dst)[1] = m;                \            dst += 4;                                \        } else {                                \            dst[0] = n;                                \            dst[1] = m;                                \            dst += 2;                                \        }        /* translucent counts are always 16 bit */#define ADD_TRANSL_COUNTS(n, m)                \        (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4)        for(y = 0; y < h; y++) {            int runstart, skipstart;            int blankline = 0;            /* First encode all opaque pixels of a scan line */            x = 0;            do {                int run, skip, len;                skipstart = x;                while(x < w && !ISOPAQUE(src[x], sf))                    x++;                runstart = x;                while(x < w && ISOPAQUE(src[x], sf))                    x++;                skip = runstart - skipstart;                if(skip == w)                    blankline = 1;                run = x - runstart;                while(skip > max_opaque_run) {                    ADD_OPAQUE_COUNTS(max_opaque_run, 0);                    skip -= max_opaque_run;                }                len = MIN(run, max_opaque_run);                ADD_OPAQUE_COUNTS(skip, len);                dst += copy_opaque(dst, src + runstart, len, sf, df);                runstart += len;                run -= len;                while(run) {                    len = MIN(run, max_opaque_run);                    ADD_OPAQUE_COUNTS(0, len);                    dst += copy_opaque(dst, src + runstart, len, sf, df);                    runstart += len;                    run -= len;                }            } while(x < w);            /* Make sure the next output address is 32-bit aligned */            dst += (unsigned long)dst & 2;            /* Next, encode all translucent pixels of the same scan line */            x = 0;            do {                int run, skip, len;                skipstart = x;                while(x < w && !ISTRANSL(src[x], sf))                    x++;                runstart = x;                while(x < w && ISTRANSL(src[x], sf))                    x++;                skip = runstart - skipstart;                blankline &= (skip == w);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -