Skip to content

Commit

Permalink
png: add support for palettes with alpha values
Browse files Browse the repository at this point in the history
  • Loading branch information
bcampbell committed Aug 20, 2015
1 parent adc5d93 commit c0e964d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 23 deletions.
2 changes: 1 addition & 1 deletion DevIL/include/IL/il.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
54 changes: 32 additions & 22 deletions DevIL/src-IL/src/il_png.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
}

/*
Expand Down Expand Up @@ -711,7 +723,6 @@ ILboolean iSavePngInternal()

if (Temp != iCurImage)
ilCloseImage(Temp);
ilClosePal(TempPal);

return IL_TRUE;

Expand All @@ -720,7 +731,6 @@ ILboolean iSavePngInternal()
ifree(RowPtr);
if (Temp != iCurImage)
ilCloseImage(Temp);
ilClosePal(TempPal);
return IL_FALSE;
}

Expand Down

0 comments on commit c0e964d

Please sign in to comment.