📄 rleaccel.c
字号:
d = (d | d << 16) & 0x07e0f81f; \ d += (s - d) * alpha >> 5; \ d &= 0x07e0f81f; \ dst = d | d >> 16; \ } while(0)#define BLIT_TRANSL_555(src, dst) \ do { \ Uint32 s = src; \ Uint32 d = dst; \ unsigned alpha = (s & 0x3e0) >> 5; \ s &= 0x03e07c1f; \ d = (d | d << 16) & 0x03e07c1f; \ d += (s - d) * alpha >> 5; \ d &= 0x03e07c1f; \ dst = d | d >> 16; \ } while(0)/* used to save the destination format in the encoding. Designed to be macro-compatible with GAL_PixelFormat but without the unneeded fields */typedef struct { Uint8 BytesPerPixel; Uint8 Rloss; Uint8 Gloss; Uint8 Bloss; Uint8 Rshift; Uint8 Gshift; Uint8 Bshift; Uint8 Ashift; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask;} RLEDestFormat;/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, GAL_Surface *dst, Uint8 *dstbuf, GAL_Rect *srcrect){ GAL_PixelFormat *df = dst->format; /* * clipped blitter: Ptype is the destination pixel type, * Ctype the translucent count type, and do_blend the macro * to blend one pixel. */#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ do { \ int linecount = srcrect->h; \ int left = srcrect->x; \ int right = left + srcrect->w; \ dstbuf -= left * sizeof(Ptype); \ do { \ int ofs = 0; \ /* blit opaque pixels on one line */ \ do { \ unsigned run; \ ofs += ((Ctype *)srcbuf)[0]; \ run = ((Ctype *)srcbuf)[1]; \ srcbuf += 2 * sizeof(Ctype); \ if(run) { \ /* clip to left and right borders */ \ int cofs = ofs; \ int crun = run; \ if(left - cofs > 0) { \ crun -= left - cofs; \ cofs = left; \ } \ if(crun > right - cofs) \ crun = right - cofs; \ if(crun > 0) \ PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ srcbuf + (cofs - ofs) * sizeof(Ptype), \ (unsigned)crun, sizeof(Ptype)); \ srcbuf += run * sizeof(Ptype); \ ofs += run; \ } else if(!ofs) \ return; \ } while(ofs < w); \ /* skip padding if necessary */ \ if(sizeof(Ptype) == 2) \ srcbuf += (unsigned long)srcbuf & 2; \ /* blit translucent pixels on the same line */ \ ofs = 0; \ do { \ unsigned run; \ ofs += ((Uint16 *)srcbuf)[0]; \ run = ((Uint16 *)srcbuf)[1]; \ srcbuf += 4; \ if(run) { \ /* clip to left and right borders */ \ int cofs = ofs; \ int crun = run; \ if(left - cofs > 0) { \ crun -= left - cofs; \ cofs = left; \ } \ if(crun > right - cofs) \ crun = right - cofs; \ if(crun > 0) { \ Ptype *dst = (Ptype *)dstbuf + cofs; \ Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ int i; \ for(i = 0; i < crun; i++) \ do_blend(src[i], dst[i]); \ } \ srcbuf += run * 4; \ ofs += run; \ } \ } while(ofs < w); \ dstbuf += dst->pitch; \ } while(--linecount); \ } while(0) switch(df->BytesPerPixel) { case 2: if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); else RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); break; case 4: RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); break; }}/* blit a pixel-alpha RLE surface */int GAL_RLEAlphaBlit(GAL_Surface *src, GAL_Rect *srcrect, GAL_Surface *dst, GAL_Rect *dstrect){ int x, y; int w = src->w; Uint8 *srcbuf, *dstbuf; GAL_PixelFormat *df = dst->format;#if 0 /* Lock the destination if necessary */ if(dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT)) { GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video; if(video->LockHWSurface(this, dst) < 0) { return -1; } }#endif x = dstrect->x; y = dstrect->y; dstbuf = (Uint8 *)dst->pixels + dst->offset + y * dst->pitch + x * df->BytesPerPixel; srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat); { /* skip lines at the top if necessary */ int vskip = srcrect->y; if(vskip) { int ofs; if(df->BytesPerPixel == 2) { /* the 16/32 interleaved format */ do { /* skip opaque line */ ofs = 0; do { int run; ofs += srcbuf[0]; run = srcbuf[1]; srcbuf += 2; if(run) { srcbuf += 2 * run; ofs += run; } else if(!ofs) goto done; } while(ofs < w); /* skip padding */ srcbuf += (unsigned long)srcbuf & 2; /* skip translucent line */ ofs = 0; do { int run; ofs += ((Uint16 *)srcbuf)[0]; run = ((Uint16 *)srcbuf)[1]; srcbuf += 4 * (run + 1); ofs += run; } while(ofs < w); } while(--vskip); } else { /* the 32/32 interleaved format */ vskip <<= 1; /* opaque and translucent have same format */ do { ofs = 0; do { int run; ofs += ((Uint16 *)srcbuf)[0]; run = ((Uint16 *)srcbuf)[1]; srcbuf += 4; if(run) { srcbuf += 4 * run; ofs += run; } else if(!ofs) goto done; } while(ofs < w); } while(--vskip); } } } /* if left or right edge clipping needed, call clip blit */ if(srcrect->x || srcrect->w != src->w) { RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect); } else { /* * non-clipped blitter. Ptype is the destination pixel type, * Ctype the translucent count type, and do_blend the * macro to blend one pixel. */#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ do { \ int linecount = srcrect->h; \ do { \ int ofs = 0; \ /* blit opaque pixels on one line */ \ do { \ unsigned run; \ ofs += ((Ctype *)srcbuf)[0]; \ run = ((Ctype *)srcbuf)[1]; \ srcbuf += 2 * sizeof(Ctype); \ if(run) { \ PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ run, sizeof(Ptype)); \ srcbuf += run * sizeof(Ptype); \ ofs += run; \ } else if(!ofs) \ goto done; \ } while(ofs < w); \ /* skip padding if necessary */ \ if(sizeof(Ptype) == 2) \ srcbuf += (unsigned long)srcbuf & 2; \ /* blit translucent pixels on the same line */ \ ofs = 0; \ do { \ unsigned run; \ ofs += ((Uint16 *)srcbuf)[0]; \ run = ((Uint16 *)srcbuf)[1]; \ srcbuf += 4; \ if(run) { \ Ptype *dst = (Ptype *)dstbuf + ofs; \ unsigned i; \ for(i = 0; i < run; i++) { \ Uint32 src = *(Uint32 *)srcbuf; \ do_blend(src, *dst); \ srcbuf += 4; \ dst++; \ } \ ofs += run; \ } \ } while(ofs < w); \ dstbuf += dst->pitch; \ } while(--linecount); \ } while(0) switch(df->BytesPerPixel) { case 2: if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); else RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); break; case 4: RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); break; } } done:#if 0 /* Unlock the destination if necessary */ if(dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT)) { GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video; video->UnlockHWSurface(this, dst); }#endif return 0;}/* * Auxiliary functions: * The encoding functions take 32bpp rgb + a, and * return the number of bytes copied to the destination. * The decoding functions copy to 32bpp rgb + a, and * return the number of bytes copied from the source. * These are only used in the encoder and un-RLE code and are therefore not
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -