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

📄 rleaccel.c

📁 linux下的图形界面开发minigui最新源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		int ofs = 0;						      \		for(;;) {						      \		    unsigned run;					      \		    ofs += *(Type *)srcbuf;				      \		    run = ((Type *)srcbuf)[1];				      \		    srcbuf += 2 * sizeof(Type);				      \		    if(run) {						      \			do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \			srcbuf += run * bpp;				      \			ofs += run;					      \		    } else if(!ofs)					      \			break;						      \		    if(ofs == w) {					      \			ofs = 0;					      \			dstbuf += dst->pitch;				      \			if(!--linecount)				      \			    break;					      \		    }							      \		}							      \	    } while(0)	    CHOOSE_BLIT(RLEBLIT, alpha, fmt);#undef RLEBLIT	}done:	/* Unlock the destination if necessary */	if ( dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT) ) {		GAL_VideoDevice *video = current_video;		GAL_VideoDevice *this  = current_video;#if 0		video->UnlockHWSurface(this, dst);#endif	}	return(0);}#undef OPAQUE_BLIT/* * Per-pixel blitting macros for translucent pixels: * These use the same techniques as the per-surface blitting macros *//* * For 32bpp pixels, we have made sure the alpha is stored in the top * 8 bits, so proceed as usual */#define BLIT_TRANSL_888(src, dst)				\    do {							\        Uint32 s = src;						\	Uint32 d = dst;						\	unsigned alpha = s >> 24;				\	Uint32 s1 = s & 0xff00ff;				\	Uint32 d1 = d & 0xff00ff;				\	d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;	\	s &= 0xff00;						\	d &= 0xff00;						\	d = (d + ((s - d) * alpha >> 8)) & 0xff00;		\	dst = d1 | d;						\    } while(0)/* * For 16bpp pixels, we have stored the 5 most significant alpha bits in * bits 5-10. As before, we can process all 3 RGB components at the same time. */#define BLIT_TRANSL_565(src, dst)		\    do {					\        Uint32 s = src;				\	Uint32 d = dst;				\	unsigned alpha = (s & 0x3e0) >> 5;	\	s &= 0x07e0f81f;			\	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;    /* Lock the destination if necessary */    if(dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT)) {	GAL_VideoDevice *video = current_video;	GAL_VideoDevice *this  = current_video;#if 0	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:    /* Unlock the destination if necessary */    if(dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT)) {	GAL_VideoDevice *video = current_video;	GAL_VideoDevice *this  = current_video;#if 0	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 * 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)

⌨️ 快捷键说明

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