diff --git a/src/modules/Image/encodings/pvr.c b/src/modules/Image/encodings/pvr.c index 02628af4f61fe6b322a54b499a3bb57f150823f0..12fb0d8db09a0f12df2cf349612dfd418957dbed 100644 --- a/src/modules/Image/encodings/pvr.c +++ b/src/modules/Image/encodings/pvr.c @@ -4,7 +4,7 @@ #include <ctype.h> #include "stralloc.h" -RCSID("$Id: pvr.c,v 1.2 2000/02/27 12:50:44 marcus Exp $"); +RCSID("$Id: pvr.c,v 1.3 2000/02/27 13:06:45 marcus Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -158,7 +158,6 @@ static void pvr_decode_twiddled(INT32 attr, unsigned char *s, rgb_group *dst, dst->r = ((p&0x7c00)>>7)|((p&0x7000)>>12); dst->g = ((p&0x03e0)>>2)|((p&0x0380)>>7); dst->b = ((p&0x001f)<<3)|((p&0x001c)>>2); - src+=2; dst++; } dst += stride; @@ -173,7 +172,6 @@ static void pvr_decode_twiddled(INT32 attr, unsigned char *s, rgb_group *dst, dst->r = ((p&0xf800)>>8)|((p&0xe000)>>13); dst->g = ((p&0x07e0)>>3)|((p&0x0600)>>9); dst->b = ((p&0x001f)<<3)|((p&0x001c)>>2); - src+=2; dst++; } dst += stride; @@ -188,7 +186,67 @@ static void pvr_decode_twiddled(INT32 attr, unsigned char *s, rgb_group *dst, dst->r = ((p&0x0f00)>>4)|((p&0x0f00)>>8); dst->g = (p&0x00f0)|((p&0x00f0)>>4); dst->b = ((p&0x000f)<<4)|(p&0x000f); - src+=2; + dst++; + } + dst += stride; + } + break; + } +} + +static void pvr_decode_alpha_rect(INT32 attr, unsigned char *src, + rgb_group *dst, INT32 stride, + unsigned int h, unsigned int w) +{ + INT32 cnt = h * w; + switch(attr&0xff) { + case MODE_ARGB1555: + while(cnt--) { + if(src[1]&0x8000) + dst->r = dst->g = dst->b = ~0; + else + dst->r = dst->g = dst->b = 0; + src+=2; + dst++; + } + break; + case MODE_ARGB4444: + while(cnt--) { + int a = src[1]&0xf0; + a |= a>>4; + dst->r = dst->g = dst->b = a; + src+=2; + dst++; + } + break; + } +} + +static void pvr_decode_alpha_twiddled(INT32 attr, unsigned char *s, + rgb_group *dst, INT32 stride, + unsigned int sz) +{ + unsigned int x, y; + unsigned char *src; + switch(attr&0xff) { + case MODE_ARGB1555: + for(y=0; y<sz; y++) { + for(x=0; x<sz; x++) { + if(s[(((twiddletab[x]<<1)|twiddletab[y])<<1)+1]&0x80) + dst->r = dst->g = dst->b = ~0; + else + dst->r = dst->g = dst->b = 0; + dst++; + } + dst += stride; + } + break; + case MODE_ARGB4444: + for(y=0; y<sz; y++) { + for(x=0; x<sz; x++) { + int a = s[(((twiddletab[x]<<1)|twiddletab[y])<<1)+1]&0xf0; + a |= a>>4; + dst->r = dst->g = dst->b = a; dst++; } dst += stride; @@ -323,6 +381,28 @@ void img_pvr_decode(INT32 args,int header_only) pvr_decode_twiddled(attr, s+bpp*w*x, img->img+w*x, 0, w); else pvr_decode_rect(attr, s, img->img, 0, h, w); + + if(hasalpha) { + + push_text("alpha"); + push_int(w); + push_int(h); + o=clone_object(image_program,2); + img=(struct image*)get_storage(o,image_program); + push_object(o); + n++; + + if(twiddle) + if(h<w) + for(x=0; x<w; x+=h) + pvr_decode_alpha_twiddled(attr, s+bpp*h*x, img->img+x, w-h, h); + else + for(x=0; x<h; x+=w) + pvr_decode_alpha_twiddled(attr, s+bpp*w*x, img->img+w*x, 0, w); + else + pvr_decode_alpha_rect(attr, s, img->img, 0, h, w); + } + } f_aggregate_mapping(2*n);