[0.1.2-4] PNG supports all image colour modes + tRNS block stuff, but still only 8bpc uninterlaced

This commit is contained in:
Ben Russell (300178622) 2013-08-06 15:56:41 +12:00
parent d5f0da048d
commit d258acd647
6 changed files with 102 additions and 16 deletions

View File

@ -19,7 +19,7 @@
#define VERSION_X 1 #define VERSION_X 1
#define VERSION_Y 2 #define VERSION_Y 2
#define VERSION_A 0 #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 "Z" basically every time you change the engine!
// Remember to bump the version in Lua too! // Remember to bump the version in Lua too!
// Remember to document API changes in a new version! // Remember to document API changes in a new version!

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

View File

@ -135,10 +135,12 @@ end
dofile("pkg/base/lib_gui.lua") dofile("pkg/base/lib_gui.lua")
-- 0.1.2-2 introduces PNG support -- 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) img_loading = img_loading or skin_load("tga", "loading_default-64c.tga", DIR_PKG_GFX)
else 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 end
img_map = img_map or common.img_load("*MAPIMG") img_map = img_map or common.img_load("*MAPIMG")

View File

@ -16,9 +16,9 @@
]] ]]
VERSION_ENGINE = { VERSION_ENGINE = {
cmp={0,1,2,0,3}, cmp={0,1,2,0,4},
num=4259840+3, num=4259840+4,
str="0.1.2-3", str="0.1.2-4",
} }
-- 0.1: 4194304 -- 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)"}, {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)"}, {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=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"}, {intro=4259840+3, fix=nil, msg="[OpenGL] option to set render quality"},
} }

View File

@ -150,9 +150,12 @@ img_t *img_parse_png(int len, const char *data)
return NULL; 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) 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; return NULL;
} }
@ -162,12 +165,6 @@ img_t *img_parse_png(int len, const char *data)
return NULL; 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) if(ihdr.cmpr != 0)
{ {
fprintf(stderr, "img_parse_png: compression type not supported"); 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; return NULL;
} }
uint8_t pal[256*3];
uint8_t trns[256];
int pal_len = 0;
int trns_len = 0;
char *cbuf = NULL; char *cbuf = NULL;
size_t cbuf_len = 0; size_t cbuf_len = 0;
for(;;) for(;;)
@ -216,6 +218,40 @@ img_t *img_parse_png(int len, const char *data)
cbuf_len += clen; cbuf_len += clen;
} else if(!memcmp("IEND", tag, 4)) { } else if(!memcmp("IEND", tag, 4)) {
break; 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)) { } else if(!(tag[0]&0x20)) {
fprintf(stderr, "img_parse_png: unexpected compulsory tag %c%c%c%c\n" fprintf(stderr, "img_parse_png: unexpected compulsory tag %c%c%c%c\n"
, tag[0], tag[1], tag[2], tag[3]); , 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) 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: case 2:
// RGB // RGB
for(x = 0; x < iwidth; x++) 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[0] = src[2];
dst[1] = src[1]; dst[1] = src[1];
dst[2] = src[0]; 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; src += 3;
dst += 4; dst += 4;
} }
break; 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: case 6:
// RGBA // RGBA
for(x = 0; x < iwidth; x++) for(x = 0; x < iwidth; x++)

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/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/ \ zip -r $ZIPNAME *.dll *.exe *.txt opencmd.bat docs/ \
dlcache/info.txt clsave/info.txt \ dlcache/info.txt clsave/info.txt \