add support for alpha
This commit is contained in:
parent
429f8aa4c1
commit
0cbccd3a0e
1 changed files with 46 additions and 13 deletions
|
|
@ -21,6 +21,7 @@ typedef struct ZlibR{
|
||||||
int width;
|
int width;
|
||||||
int nrow, ncol;
|
int nrow, ncol;
|
||||||
int row, col; // next pixel to send
|
int row, col; // next pixel to send
|
||||||
|
int pixwid;
|
||||||
} ZlibR;
|
} ZlibR;
|
||||||
|
|
||||||
typedef struct ZlibW{
|
typedef struct ZlibW{
|
||||||
|
|
@ -68,19 +69,42 @@ zread(void *va, void *buf, int n)
|
||||||
int ncol = z->ncol;
|
int ncol = z->ncol;
|
||||||
uchar *b = buf, *e = b+n, *img;
|
uchar *b = buf, *e = b+n, *img;
|
||||||
int pixels; // number of pixels in row that can be sent now
|
int pixels; // number of pixels in row that can be sent now
|
||||||
|
int i, a, pixwid;
|
||||||
|
|
||||||
while(b+3 <= e){ // loop over image rows
|
pixwid = z->pixwid;
|
||||||
|
while(b+pixwid <= e){ // loop over image rows
|
||||||
if(z->row >= nrow)
|
if(z->row >= nrow)
|
||||||
break;
|
break;
|
||||||
if(z->col==0)
|
if(z->col==0)
|
||||||
*b++ = FilterNone;
|
*b++ = FilterNone;
|
||||||
pixels = (e-b)/3;
|
pixels = (e-b)/pixwid;
|
||||||
if(pixels > ncol - z->col)
|
if(pixels > ncol - z->col)
|
||||||
pixels = ncol - z->col;
|
pixels = ncol - z->col;
|
||||||
img = z->data + z->width * z->row + 3 * z->col;
|
img = z->data + z->width * z->row + pixwid * z->col;
|
||||||
|
|
||||||
memmove(b, img, 3*pixels);
|
memmove(b, img, pixwid*pixels);
|
||||||
b += 3*pixels;
|
if(pixwid == 4){
|
||||||
|
/*
|
||||||
|
* Convert to non-premultiplied alpha.
|
||||||
|
*/
|
||||||
|
for(i=0; i<pixels; i++, b+=4){
|
||||||
|
a = b[3];
|
||||||
|
if(a == 255 || a == 0)
|
||||||
|
;
|
||||||
|
else{
|
||||||
|
if(b[0] >= a)
|
||||||
|
b[0] = a;
|
||||||
|
b[0] = (b[0]*255)/a;
|
||||||
|
if(b[1] >= a)
|
||||||
|
b[1] = a;
|
||||||
|
b[1] = (b[1]*255)/a;
|
||||||
|
if(b[2] >= a)
|
||||||
|
b[2] = a;
|
||||||
|
b[2] = (b[2]*255)/a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
b += pixwid*pixels;
|
||||||
|
|
||||||
z->col += pixels;
|
z->col += pixels;
|
||||||
if(z->col >= ncol){
|
if(z->col >= ncol){
|
||||||
|
|
@ -119,17 +143,25 @@ zwrite(void *va, void *buf, int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Memimage*
|
static Memimage*
|
||||||
memRGB(Memimage *i)
|
memRGBA(Memimage *i)
|
||||||
{
|
{
|
||||||
Memimage *ni;
|
Memimage *ni;
|
||||||
|
char buf[32];
|
||||||
|
ulong dst;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BGR24 because we want R,G,B in big-endian order. Sigh.
|
* [A]BGR because we want R,G,B,[A] in big-endian order. Sigh.
|
||||||
*/
|
*/
|
||||||
if(i->chan == BGR24)
|
chantostr(buf, i->chan);
|
||||||
|
if(strchr(buf, 'a'))
|
||||||
|
dst = ABGR32;
|
||||||
|
else
|
||||||
|
dst = BGR24;
|
||||||
|
|
||||||
|
if(i->chan == dst)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
ni = allocmemimage(i->r, BGR24);
|
ni = allocmemimage(i->r, dst);
|
||||||
if(ni == nil)
|
if(ni == nil)
|
||||||
return ni;
|
return ni;
|
||||||
memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
|
memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
|
||||||
|
|
@ -149,7 +181,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
|
||||||
Tm *tm;
|
Tm *tm;
|
||||||
Memimage *rgb;
|
Memimage *rgb;
|
||||||
|
|
||||||
rgb = memRGB(r);
|
rgb = memRGBA(r);
|
||||||
if(rgb == nil)
|
if(rgb == nil)
|
||||||
return "allocmemimage nil";
|
return "allocmemimage nil";
|
||||||
crctab = mkcrctab(0xedb88320);
|
crctab = mkcrctab(0xedb88320);
|
||||||
|
|
@ -163,7 +195,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
|
||||||
put4(h, ncol); h += 4;
|
put4(h, ncol); h += 4;
|
||||||
put4(h, nrow); h += 4;
|
put4(h, nrow); h += 4;
|
||||||
*h++ = 8; // bit depth = 24 bit per pixel
|
*h++ = 8; // bit depth = 24 bit per pixel
|
||||||
*h++ = 2; // color type = rgb
|
*h++ = rgb->chan==BGR24 ? 2 : 6; // color type = rgb
|
||||||
*h++ = 0; // compression method = deflate
|
*h++ = 0; // compression method = deflate
|
||||||
*h++ = 0; // filter method
|
*h++ = 0; // filter method
|
||||||
*h++ = 0; // interlace method = no interlace
|
*h++ = 0; // interlace method = no interlace
|
||||||
|
|
@ -199,6 +231,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
|
||||||
zr.width = rgb->width * sizeof(ulong);
|
zr.width = rgb->width * sizeof(ulong);
|
||||||
zr.data = rgb->data->bdata;
|
zr.data = rgb->data->bdata;
|
||||||
zr.row = zr.col = 0;
|
zr.row = zr.col = 0;
|
||||||
|
zr.pixwid = chantodepth(rgb->chan)/8;
|
||||||
zw.bo = bo;
|
zw.bo = bo;
|
||||||
zw.buf = malloc(IDATSIZE);
|
zw.buf = malloc(IDATSIZE);
|
||||||
zw.b = zw.buf;
|
zw.b = zw.buf;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue