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);