shithub: riscv

Download patch

ref: 69daa9fd96668123b751de83df864531a092b0f2
parent: 18169e03de5f44f1dd8fa1e355dd166cab983e50
author: cinap_lenrek <[email protected]>
date: Fri Jul 31 08:58:58 EDT 2015

jpg/ico: support for embedded png icons

--- a/sys/src/cmd/jpg/ico.c
+++ b/sys/src/cmd/jpg/ico.c
@@ -6,6 +6,8 @@
 #include <event.h>
 #include <cursor.h>
 
+#include "imagefile.h"
+
 typedef struct Icon Icon;
 struct Icon
 {
@@ -204,27 +206,63 @@
 	uchar *buf;
 	uchar *map2map;
 	Memimage *img;
+	uchar magic[4];
 	int ncolor;
 	long chan;
 
+	Bseek(b, icon->offset, 0);
+	if(Bread(b, magic, 4) != 4){
+		werrstr("unexpected EOF");
+		return -1;
+	}
+	if(magic[0] == 137 && memcmp(magic+1, "PNG", 3) == 0){
+		Rawimage **png;
+
+		Bseek(b, -4, 1);
+		png = Breadpng(b, CRGB);
+		if(png == nil || png[0] == nil)
+			return -1;
+		switch(png[0]->chandesc){
+		case CY:
+			chan = GREY8;
+			break;
+		case CYA16:
+			chan = CHAN2(CGrey, 8, CAlpha, 8);
+			break;
+		case CRGB24:
+			chan = RGB24;
+			break;
+		case CRGBA32:
+			chan = RGBA32;
+			break;
+		default:
+			werrstr("bad icon png channel descriptor");
+			return -1;
+		}
+		icon->mask = nil;
+		icon->img = allocmemimage(png[0]->r, chan);
+		loadmemimage(icon->img, icon->img->r, png[0]->chans[0], png[0]->chanlen);
+		return 0;
+	}
+
+	if(getl(magic) != 40){
+		werrstr("bad icon bmp header");
+		return -1;
+	}
 	if(icon->len < 40){
-		werrstr("bad icon header length");
+		werrstr("bad icon bmp header length");
 		return -1;
 	}
-	Bseek(b, icon->offset, 0);
 	buf = malloc(icon->len);
 	if(buf == nil)
 		return -1;
-	if(Bread(b, buf, icon->len) != icon->len){
+	memmove(buf, magic, 4);
+	if(Bread(b, buf+4, icon->len-4) != icon->len-4){
 		werrstr("unexpected EOF");
 		return -1;
 	}
-	/* this header's info takes precedence over previous one */
-	if(getl(buf) != 40){
-		werrstr("bad icon header");
-		return -1;
-	}
 
+	/* this header's info takes precedence over previous one */
 	ncolor = 0;
 	icon->w = getl(buf+4);
 	icon->h = getl(buf+8)>>1;
@@ -390,6 +428,9 @@
 	int rv;
 	char file[64];
 	int fd;
+
+	if(icon->mask == nil)
+		return;
 
 	rv = -1;
 	snprint(file, sizeof(file), "%dx%d.mask", icon->w, icon->h);