mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
jpg/tga: decode TGA32 images into RGBA32 ones
This commit is contained in:
parent
ce97bb4998
commit
9482f887f9
4 changed files with 37 additions and 13 deletions
|
@ -29,6 +29,7 @@ enum
|
|||
CRGBA32 = 6, /* one channel in correct data order for loadimage(RGBA32) */
|
||||
CYA16 = 7, /* one channel in correct data order for loadimage(Grey8+Alpha8) */
|
||||
CRGBVA16= 8, /* one channel in correct data order for loadimage(CMAP8+Alpha8) */
|
||||
CRGBA = 9, /* four channels, no map */
|
||||
|
||||
/* GIF flags */
|
||||
TRANSP = 1,
|
||||
|
|
|
@ -238,7 +238,7 @@ cmap_rle(Biobuf *bp, uchar *l, int num)
|
|||
}
|
||||
|
||||
static int
|
||||
rgba(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, int num)
|
||||
rgba(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, uchar *a, int num)
|
||||
{
|
||||
int i;
|
||||
uchar buf[4], tmp;
|
||||
|
@ -275,6 +275,7 @@ rgba(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, int num)
|
|||
*b++ = buf[0];
|
||||
*g++ = buf[1];
|
||||
*r++ = buf[2];
|
||||
*a++ = buf[3];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -285,7 +286,7 @@ rgba(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, int num)
|
|||
}
|
||||
|
||||
static int
|
||||
rgba_rle(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, int num)
|
||||
rgba_rle(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, uchar *a, int num)
|
||||
{
|
||||
uchar len;
|
||||
int i, got;
|
||||
|
@ -296,23 +297,27 @@ rgba_rle(Biobuf *bp, int bpp, uchar *r, uchar *g, uchar *b, int num)
|
|||
if(len & 0x80){
|
||||
len &= 0x7f;
|
||||
len += 1; /* run of zero is meaningless */
|
||||
if(rgba(bp, bpp, r, g, b, 1) != 1)
|
||||
if(rgba(bp, bpp, r, g, b, a, 1) != 1)
|
||||
break;
|
||||
for(i = 1; i < len && got+i < num; i++){
|
||||
r[i] = *r;
|
||||
g[i] = *g;
|
||||
b[i] = *b;
|
||||
if(bpp == 32)
|
||||
a[i] = *a;
|
||||
}
|
||||
len = i;
|
||||
}
|
||||
else{
|
||||
len += 1; /* raw block of zero is meaningless */
|
||||
if(rgba(bp, bpp, r, g, b, len) != len)
|
||||
if(rgba(bp, bpp, r, g, b, a, len) != len)
|
||||
break;
|
||||
}
|
||||
r += len;
|
||||
g += len;
|
||||
b += len;
|
||||
if(bpp == 32)
|
||||
a += len;
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
@ -380,7 +385,7 @@ Breadtga(Biobuf *bp)
|
|||
{
|
||||
Tga *h;
|
||||
int n, c, num;
|
||||
uchar *r, *g, *b;
|
||||
uchar *r, *g, *b, *a;
|
||||
Rawimage *ar, **array;
|
||||
|
||||
if((h = rdhdr(bp)) == nil){
|
||||
|
@ -429,8 +434,8 @@ Breadtga(Biobuf *bp)
|
|||
ar->chandesc = (h->cmapbpp == 32) ? CRGBV : CRGB1;
|
||||
}
|
||||
else{
|
||||
ar->nchans = 3;
|
||||
ar->chandesc = CRGB;
|
||||
ar->nchans = (h->bpp == 32) ? 4: 3;
|
||||
ar->chandesc = (h->bpp == 32) ? CRGBA: CRGB;
|
||||
}
|
||||
|
||||
ar->cmap = h->cmap;
|
||||
|
@ -445,6 +450,7 @@ Breadtga(Biobuf *bp)
|
|||
r = ar->chans[0];
|
||||
g = ar->chans[1];
|
||||
b = ar->chans[2];
|
||||
a = ar->chans[3];
|
||||
|
||||
num = h->width*h->height;
|
||||
switch(h->datatype){
|
||||
|
@ -452,7 +458,7 @@ Breadtga(Biobuf *bp)
|
|||
n = cmap(bp, r, num);
|
||||
break;
|
||||
case 2:
|
||||
n = rgba(bp, h->bpp, r, g, b, num);
|
||||
n = rgba(bp, h->bpp, r, g, b, a, num);
|
||||
break;
|
||||
case 3:
|
||||
n = luma(bp, h->bpp, r, num);
|
||||
|
@ -461,7 +467,7 @@ Breadtga(Biobuf *bp)
|
|||
n = cmap_rle(bp, r, num);
|
||||
break;
|
||||
case 10:
|
||||
n = rgba_rle(bp, h->bpp, r, g, b, num);
|
||||
n = rgba_rle(bp, h->bpp, r, g, b, a, num);
|
||||
break;
|
||||
case 11:
|
||||
n = luma_rle(bp, h->bpp, r, num);
|
||||
|
|
|
@ -166,6 +166,9 @@ show(int fd, char *name)
|
|||
if(outchan==GREY8 || (r->chandesc==CY && threeflag==0)){
|
||||
c = totruecolor(r, CY);
|
||||
outchan = GREY8;
|
||||
}else if(r->chandesc==CRGBA){
|
||||
c = totruecolor(r, CRGBA32);
|
||||
outchan = RGBA32;
|
||||
}else
|
||||
c = totruecolor(r, CRGB24);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,11 @@ totruecolor(Rawimage *i, int chandesc)
|
|||
int j, k;
|
||||
Rawimage *im;
|
||||
char err[ERRMAX];
|
||||
uchar *rp, *gp, *bp, *cmap, *inp, *outp, cmap1[4*256];
|
||||
uchar *rp, *gp, *bp, *ap, *cmap, *inp, *outp, cmap1[4*256];
|
||||
int r, g, b, Y, Cr, Cb, psize;
|
||||
double a;
|
||||
|
||||
if(chandesc!=CY && chandesc!=CRGB24)
|
||||
if(chandesc!=CY && chandesc!=CRGB24 && chandesc!=CRGBA32)
|
||||
return _remaperror("remap: can't convert to chandesc %d", chandesc);
|
||||
|
||||
err[0] = '\0';
|
||||
|
@ -31,8 +32,10 @@ totruecolor(Rawimage *i, int chandesc)
|
|||
memset(im, 0, sizeof(Rawimage));
|
||||
if(chandesc == CY)
|
||||
im->chanlen = i->chanlen;
|
||||
else
|
||||
else if(chandesc == CRGB24)
|
||||
im->chanlen = 3*i->chanlen;
|
||||
else
|
||||
im->chanlen = 4*i->chanlen;
|
||||
im->chandesc = chandesc;
|
||||
im->chans[0] = malloc(im->chanlen);
|
||||
if(im->chans[0] == nil){
|
||||
|
@ -101,11 +104,13 @@ totruecolor(Rawimage *i, int chandesc)
|
|||
break;
|
||||
|
||||
case CRGB:
|
||||
if(i->nchans != 3)
|
||||
case CRGBA:
|
||||
if(i->nchans != 3 && i->nchans != 4)
|
||||
return _remaperror("remap: can't handle nchans %d", i->nchans);
|
||||
rp = i->chans[0];
|
||||
gp = i->chans[1];
|
||||
bp = i->chans[2];
|
||||
ap = i->chans[3];
|
||||
if(chandesc == CY){
|
||||
for(j=0; j<i->chanlen; j++){
|
||||
r = *bp++;
|
||||
|
@ -116,6 +121,15 @@ totruecolor(Rawimage *i, int chandesc)
|
|||
}
|
||||
}else
|
||||
for(j=0; j<i->chanlen; j++){
|
||||
if(i->nchans == 4){
|
||||
*outp++ = *ap++;
|
||||
/* pre-multiply alpha */
|
||||
a = (double)ap[-1]/0xFF;
|
||||
*outp++ = *bp++ * a;
|
||||
*outp++ = *gp++ * a;
|
||||
*outp++ = *rp++ * a;
|
||||
continue;
|
||||
}
|
||||
*outp++ = *bp++;
|
||||
*outp++ = *gp++;
|
||||
*outp++ = *rp++;
|
||||
|
|
Loading…
Reference in a new issue