summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Campbell <ben@scumways.com>2015-08-20 13:42:50 +1200
committerBen Campbell <ben@scumways.com>2015-08-20 13:42:50 +1200
commitc0e964dec6feec92ffbd7ab475793a86488b5f7e (patch)
tree3cd86554a100945375249d30b299ac37c0b69872
parentadc5d934ec56f9a1bcdf420286de82ec5a5b252e (diff)
downloaddevil-c0e964dec6feec92ffbd7ab475793a86488b5f7e.tar.gz
png: add support for palettes with alpha values
-rw-r--r--DevIL/include/IL/il.h2
-rw-r--r--DevIL/src-IL/src/il_png.c54
2 files changed, 33 insertions, 23 deletions
diff --git a/DevIL/include/IL/il.h b/DevIL/include/IL/il.h
index 540a56eb..d8206cbb 100644
--- a/DevIL/include/IL/il.h
+++ b/DevIL/include/IL/il.h
@@ -374,7 +374,7 @@ typedef long long unsigned int ILuint64;
#define IL_JPG_SAVE_FORMAT 0x0721
#define IL_CHEAD_HEADER_STRING 0x0722
#define IL_PCD_PICNUM 0x0723
-#define IL_PNG_ALPHA_INDEX 0x0724 //XIX : ILint : the color in the palette at this index value (0-255) is considered transparent, -1 for no trasparent color
+#define IL_PNG_ALPHA_INDEX 0x0724 // currently has no effect!
#define IL_JPG_PROGRESSIVE 0x0725
#define IL_VTF_COMP 0x0726
diff --git a/DevIL/src-IL/src/il_png.c b/DevIL/src-IL/src/il_png.c
index 6234ca3a..830c9f9d 100644
--- a/DevIL/src-IL/src/il_png.c
+++ b/DevIL/src-IL/src/il_png.c
@@ -8,10 +8,6 @@
//
// Description: Portable network graphics file (.png) functions
//
-// 20040223 XIX : now may spit out pngs with a transparent index, this is mostly a hack
-// but the proper way of doing it would be to change the pal stuff to think in argb rather than rgb
-// which is something of a bigger job.
-//
//-----------------------------------------------------------------------------
// Most of the comments are left in this file from libpng's excellent example.c
@@ -495,11 +491,6 @@ ILboolean iSavePngInternal()
ILuint BitDepth, i, j;
ILubyte **RowPtr = NULL;
ILimage *Temp = NULL;
- ILpal *TempPal = NULL;
-
-//XIX alpha
- ILubyte transpart[1];
- ILint trans;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
@@ -603,19 +594,40 @@ ILboolean iSavePngInternal()
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
}
+ // set the palette if there is one. REQUIRED for indexed-color images.
if (iCurImage->Format == IL_COLOUR_INDEX) {
- // set the palette if there is one. REQUIRED for indexed-color images.
+ ILpal *TempPal = NULL;
+ ILint palType;
+ ILint numCols;
+
+ numCols = ilGetInteger(IL_PALETTE_NUM_COLS);
+ if(numCols>256) {
+ numCols = 256; // png maximum
+ }
+
TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_RGB24);
- png_set_PLTE(png_ptr, info_ptr, (png_colorp)TempPal->Palette,
- ilGetInteger(IL_PALETTE_NUM_COLS));
-
-//XIX alpha
- trans=iGetInt(IL_PNG_ALPHA_INDEX);
- if ( trans>=0)
- {
- transpart[0]=(ILubyte)trans;
- png_set_tRNS(png_ptr, info_ptr, transpart, 1, 0);
- }
+ png_set_PLTE(png_ptr, info_ptr, (png_colorp)TempPal->Palette, numCols);
+ ilClosePal(TempPal);
+
+ palType = ilGetInteger(IL_PALETTE_TYPE);
+ if( palType==IL_PAL_RGBA32 || palType==IL_PAL_BGRA32 ) {
+ // the palette has transparency, so we need a tRNS chunk.
+ png_byte trans[256]; // png supports up to 256 palette entries
+ int maxTrans = -1;
+ int i;
+ for(i=0; i<numCols; ++i) {
+ ILubyte alpha = iCurImage->Pal.Palette[(4*i) + 3];
+ trans[i] = alpha;
+ if(alpha<255) {
+ // record the highest non-opaque index
+ maxTrans = i;
+ }
+ }
+ // only write tRNS chunk if we've got some non-opaque colours
+ if(maxTrans!=-1) {
+ png_set_tRNS(png_ptr, info_ptr, trans, maxTrans+1, 0);
+ }
+ }
}
/*
@@ -711,7 +723,6 @@ ILboolean iSavePngInternal()
if (Temp != iCurImage)
ilCloseImage(Temp);
- ilClosePal(TempPal);
return IL_TRUE;
@@ -720,7 +731,6 @@ error_label:
ifree(RowPtr);
if (Temp != iCurImage)
ilCloseImage(Temp);
- ilClosePal(TempPal);
return IL_FALSE;
}