ref: 23dc7aaa3f6a42dc1b8f4a44f6ffefbe025e2979
dir: /png-trns-unfinished/
png: read mTRS chunks for indexed rgb24 images
FIXME: UNFINISHED, surely breaks with other formats, and code is crap
- then, don't check against apalsize (which should not exist) but
channel/nout/... settings
- implement support for other modes, if we can find test pictures
diff -r 321912cfedf3 sys/src/cmd/jpg/readpng.c
--- a/sys/src/cmd/jpg/readpng.c Sun Jun 25 22:57:47 2017 +0200
+++ b/sys/src/cmd/jpg/readpng.c Mon Jun 26 23:29:03 2017 +0200
@@ -46,6 +46,8 @@
int pass; /* adam7 pass#; 0 means no adam7 */
uchar palette[3*256]; /* color palette */
int palsize; /* number of palette entries */
+ uchar apalette[256]; /* optional alpha values for palette */
+ int hasapal;
};
struct ZlibR
@@ -142,8 +144,18 @@
z->w->palsize = 256;
goto Again;
}
- if(type[0] & PropertyBit)
- goto Again; /* skip auxiliary chunks fornow */
+ if(type[0] & PropertyBit){
+ /* FIXME: non-3 formats are unhandled */
+ if(strcmp(type,"tRNS"))
+ goto Again; /* skip auxiliary chunks fornow */
+ if(z->w->chandesc != CRGBA32 || z->w->nchan != 1)
+ goto Again; /* unimplemented */
+ if(n > z->w->palsize)
+ sysfatal("invalid tRNS chunk len %d", n);
+ memcpy(z->w->apalette, z->p, n);
+ z->w->hasapal = 1;
+ goto Again;
+ }
if(strcmp(type,"IDAT")){
sysfatal("unrecognized mandatory chunk %s", type);
goto Again;
@@ -258,7 +270,7 @@
j >>= 8-z->bpc;
if(j >= z->palsize)
sysfatal("index %d >= palette size %d", j, z->palsize);
- pixel[3] = pixel[1]; /* alpha */
+ pixel[3] = z->hasapal ? z->apalette[j] : pixel[1]; /* alpha */
pixel[0] = z->palette[3*j];
pixel[1] = z->palette[3*j+1];
pixel[2] = z->palette[3*j+2];
@@ -272,6 +284,12 @@
case CRGBA32:
// print("%.2x%.2x%.2x%.2x ", pixel[0], pixel[1], pixel[2], pixel[3]);
*w++ += pixel[3];
+ if(z->hasapal){
+ *w++ = pixel[2];
+ *w++ = pixel[1];
+ *w++ = pixel[0];
+ break;
+ }
*w++ += (pixel[2]*pixel[3])/255;
*w++ += (pixel[1]*pixel[3])/255;
*w++ += (pixel[0]*pixel[3])/255;
@@ -438,9 +456,14 @@
case 3: /* indexed rgb with PLTE */
if(bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8)
sysfatal("invalid indexed rgb bpc %d", bpc);
+ /* FIXME: conditially set CRGBA32? maybe pngmalloc directly to zw buffer, resize it
+ * as needed, and set it before returning? or perhaps alloc maximal size,
+ * and if there's no valid tRNS chunk, shrink it before returning image;
+ * so, alloc max, but use minimal params before inflating... */
+ /* FIXME: support other formats */
image->nchans = 1;
- image->chandesc = CRGB24;
- nout = 3;
+ image->chandesc = CRGBA32;
+ nout = 4;
nchan = 1;
break;
case 4: /* grey+alpha */
@@ -478,6 +501,7 @@
zw.ndata = image->chanlen;
zw.chandesc = image->chandesc;
zw.noutchan = nout;
+ memset(zw.apalette, 0xff, sizeof zw.apalette);
zw.dx = dx;
zw.dy = dy;