URI: 
       tadd support for alpha - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 0cbccd3a0e84526d0de02d003d88c456be1f0ca7
   DIR parent 429f8aa4c12c7fb04a0285ca31db5d0ab88b53d8
  HTML Author: rsc <devnull@localhost>
       Date:   Tue, 15 Feb 2005 05:04:18 +0000
       
       add support for alpha
       
       Diffstat:
         M src/cmd/jpg/writepng.c              |      61 ++++++++++++++++++++++++-------
       
       1 file changed, 47 insertions(+), 14 deletions(-)
       ---
   DIR diff --git a/src/cmd/jpg/writepng.c b/src/cmd/jpg/writepng.c
       t@@ -21,6 +21,7 @@ typedef struct ZlibR{
                int width;
                int nrow, ncol;
                int row, col;        // next pixel to send
       +        int pixwid;
        } ZlibR;
        
        typedef struct ZlibW{
       t@@ -68,19 +69,42 @@ zread(void *va, void *buf, int n)
                int ncol = z->ncol;
                uchar *b = buf, *e = b+n, *img;
                int pixels;  // number of pixels in row that can be sent now
       -
       -        while(b+3 <= e){ // loop over image rows
       +        int i, a, pixwid;
       +        
       +        pixwid = z->pixwid;
       +        while(b+pixwid <= e){ // loop over image rows
                        if(z->row >= nrow)
                                break;
                        if(z->col==0)
                                *b++ = FilterNone;
       -                pixels = (e-b)/3;
       +                pixels = (e-b)/pixwid;
                        if(pixels > ncol - z->col)
                                pixels = ncol - z->col;
       -                img = z->data + z->width * z->row + 3 * z->col;
       -
       -                memmove(b, img, 3*pixels);
       -                b += 3*pixels;
       +                img = z->data + z->width * z->row + pixwid * z->col;
       +
       +                memmove(b, img, pixwid*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;
                        if(z->col >= ncol){
       t@@ -119,17 +143,25 @@ zwrite(void *va, void *buf, int n)
        }
        
        static Memimage*
       -memRGB(Memimage *i)
       +memRGBA(Memimage *i)
        {
                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;
        
       -        ni = allocmemimage(i->r, BGR24);
       +        ni = allocmemimage(i->r, dst);
                if(ni == nil)
                        return ni;
                memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
       t@@ -149,7 +181,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
                Tm *tm;
                Memimage *rgb;
        
       -        rgb = memRGB(r);
       +        rgb = memRGBA(r);
                if(rgb == nil)
                        return "allocmemimage nil";
                crctab = mkcrctab(0xedb88320);
       t@@ -163,7 +195,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
                put4(h, ncol); h += 4;
                put4(h, nrow); h += 4;
                *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; // filter method
                *h++ = 0; // interlace method = no interlace
       t@@ -199,6 +231,7 @@ memwritepng(Biobuf *bo, Memimage *r, ImageInfo *II)
                zr.width = rgb->width * sizeof(ulong);
                zr.data = rgb->data->bdata;
                zr.row = zr.col = 0;
       +        zr.pixwid = chantodepth(rgb->chan)/8;
                zw.bo = bo;
                zw.buf = malloc(IDATSIZE);
                zw.b = zw.buf;