[0.1.2-4] PNG supports all image colour modes + tRNS block stuff, but still only 8bpc uninterlaced
This commit is contained in:
parent
d5f0da048d
commit
d258acd647
@ -19,7 +19,7 @@
|
||||
#define VERSION_X 1
|
||||
#define VERSION_Y 2
|
||||
#define VERSION_A 0
|
||||
#define VERSION_Z 3
|
||||
#define VERSION_Z 4
|
||||
// Remember to bump "Z" basically every time you change the engine!
|
||||
// Remember to bump the version in Lua too!
|
||||
// Remember to document API changes in a new version!
|
||||
|
BIN
pkg/base/gfx/loading_default-256c.png
Normal file
BIN
pkg/base/gfx/loading_default-256c.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
@ -135,10 +135,12 @@ end
|
||||
dofile("pkg/base/lib_gui.lua")
|
||||
|
||||
-- 0.1.2-2 introduces PNG support
|
||||
if common.version.num < 4259840+2 then
|
||||
-- 0.1.2-4 introduces support for indexed+greyscale images and tRNS-block (magic colour + palette alpha) transparency
|
||||
-- there's no reason to make them load the full RGB image when they don't support the indexed one.
|
||||
if common.version.num < 4259840+4 then
|
||||
img_loading = img_loading or skin_load("tga", "loading_default-64c.tga", DIR_PKG_GFX)
|
||||
else
|
||||
img_loading = img_loading or skin_load("png", "loading_default.png", DIR_PKG_GFX)
|
||||
img_loading = img_loading or skin_load("png", "loading_default-256c.png", DIR_PKG_GFX)
|
||||
end
|
||||
|
||||
img_map = img_map or common.img_load("*MAPIMG")
|
||||
|
@ -16,9 +16,9 @@
|
||||
]]
|
||||
|
||||
VERSION_ENGINE = {
|
||||
cmp={0,1,2,0,3},
|
||||
num=4259840+3,
|
||||
str="0.1.2-3",
|
||||
cmp={0,1,2,0,4},
|
||||
num=4259840+4,
|
||||
str="0.1.2-4",
|
||||
}
|
||||
|
||||
-- 0.1: 4194304
|
||||
@ -114,7 +114,9 @@ VERSION_BUGS = {
|
||||
{intro=nil, fix=4259840, msg="Sound broken wrt stereo (only the last sound played is in stereo; the rest uses the left for both channels)"},
|
||||
{renderer="softgm", intro=nil, fix=4259840+1, msg="[OSX][softgm] Colours are incorrect (32-bit endian swap)"},
|
||||
{intro=nil, fix=4259840+2, msg="PNG not supported"},
|
||||
{intro=4259840+2, fix=nil, msg="Preliminary PNG support - more support to come when we can be bothered (RGB/RGBA only for now)"},
|
||||
{intro=4259840+2, fix=nil, msg="Preliminary PNG support - more support to come when we can be bothered"},
|
||||
{intro=4259840+2, fix=4259840+4, msg="PNG reader lacks support for greyscale/indexed images"},
|
||||
{intro=4259840+2, fix=4259840+4, msg="PNG reader lacks support for tRNS-block transparency"},
|
||||
{intro=4259840+3, fix=nil, msg="[OpenGL] option to set render quality"},
|
||||
}
|
||||
|
||||
|
98
src/png.c
98
src/png.c
@ -150,9 +150,12 @@ img_t *img_parse_png(int len, const char *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: implement 1,2,4bpc for modes 0 (greyscale) and 3 (indexed)
|
||||
//if(((ihdr.ctyp != 3 && ihdr.ctyp != 0) || (ihdr.bpc != 1 && ihdr.bpc != 2 && ihdr.bpc != 4)) && ihdr.bpc != 8)
|
||||
if(ihdr.bpc != 8)
|
||||
{
|
||||
fprintf(stderr, "img_parse_png: only 8-bits-per-component images currently supported\n");
|
||||
//fprintf(stderr, "img_parse_png: given bits-per-component not supported (16bpc unsupported at the moment)\n");
|
||||
fprintf(stderr, "img_parse_png: given bits-per-component not supported (only 8bpc supported at the moment)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -162,12 +165,6 @@ img_t *img_parse_png(int len, const char *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ihdr.ctyp != 2 && ihdr.ctyp != 6)
|
||||
{
|
||||
fprintf(stderr, "img_parse_png: given colour type not supported yet!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ihdr.cmpr != 0)
|
||||
{
|
||||
fprintf(stderr, "img_parse_png: compression type not supported");
|
||||
@ -186,6 +183,11 @@ img_t *img_parse_png(int len, const char *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t pal[256*3];
|
||||
uint8_t trns[256];
|
||||
int pal_len = 0;
|
||||
int trns_len = 0;
|
||||
|
||||
char *cbuf = NULL;
|
||||
size_t cbuf_len = 0;
|
||||
for(;;)
|
||||
@ -216,6 +218,40 @@ img_t *img_parse_png(int len, const char *data)
|
||||
cbuf_len += clen;
|
||||
} else if(!memcmp("IEND", tag, 4)) {
|
||||
break;
|
||||
} else if(!memcmp("PLTE", tag, 4)) {
|
||||
if(ihdr.ctyp != 3)
|
||||
{
|
||||
// probably best not to spam this stuff.
|
||||
//fprintf(stderr, "img_parse_png: PLTE tag for non-indexed image ignored\n");
|
||||
} else if((clen % 3) != 0 || clen > (3<<ihdr.bpc) || clen > 256*3) {
|
||||
fprintf(stderr, "img_parse_png: invalid PLTE length\n");
|
||||
if(cbuf != NULL)
|
||||
free(cbuf);
|
||||
return NULL;
|
||||
} else {
|
||||
pal_len = clen / 3;
|
||||
memcpy(pal, data+8, clen);
|
||||
}
|
||||
} else if(!memcmp("tRNS", tag, 4)) {
|
||||
// we might as well be better than Internet Explorer
|
||||
int explen = -1;
|
||||
if(ihdr.ctyp == 0)
|
||||
explen = 2;
|
||||
else if(ihdr.ctyp == 2)
|
||||
explen = 6;
|
||||
else if(ihdr.ctyp == 3)
|
||||
explen = pal_len;
|
||||
|
||||
if(explen == -1)
|
||||
{
|
||||
fprintf(stderr, "img_parse_png: warning: tRNS not expected for this image type!\n");
|
||||
} else if((ihdr.ctyp == 3 ? clen > explen : explen != clen)) {
|
||||
fprintf(stderr, "img_parse_png: warning: tRNS chunk length incorrect; ignored\n");
|
||||
} else {
|
||||
memset(trns+clen, 0xFF, 256-clen);
|
||||
memcpy(trns, data+8, clen);
|
||||
trns_len = clen;
|
||||
}
|
||||
} else if(!(tag[0]&0x20)) {
|
||||
fprintf(stderr, "img_parse_png: unexpected compulsory tag %c%c%c%c\n"
|
||||
, tag[0], tag[1], tag[2], tag[3]);
|
||||
@ -384,6 +420,21 @@ img_t *img_parse_png(int len, const char *data)
|
||||
|
||||
switch(ihdr.ctyp)
|
||||
{
|
||||
case 0:
|
||||
// Greyscale
|
||||
for(x = 0; x < iwidth; x++)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[0];
|
||||
dst[2] = src[0];
|
||||
dst[3] = (trns_len == 0
|
||||
|| trns[0] != src[0]
|
||||
? 0xFF : 0x00);
|
||||
src += 1;
|
||||
dst += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// RGB
|
||||
for(x = 0; x < iwidth; x++)
|
||||
@ -391,11 +442,42 @@ img_t *img_parse_png(int len, const char *data)
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
dst[3] = 0xFF; // TODO: tRNS block
|
||||
dst[3] = (trns_len == 0
|
||||
|| trns[0] != src[0]
|
||||
|| trns[2] != src[1]
|
||||
|| trns[4] != src[2]
|
||||
? 0xFF : 0x00);
|
||||
src += 3;
|
||||
dst += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Indexed colour
|
||||
for(x = 0; x < iwidth; x++)
|
||||
{
|
||||
dst[0] = pal[src[0]*3+2];
|
||||
dst[1] = pal[src[0]*3+1];
|
||||
dst[2] = pal[src[0]*3+0];
|
||||
dst[3] = (trns_len == 0 ? 0xFF : trns[src[0]]);
|
||||
src += 1;
|
||||
dst += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Greyscale + Alpha
|
||||
for(x = 0; x < iwidth; x++)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[0];
|
||||
dst[2] = src[0];
|
||||
dst[3] = src[1];
|
||||
src += 2;
|
||||
dst += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// RGBA
|
||||
for(x = 0; x < iwidth; x++)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
export ZIPNAME=nubdist/iceball-indev-0.1.1-9.zip
|
||||
export ZIPNAME=nubdist/iceball-indev-0.1.2-4.zip
|
||||
|
||||
zip -r $ZIPNAME *.dll *.exe *.txt opencmd.bat docs/ \
|
||||
dlcache/info.txt clsave/info.txt \
|
||||
|
Loading…
x
Reference in New Issue
Block a user