Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2010-05-06 16:37:38 +0400
committerXhmikosR <xhmikosr@users.sourceforge.net>2010-05-06 16:37:38 +0400
commit0be6f0bc5461f0a43f585f6f642aba59aeb7976d (patch)
tree1bc7896b02ef50c3cf440e749946cbfa533fc585
parentdf2c5c3d332fded918da13b33b3530f979e19c4e (diff)
Updated PNGDIB to v3.0.2
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@1853 10f7b99b-c216-0410-bff0-8a66a9350fd8
-rw-r--r--src/apps/mplayerc/ChangeLog1
-rw-r--r--src/apps/mplayerc/pngdib.c2864
-rw-r--r--src/apps/mplayerc/pngdib.h309
3 files changed, 1474 insertions, 1700 deletions
diff --git a/src/apps/mplayerc/ChangeLog b/src/apps/mplayerc/ChangeLog
index 43239202c..67c70e750 100644
--- a/src/apps/mplayerc/ChangeLog
+++ b/src/apps/mplayerc/ChangeLog
@@ -11,6 +11,7 @@ v1.x.x.x - unreleased
CHANGED: Updated zlib to v1.2.5
CHANGED: Updated LibOgg to v1.2.0
CHANGED: Updated LibVorbis to v1.3.1
+ CHANGED: Updated PNGDIB to v3.0.2
FIXED : Name of MPC-HC in title bar (Bug #2826963)
FIXED : crash/hang after standby, hibernate, UAC or CTRL+ALT+DEL (ticket #12)
diff --git a/src/apps/mplayerc/pngdib.c b/src/apps/mplayerc/pngdib.c
index 18e7e1c0b..75eb5094f 100644
--- a/src/apps/mplayerc/pngdib.c
+++ b/src/apps/mplayerc/pngdib.c
@@ -12,14 +12,14 @@
#include <malloc.h>
#include <math.h>
-#include "../../libpng/png.h"
+#include <png.h>
#define PNGDIB_INTERNALS
#include "pngdib.h"
+#include <strsafe.h>
-
-#define PNGDIB_SRC_VERSION 30001
-#define PNGDIB_SRC_VERSION_STRING _T("3.0.1")
+#define PNGDIB_SRC_VERSION 30002
+#define PNGDIB_SRC_VERSION_STRING _T("3.0.2")
#if PNGDIB_SRC_VERSION != PNGDIB_HEADER_VERSION
@@ -37,159 +37,130 @@
// This is basically a Windows-only utility with a simple-as-possible
-// interface, so I'm not too concerned about allowing a
+// interface, so I'm not too concerned about allowing a
// user-configurable screen gamma.
//static const double screen_gamma = 2.2;
-#define MAX_ERRMSGLEN 100
-
-struct errstruct
-{
- jmp_buf *jbufp;
- TCHAR *errmsg;
+struct errstruct {
+ jmp_buf *jbufp;
+ TCHAR *errmsg;
};
-static void pngd_get_error_message(int rv,TCHAR *e)
+static void pngd_get_error_message(int rv,TCHAR *e, int e_len)
{
- switch(rv)
- {
- case PNGD_E_ERROR:
- lstrcpy(e,_T("Unknown error"));
- break;
- case PNGD_E_VERSION:
- lstrcpy(e,_T("Incompatible library version"));
- break;
- case PNGD_E_NOMEM:
- lstrcpy(e,_T("Unable to allocate memory"));
- break;
- case PNGD_E_UNSUPP:
- lstrcpy(e,_T("Invalid or unsupported image"));
- break;
- case PNGD_E_LIBPNG:
- lstrcpy(e,_T("libpng reported an error"));
- break;
- case PNGD_E_BADBMP:
- lstrcpy(e,_T("Invalid BMP image"));
- break;
- case PNGD_E_BADPNG:
- lstrcpy(e,_T("Invalid PNG image"));
- break;
- case PNGD_E_READ:
- lstrcpy(e,_T("Unable to read file"));
- break;
- case PNGD_E_WRITE:
- lstrcpy(e,_T("Unable to write file"));
- break;
- }
+ switch(rv) {
+ case PNGD_E_ERROR: StringCchCopy(e,e_len,_T("Unknown error")); break;
+ case PNGD_E_VERSION: StringCchCopy(e,e_len,_T("Incompatible library version")); break;
+ case PNGD_E_NOMEM: StringCchCopy(e,e_len,_T("Unable to allocate memory")); break;
+ case PNGD_E_UNSUPP: StringCchCopy(e,e_len,_T("Invalid or unsupported image")); break;
+ case PNGD_E_LIBPNG: StringCchCopy(e,e_len,_T("libpng reported an error")); break;
+ case PNGD_E_BADBMP: StringCchCopy(e,e_len,_T("Invalid BMP image")); break;
+ case PNGD_E_BADPNG: StringCchCopy(e,e_len,_T("Invalid PNG image")); break;
+ case PNGD_E_READ: StringCchCopy(e,e_len,_T("Unable to read file")); break;
+ case PNGD_E_WRITE: StringCchCopy(e,e_len,_T("Unable to write file")); break;
+ }
}
static unsigned char* uncompress_dib(LPBITMAPINFO lpbmi1, int infosize, void *lpbits1)
{
- LPBITMAPINFOHEADER lpdib2;
- unsigned char *lpbits2;
- void *whatever;
- int linesize, bitssize;
- HBITMAP hb;
- HDC hdc;
- HGDIOBJ rvgdi;
- int rvi;
- int width,height;
- LPBITMAPINFOHEADER lpdib1;
-
- lpdib1=(LPBITMAPINFOHEADER)lpbmi1;
- width=lpdib1->biWidth;
- height=lpdib1->biHeight;
-
- linesize= (((width * lpdib1->biBitCount)+31)/32)*4;
- bitssize= linesize*height;
-
- lpdib2= (LPBITMAPINFOHEADER)malloc(infosize);
- if(!lpdib2) return NULL;
-
- // create a header for the new uncompressed DIB
- CopyMemory((void*)lpdib2,(void*)lpdib1,infosize);
- lpdib2->biCompression=BI_RGB;
- lpdib2->biSizeImage=0;
-
- lpbits2= (unsigned char*)malloc(bitssize);
- if(!lpbits2)
- {
- free((void*)lpdib2);
- return NULL;
- }
-
-
- // Windows bitmap handling functions are not exactly convenient,
- // especially when trying to deal with DIBs. Every function wants
- // to convert them into DDBs. We have to play stupid games and
- // convert back and forth. This probably uses too much memory,
- // and I'm not 100% sure it is exactly correct, but it seems to
- // work for me.
-
- hb=CreateDIBSection(NULL,(LPBITMAPINFO)lpdib2,DIB_RGB_COLORS,&whatever,NULL,0);
-
- hdc=CreateCompatibleDC(NULL);
- rvgdi=SelectObject(hdc,hb);
- //SetStretchBltMode(hdc,COLORONCOLOR);
- rvi=StretchDIBits(hdc,
- 0,0,width,height,
- 0,0,width,height,
- lpbits1, (LPBITMAPINFO)lpdib1,
- DIB_RGB_COLORS,SRCCOPY);
- rvi=GetDIBits(hdc,hb,0,height, (LPVOID)lpbits2,
- (LPBITMAPINFO)lpdib2,DIB_RGB_COLORS);
-
- DeleteDC(hdc);
- DeleteObject(hb);
- free((void*)lpdib2);
-
- return lpbits2;
+ LPBITMAPINFOHEADER lpdib2;
+ unsigned char *lpbits2;
+ void *whatever;
+ int linesize, bitssize;
+ HBITMAP hb;
+ HDC hdc;
+ HGDIOBJ rvgdi;
+ int rvi;
+ int width,height;
+ LPBITMAPINFOHEADER lpdib1;
+
+ lpdib1=(LPBITMAPINFOHEADER)lpbmi1;
+ width=lpdib1->biWidth;
+ height=lpdib1->biHeight;
+
+ linesize= (((width * lpdib1->biBitCount)+31)/32)*4;
+ bitssize= linesize*height;
+
+ lpdib2= (LPBITMAPINFOHEADER)malloc(infosize);
+ if(!lpdib2) return NULL;
+
+ // create a header for the new uncompressed DIB
+ CopyMemory((void*)lpdib2,(void*)lpdib1,infosize);
+ lpdib2->biCompression=BI_RGB;
+ lpdib2->biSizeImage=0;
+
+ lpbits2= (unsigned char*)malloc(bitssize);
+ if(!lpbits2) { free((void*)lpdib2); return NULL; }
+
+
+ // Windows bitmap handling functions are not exactly convenient,
+ // especially when trying to deal with DIBs. Every function wants
+ // to convert them into DDBs. We have to play stupid games and
+ // convert back and forth. This probably uses too much memory,
+ // and I'm not 100% sure it is exactly correct, but it seems to
+ // work for me.
+
+ hb=CreateDIBSection(NULL,(LPBITMAPINFO)lpdib2,DIB_RGB_COLORS,&whatever,NULL,0);
+
+ hdc=CreateCompatibleDC(NULL);
+ rvgdi=SelectObject(hdc,hb);
+ //SetStretchBltMode(hdc,COLORONCOLOR);
+ rvi=StretchDIBits(hdc,
+ 0,0,width,height,
+ 0,0,width,height,
+ lpbits1, (LPBITMAPINFO)lpdib1,
+ DIB_RGB_COLORS,SRCCOPY);
+ rvi=GetDIBits(hdc,hb,0,height, (LPVOID)lpbits2,
+ (LPBITMAPINFO)lpdib2,DIB_RGB_COLORS);
+
+ DeleteDC(hdc);
+ DeleteObject(hb);
+ free((void*)lpdib2);
+
+ return lpbits2;
}
static void my_png_error_fn(png_structp png_ptr, const char *err_msg)
{
- struct errstruct *errinfop;
- jmp_buf *j;
+ struct errstruct *errinfop;
+ jmp_buf *j;
- errinfop = (struct errstruct *)png_get_error_ptr(png_ptr);
- j = errinfop->jbufp;
+ errinfop = (struct errstruct *)png_get_error_ptr(png_ptr);
+ j = errinfop->jbufp;
#ifdef _UNICODE
- _snwprintf(errinfop->errmsg,MAX_ERRMSGLEN,_T("[libpng] %S"),err_msg);
+ StringCchPrintf(errinfop->errmsg,PNGDIB_ERRMSG_MAX,_T("[libpng] %S"),err_msg);
#else
- _snprintf(errinfop->errmsg,MAX_ERRMSGLEN,"[libpng] %s",err_msg);
+ StringCchPrintf(errinfop->errmsg,PNGDIB_ERRMSG_MAX,"[libpng] %s",err_msg);
#endif
- errinfop->errmsg[MAX_ERRMSGLEN-1]='\0';
- longjmp(*j, -1);
+ longjmp(*j, -1);
}
static void my_png_warning_fn(png_structp png_ptr, const char *warn_msg)
{
- return;
+ return;
}
// A callback function used when reading memory-mapped PNG files.
static void my_png_read_fn(png_structp png_ptr,
- png_bytep data, png_size_t length)
+ png_bytep data, png_size_t length)
{
- struct p2d_struct *p2d;
+ struct p2d_struct *p2d;
- p2d = (struct p2d_struct*)png_get_io_ptr(png_ptr);
+ p2d = (struct p2d_struct*)png_get_io_ptr(png_ptr);
- if(p2d->input_memblk_size>0)
- {
- if((int)length > (p2d->input_memblk_size - p2d->input_memblk_curpos))
- {
- png_error(png_ptr, "read error: unexpected end of file");
- return;
- }
- }
+ if(p2d->input_memblk_size>0) {
+ if((int)length > (p2d->input_memblk_size - p2d->input_memblk_curpos)) {
+ png_error(png_ptr, "read error: unexpected end of file");
+ return;
+ }
+ }
- CopyMemory((void*)data,(void*)&p2d->input_memblk[p2d->input_memblk_curpos],length);
- p2d->input_memblk_curpos+=length;
+ CopyMemory((void*)data,(void*)&p2d->input_memblk[p2d->input_memblk_curpos],length);
+ p2d->input_memblk_curpos+=length;
}
@@ -197,1455 +168,1274 @@ static void my_png_read_fn(png_structp png_ptr,
// I'd prefer to have libpng do all gamma correction itself,
// but I can't figure out how to do that efficiently.
static void gamma_correct(double screen_gamma,double file_gamma,
- unsigned char *red, unsigned char *green, unsigned char *blue)
+ unsigned char *red, unsigned char *green, unsigned char *blue)
{
- double g;
+ double g;
#ifndef PNG_GAMMA_THRESHOLD
# define PNG_GAMMA_THRESHOLD 0.05
#endif
- if(fabs(screen_gamma*file_gamma-1.0)<=PNG_GAMMA_THRESHOLD) return;
+ if(fabs(screen_gamma*file_gamma-1.0)<=PNG_GAMMA_THRESHOLD) return;
- if (screen_gamma>0.000001)
- g=1.0/(file_gamma*screen_gamma);
- else
- g=1.0;
+ if (screen_gamma>0.000001)
+ g=1.0/(file_gamma*screen_gamma);
+ else
+ g=1.0;
- (*red) = (unsigned char)(pow((double)(*red )/255.0,g)*255.0+0.5);
- (*green) = (unsigned char)(pow((double)(*green)/255.0,g)*255.0+0.5);
- (*blue) = (unsigned char)(pow((double)(*blue )/255.0,g)*255.0+0.5);
+ (*red) = (unsigned char)(pow((double)(*red )/255.0,g)*255.0+0.5);
+ (*green) = (unsigned char)(pow((double)(*green)/255.0,g)*255.0+0.5);
+ (*blue) = (unsigned char)(pow((double)(*blue )/255.0,g)*255.0+0.5);
}
int PNGDIB_DECL pngdib_p2d_run(PNGDIB *qq)
{
- struct p2d_struct *p2d;
-
- png_structp png_ptr;
- png_infop info_ptr;
- jmp_buf jbuf;
- struct errstruct errinfo;
- png_uint_32 width, height;
- int png_bit_depth, color_type, interlace_type;
- png_colorp png_palette;
- png_uint_32 res_x, res_y;
- int has_phys, has_gama;
- int res_unit_type;
- FILE *fp;
- int palette_entries;
- unsigned char **row_pointers;
- unsigned char *lpdib;
- unsigned char *dib_palette;
- unsigned char *dib_bits;
- unsigned char *tmprow;
- int dib_bpp, dib_bytesperrow;
- int i,j;
- int rv;
- png_color_16 bkgd; // used with png_set_background
- int has_trns, trns_color;
- int has_bkgd; // ==1 if there a bkgd chunk, and USE_BKGD flag
- png_color_16p temp_colorp;
- png_color_16p bg_colorp; // background color (if has_bkgd)
- png_bytep trns_trans;
- int manual_trns;
- int manual_gamma;
- struct PNGD_COLOR_struct bkgd_color;
- int is_grayscale,has_alpha_channel;
- double file_gamma;
- int dib_alpha32;
- int write_bitfields;
-
- p2d=(struct p2d_struct*)qq;
-
- dib_alpha32=0;
- write_bitfields=0;
-
-
- manual_trns=0;
- has_trns=has_bkgd=0;
- rv=PNGD_E_ERROR;
- png_ptr=NULL;
- info_ptr=NULL;
- fp=NULL;
- row_pointers=NULL;
- lpdib=NULL;
-
- lstrcpy(p2d->common.errmsg,_T(""));
-
- if(p2d->use_custom_bg_flag)
- {
- bkgd_color.red= p2d->bgcolor.red;
- bkgd_color.green= p2d->bgcolor.green;
- bkgd_color.blue= p2d->bgcolor.blue;
- }
- else
- {
- bkgd_color.red= 255; // Should never get used. If the
- bkgd_color.green= 128; // background turns orange, it's a bug.
- bkgd_color.blue= 0;
- }
-
- // Set the user-defined pointer to point to our jmp_buf. This will
- // hopefully protect against potentially different sized jmp_buf's in
- // libpng, while still allowing this library to be threadsafe.
- errinfo.jbufp = &jbuf;
- errinfo.errmsg = p2d->common.errmsg;
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,(void*)(&errinfo),
- my_png_error_fn, my_png_warning_fn);
- if(!png_ptr)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
-
- info_ptr = png_create_info_struct(png_ptr);
- if(!info_ptr)
- {
- //png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
- if(setjmp(jbuf))
- {
- // we'll get here if an error occurred in any of the following
- // png_ functions
-
- rv=PNGD_E_LIBPNG;
- goto abort;
- }
-
- if(p2d->input_method==0)
- {
- // reading from a filename
- if(!p2d->input_filename)
- {
- wsprintf(p2d->common.errmsg,_T("Input filename not set"));
- rv=PNGD_E_ERROR;
- goto abort;
- }
-
- if((fp = _tfopen(p2d->input_filename,_T("rb"))) == NULL)
- {
- rv=PNGD_E_READ;
- goto abort;
- }
- png_init_io(png_ptr, fp);
- }
- else if(p2d->input_method==1)
- {
- // reading from a memory block
- p2d->input_memblk_curpos=0;
- png_set_read_fn(png_ptr, (void*)p2d, my_png_read_fn);
- }
- else
- {
- goto abort;
- }
-
- png_read_info(png_ptr, info_ptr);
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &png_bit_depth, &color_type,
- &interlace_type, NULL, NULL);
-
- p2d->color_type=color_type;
- p2d->bits_per_sample=png_bit_depth;
- p2d->interlace=interlace_type;
- switch(color_type)
- {
- case PNG_COLOR_TYPE_RGB:
- p2d->bits_per_pixel=png_bit_depth*3;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- p2d->bits_per_pixel=png_bit_depth*4;
- break;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- p2d->bits_per_pixel=png_bit_depth*2;
- break;
- default:
- p2d->bits_per_pixel=png_bit_depth;
- }
-
- is_grayscale = !(color_type&PNG_COLOR_MASK_COLOR);
- has_alpha_channel = (color_type&PNG_COLOR_MASK_ALPHA)?1:0;
-
- has_trns = png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS);
-
- if(p2d->common.dib_alpha32 && (has_trns || has_alpha_channel))
- {
- // Fixme - if trns(for palette) has no transparent entries,
- // we could skip this.
- dib_alpha32=1;
- write_bitfields=1;
-
- if (!(color_type&PNG_COLOR_MASK_COLOR))
- {
- png_set_gray_to_rgb(png_ptr);
- }
- else if(color_type==PNG_COLOR_TYPE_PALETTE)
- {
- png_set_palette_to_rgb(png_ptr);
- }
-
- if (has_trns) png_set_tRNS_to_alpha(png_ptr);
-
- goto notrans;
- }
-
- // look for bKGD chunk, and process if applicable
- if(p2d->use_file_bg_flag)
- {
- if(png_get_bKGD(png_ptr, info_ptr, &bg_colorp))
- {
- // process the background, store 8-bit RGB in bkgd_color
- has_bkgd=1;
-
- if(is_grayscale && png_bit_depth<8)
- {
- bkgd_color.red =
- bkgd_color.green=
- bkgd_color.blue =
- (unsigned char) ( (bg_colorp->gray*255)/( (1<<png_bit_depth)-1 ) );
- }
- else if(png_bit_depth<=8)
- {
- bkgd_color.red=(unsigned char)(bg_colorp->red);
- bkgd_color.green=(unsigned char)(bg_colorp->green);
- bkgd_color.blue =(unsigned char)(bg_colorp->blue);
- }
- else
- {
- bkgd_color.red=(unsigned char)(bg_colorp->red>>8);
- bkgd_color.green=(unsigned char)(bg_colorp->green>>8);
- bkgd_color.blue =(unsigned char)(bg_colorp->blue>>8);
- }
- }
- }
-
- if( !(color_type & PNG_COLOR_MASK_ALPHA) && !has_trns)
- {
- // If no transparency, we can skip this whole background-color mess.
- goto notrans;
- }
-
- if(has_bkgd && (png_bit_depth>8 || !is_grayscale || has_alpha_channel))
- {
- png_set_background(png_ptr, bg_colorp,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- }
- else if(is_grayscale && has_trns && png_bit_depth<=8
- && (has_bkgd || (p2d->use_custom_bg_flag)) )
- {
- // grayscale binarytrans,<=8bpp: transparency is handle manually
- // by modifying a palette entry (later)
- png_get_tRNS(png_ptr,info_ptr,&trns_trans, &i, &temp_colorp);
- if(i>=1)
- {
- trns_color= temp_colorp->gray; // corresponds to a palette entry
- manual_trns=1;
- }
- }
- else if(!has_bkgd && (has_trns || has_alpha_channel) &&
- (p2d->use_custom_bg_flag) )
- {
- // process most CUSTOM background colors
- bkgd.index = 0; // unused
- bkgd.red = p2d->bgcolor.red;
- bkgd.green = p2d->bgcolor.green;
- bkgd.blue = p2d->bgcolor.blue;
-
- // libpng may use bkgd.gray if bkgd.red==bkgd.green==bkgd.blue.
- // Not sure if that's a libpng bug or not.
- bkgd.gray = p2d->bgcolor.red;
-
- if(png_bit_depth>8)
- {
- bkgd.red = (bkgd.red <<8)|bkgd.red;
- bkgd.green= (bkgd.green<<8)|bkgd.green;
- bkgd.blue = (bkgd.blue <<8)|bkgd.blue;
- bkgd.gray = (bkgd.gray <<8)|bkgd.gray;
- }
-
- if(is_grayscale)
- {
- /* assert(png_bit_depth>8); */
-
- /* Need to expand to full RGB if unless background is pure gray */
- if(bkgd.red!=bkgd.green || bkgd.red!=bkgd.blue)
- {
- png_set_gray_to_rgb(png_ptr);
-
- // png_set_tRNS_to_alpha() is called here because otherwise
- // binary transparency for 16-bps grayscale images doesn't
- // work. Libpng will think black pixels are transparent.
- // I don't know exactly why it works. It does *not* add an
- // alpha channel, as you might think (adding an alpha
- // channnel makes no sense if you are using
- // png_set_background).
- //
- // Here's an alternate hack that also seems to work, but
- // uses direct structure access:
- //
- // png_ptr->trans_values.red =
- // png_ptr->trans_values.green =
- // png_ptr->trans_values.blue = png_ptr->trans_values.gray;
- if(has_trns)
- png_set_tRNS_to_alpha(png_ptr);
-
- png_set_background(png_ptr, &bkgd,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-
- }
- else // gray custom background
- {
- png_set_background(png_ptr, &bkgd,
- PNG_BACKGROUND_GAMMA_SCREEN, 1, 1.0);
- }
-
- }
- else
- {
- png_set_background(png_ptr, &bkgd,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
- }
- }
+ struct p2d_struct *p2d;
+
+ png_structp png_ptr;
+ png_infop info_ptr;
+ jmp_buf jbuf;
+ struct errstruct errinfo;
+ png_uint_32 width, height;
+ int png_bit_depth, color_type, interlace_type;
+ png_colorp png_palette;
+ png_uint_32 res_x, res_y;
+ int has_phys, has_gama;
+ int res_unit_type;
+ FILE *fp;
+ int palette_entries;
+ unsigned char **row_pointers;
+ unsigned char *lpdib;
+ unsigned char *dib_palette;
+ unsigned char *dib_bits;
+ unsigned char *tmprow;
+ int dib_bpp, dib_bytesperrow;
+ int i,j;
+ int rv;
+ png_color_16 bkgd; // used with png_set_background
+ int has_trns, trns_color;
+ int has_bkgd; // ==1 if there a bkgd chunk, and USE_BKGD flag
+ png_color_16p temp_colorp;
+ png_color_16p bg_colorp; // background color (if has_bkgd)
+ png_bytep trns_trans;
+ int manual_trns;
+ int manual_gamma;
+ struct PNGD_COLOR_struct bkgd_color;
+ int is_grayscale,has_alpha_channel;
+ double file_gamma;
+ int dib_alpha32;
+ int write_bitfields;
+
+ p2d=(struct p2d_struct*)qq;
+
+ dib_alpha32=0;
+ write_bitfields=0;
+
+
+ manual_trns=0;
+ has_trns=has_bkgd=0;
+ rv=PNGD_E_ERROR;
+ png_ptr=NULL;
+ info_ptr=NULL;
+ fp=NULL;
+ row_pointers=NULL;
+ lpdib=NULL;
+
+ StringCchCopy(p2d->common.errmsg,PNGDIB_ERRMSG_MAX,_T(""));
+
+ if(p2d->use_custom_bg_flag) {
+ bkgd_color.red= p2d->bgcolor.red;
+ bkgd_color.green= p2d->bgcolor.green;
+ bkgd_color.blue= p2d->bgcolor.blue;
+ }
+ else {
+ bkgd_color.red= 255; // Should never get used. If the
+ bkgd_color.green= 128; // background turns orange, it's a bug.
+ bkgd_color.blue= 0;
+ }
+
+ // Set the user-defined pointer to point to our jmp_buf. This will
+ // hopefully protect against potentially different sized jmp_buf's in
+ // libpng, while still allowing this library to be threadsafe.
+ errinfo.jbufp = &jbuf;
+ errinfo.errmsg = p2d->common.errmsg;
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,(void*)(&errinfo),
+ my_png_error_fn, my_png_warning_fn);
+ if(!png_ptr) { rv=PNGD_E_NOMEM; goto abort; }
+
+ if(p2d->common.pngptrhook_function) {
+ (*(p2d->common.pngptrhook_function))(p2d->common.userdata,(void*)png_ptr);
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if(!info_ptr) {
+ //png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ rv=PNGD_E_NOMEM; goto abort;
+ }
+
+ if(setjmp(jbuf)) {
+ // we'll get here if an error occurred in any of the following
+ // png_ functions
+
+ rv=PNGD_E_LIBPNG;
+ goto abort;
+ }
+
+ if(p2d->input_method==0) {
+ // reading from a filename
+ if(!p2d->input_filename) {
+ StringCchPrintf(p2d->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Input filename not set"));
+ rv=PNGD_E_ERROR; goto abort;
+ }
+
+ if((fp = _tfopen(p2d->input_filename,_T("rb"))) == NULL) {
+ rv=PNGD_E_READ;
+ goto abort;
+ }
+ png_init_io(png_ptr, fp);
+ }
+ else if(p2d->input_method==1) {
+ // reading from a memory block
+ p2d->input_memblk_curpos=0;
+ png_set_read_fn(png_ptr, (void*)p2d, my_png_read_fn);
+ }
+ else { goto abort; }
+
+ png_read_info(png_ptr, info_ptr);
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &png_bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
+
+ p2d->color_type=color_type;
+ p2d->bits_per_sample=png_bit_depth;
+ p2d->interlace=interlace_type;
+ switch(color_type) {
+ case PNG_COLOR_TYPE_RGB: p2d->bits_per_pixel=png_bit_depth*3; break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: p2d->bits_per_pixel=png_bit_depth*4; break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: p2d->bits_per_pixel=png_bit_depth*2; break;
+ default: p2d->bits_per_pixel=png_bit_depth;
+ }
+
+ is_grayscale = !(color_type&PNG_COLOR_MASK_COLOR);
+ has_alpha_channel = (color_type&PNG_COLOR_MASK_ALPHA)?1:0;
+
+ has_trns = png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS);
+
+ if(p2d->common.dib_alpha32 && (has_trns || has_alpha_channel)) {
+ // Fixme - if trns(for palette) has no transparent entries,
+ // we could skip this.
+ dib_alpha32=1;
+ write_bitfields=1;
+
+ if (!(color_type&PNG_COLOR_MASK_COLOR)) {
+ png_set_gray_to_rgb(png_ptr);
+ }
+ else if(color_type==PNG_COLOR_TYPE_PALETTE) {
+ png_set_palette_to_rgb(png_ptr);
+ }
+
+ if (has_trns) png_set_tRNS_to_alpha(png_ptr);
+
+ goto notrans;
+ }
+
+ // look for bKGD chunk, and process if applicable
+ if(p2d->use_file_bg_flag) {
+ if(png_get_bKGD(png_ptr, info_ptr, &bg_colorp)) {
+ // process the background, store 8-bit RGB in bkgd_color
+ has_bkgd=1;
+
+ if(is_grayscale && png_bit_depth<8) {
+ bkgd_color.red =
+ bkgd_color.green=
+ bkgd_color.blue =
+ (unsigned char) ( (bg_colorp->gray*255)/( (1<<png_bit_depth)-1 ) );
+ }
+ else if(png_bit_depth<=8) {
+ bkgd_color.red=(unsigned char)(bg_colorp->red);
+ bkgd_color.green=(unsigned char)(bg_colorp->green);
+ bkgd_color.blue =(unsigned char)(bg_colorp->blue);
+ }
+ else {
+ bkgd_color.red=(unsigned char)(bg_colorp->red>>8);
+ bkgd_color.green=(unsigned char)(bg_colorp->green>>8);
+ bkgd_color.blue =(unsigned char)(bg_colorp->blue>>8);
+ }
+ }
+ }
+
+ if( !(color_type & PNG_COLOR_MASK_ALPHA) && !has_trns) {
+ // If no transparency, we can skip this whole background-color mess.
+ goto notrans;
+ }
+
+ if(has_bkgd && (png_bit_depth>8 || !is_grayscale || has_alpha_channel)) {
+ png_set_background(png_ptr, bg_colorp,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ }
+ else if(is_grayscale && has_trns && png_bit_depth<=8
+ && (has_bkgd || (p2d->use_custom_bg_flag)) )
+ {
+ // grayscale binarytrans,<=8bpp: transparency is handle manually
+ // by modifying a palette entry (later)
+ png_get_tRNS(png_ptr,info_ptr,&trns_trans, &i, &temp_colorp);
+ if(i>=1) {
+ trns_color= temp_colorp->gray; // corresponds to a palette entry
+ manual_trns=1;
+ }
+ }
+ else if(!has_bkgd && (has_trns || has_alpha_channel) &&
+ (p2d->use_custom_bg_flag) )
+ { // process most CUSTOM background colors
+ bkgd.index = 0; // unused
+ bkgd.red = p2d->bgcolor.red;
+ bkgd.green = p2d->bgcolor.green;
+ bkgd.blue = p2d->bgcolor.blue;
+
+ // libpng may use bkgd.gray if bkgd.red==bkgd.green==bkgd.blue.
+ // Not sure if that's a libpng bug or not.
+ bkgd.gray = p2d->bgcolor.red;
+
+ if(png_bit_depth>8) {
+ bkgd.red = (bkgd.red <<8)|bkgd.red;
+ bkgd.green= (bkgd.green<<8)|bkgd.green;
+ bkgd.blue = (bkgd.blue <<8)|bkgd.blue;
+ bkgd.gray = (bkgd.gray <<8)|bkgd.gray;
+ }
+
+ if(is_grayscale) {
+ /* assert(png_bit_depth>8); */
+
+ /* Need to expand to full RGB if unless background is pure gray */
+ if(bkgd.red!=bkgd.green || bkgd.red!=bkgd.blue) {
+ png_set_gray_to_rgb(png_ptr);
+
+ // png_set_tRNS_to_alpha() is called here because otherwise
+ // binary transparency for 16-bps grayscale images doesn't
+ // work. Libpng will think black pixels are transparent.
+ // I don't know exactly why it works. It does *not* add an
+ // alpha channel, as you might think (adding an alpha
+ // channnel makes no sense if you are using
+ // png_set_background).
+ //
+ // Here's an alternate hack that also seems to work, but
+ // uses direct structure access:
+ //
+ // png_ptr->trans_values.red =
+ // png_ptr->trans_values.green =
+ // png_ptr->trans_values.blue = png_ptr->trans_values.gray;
+ if(has_trns)
+ png_set_tRNS_to_alpha(png_ptr);
+
+ png_set_background(png_ptr, &bkgd,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ }
+ else { // gray custom background
+ png_set_background(png_ptr, &bkgd,
+ PNG_BACKGROUND_GAMMA_SCREEN, 1, 1.0);
+ }
+
+ }
+ else {
+ png_set_background(png_ptr, &bkgd,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ }
+ }
notrans:
- // If we don't have any background color at all that we can use,
- // strip the alpha channel.
- if(!dib_alpha32 && has_alpha_channel && !has_bkgd &&
- !(p2d->use_custom_bg_flag) )
- {
- png_set_strip_alpha(png_ptr);
- }
-
- if(png_bit_depth>8)
- png_set_strip_16(png_ptr);
-
- if (png_get_sRGB(png_ptr, info_ptr, &i))
- {
- has_gama=1;
- file_gamma = 0.45455;
- }
- else if(png_get_gAMA(png_ptr, info_ptr, &file_gamma))
- {
- has_gama=1;
- }
- else
- {
- has_gama=0;
- file_gamma = 0.45455;
- }
-
- if(/*imginfo && */ has_gama)
- {
- p2d->file_gamma=file_gamma;
- p2d->gamma_returned=1;
- }
-
- manual_gamma=0;
- if(p2d->gamma_correction)
- {
-
- if(!is_grayscale || png_bit_depth>8 || has_alpha_channel)
- {
- png_set_gamma(png_ptr, p2d->screen_gamma, file_gamma);
- //png_ptr->transformations |= 0x2000; // hack for old libpng versions
- }
- else manual_gamma=1;
-
- if(has_bkgd)
- {
- // Gamma correct the background color (if we got it from the file)
- // before returning it to the app.
- gamma_correct(p2d->screen_gamma,file_gamma,&bkgd_color.red,&bkgd_color.green,&bkgd_color.blue);
- }
- }
-
- png_read_update_info(png_ptr, info_ptr);
-
- // color type may have changed, due to our transformations
- color_type = png_get_color_type(png_ptr,info_ptr);
-
-
- switch(color_type)
- {
- case PNG_COLOR_TYPE_RGB_ALPHA:
- assert(dib_alpha32);
- dib_bpp= 32;
- palette_entries=0;
- png_set_bgr(png_ptr);
- break;
- case PNG_COLOR_TYPE_RGB:
- dib_bpp= 24;
- palette_entries=0;
- png_set_bgr(png_ptr);
- break;
- case PNG_COLOR_TYPE_PALETTE:
- dib_bpp=png_bit_depth;
- png_get_PLTE(png_ptr,info_ptr,&png_palette,&palette_entries);
- break;
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- dib_bpp=png_bit_depth;
- if(png_bit_depth>8) dib_bpp=8;
- palette_entries= 1<<dib_bpp;
- // we'll construct a grayscale palette later
- break;
- default:
- rv=PNGD_E_BADPNG;
- goto abort;
- }
-
- if(dib_bpp==2) dib_bpp=4;
-
- has_phys=png_get_valid(png_ptr,info_ptr,PNG_INFO_pHYs);
- if(has_phys)
- {
- png_get_pHYs(png_ptr,info_ptr,&res_x,&res_y,&res_unit_type);
- if(res_x>0 && res_y>0)
- {
- p2d->res_x=res_x;
- p2d->res_y=res_y;
- p2d->res_units=res_unit_type;
- p2d->res_valid=1;
- }
- }
-
- // DIB scanlines are padded to 4-byte boundaries.
- dib_bytesperrow= (((width * dib_bpp)+31)/32)*4;
-
- p2d->bitssize = height*dib_bytesperrow;
-
- p2d->dibsize=sizeof(BITMAPINFOHEADER) + 4*palette_entries +
- (write_bitfields?12:0) + p2d->bitssize;
-
- if(p2d->common.malloc_function)
- {
- lpdib = (unsigned char*)(*(p2d->common.malloc_function))(p2d->common.userdata,p2d->dibsize);
- }
- else
- {
- lpdib = (unsigned char*)calloc(p2d->dibsize,1);
- }
-
-
- if(!lpdib)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
- p2d->pdib = (LPBITMAPINFOHEADER)lpdib;
-
- row_pointers=(unsigned char**)malloc(height*sizeof(unsigned char*));
- if(!row_pointers)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
- // there is some redundancy here...
- p2d->palette_offs=sizeof(BITMAPINFOHEADER);
- p2d->bits_offs =sizeof(BITMAPINFOHEADER) + 4*palette_entries + (write_bitfields?12:0);
- dib_palette= &lpdib[p2d->palette_offs];
- p2d->palette= (RGBQUAD*)dib_palette;
- dib_bits = &lpdib[p2d->bits_offs];
- p2d->pbits = (VOID*)dib_bits;
- p2d->palette_colors = palette_entries;
-
- // set up the DIB palette, if needed
- switch(color_type)
- {
- case PNG_COLOR_TYPE_PALETTE:
- for(i=0; i<palette_entries; i++)
- {
- p2d->palette[i].rgbRed = png_palette[i].red;
- p2d->palette[i].rgbGreen = png_palette[i].green;
- p2d->palette[i].rgbBlue = png_palette[i].blue;
- }
- break;
- case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- for(i=0; i<palette_entries; i++)
- {
- p2d->palette[i].rgbRed =
- p2d->palette[i].rgbGreen =
- p2d->palette[i].rgbBlue = (i*255)/(palette_entries-1);
- if(manual_gamma)
- {
- gamma_correct(p2d->screen_gamma,file_gamma,
- &(p2d->palette[i].rgbRed),
- &(p2d->palette[i].rgbGreen),
- &(p2d->palette[i].rgbBlue));
- }
- }
- if(manual_trns)
- {
- p2d->palette[trns_color].rgbRed = bkgd_color.red;
- p2d->palette[trns_color].rgbGreen = bkgd_color.green;
- p2d->palette[trns_color].rgbBlue = bkgd_color.blue;
- }
- break;
- }
-
- // set up BITFIELDS, if needed
- if(dib_alpha32)
- {
- static const unsigned char bf_data[12] =
- {
- 0x00,0x00,0xff,0x00,
- 0x00,0xff,0x00,0x00,
- 0xff,0x00,0x00,0x00
- };
-
- for(i=0; i<12; i++)
- {
- lpdib[p2d->palette_offs+i]=bf_data[i];
- }
-
- }
-
- for(j=0; j<(int)height; j++)
- {
- row_pointers[height-1-j]= &dib_bits[j*dib_bytesperrow];
- }
-
- png_read_image(png_ptr, row_pointers);
-
- // special handling for this bit depth, since it doesn't exist in DIBs
- // expand 2bpp to 4bpp
- if(png_bit_depth==2)
- {
- tmprow = (unsigned char*)malloc((width+3)/4 );
- if(!tmprow)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
- for(j=0; j<(int)height; j++)
- {
- CopyMemory(tmprow, row_pointers[j], (width+3)/4 );
- ZeroMemory(row_pointers[j], (width+1)/2 );
-
- for(i=0; i<(int)width; i++)
- {
- row_pointers[j][i/2] |=
- ( ((tmprow[i/4] >> (2*(3-i%4)) ) & 0x03)<< (4*(1-i%2)) );
- }
- }
- free((void*)tmprow);
- }
-
- free((void*)row_pointers);
- row_pointers=NULL;
-
- png_read_end(png_ptr, info_ptr);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- png_ptr=NULL;
-
- if(p2d->input_method==0)
- {
- fclose(fp);
- fp=NULL;
- }
-
- // fill in the DIB header fields
- p2d->pdib->biSize= sizeof(BITMAPINFOHEADER);
- p2d->pdib->biWidth= width;
- p2d->pdib->biHeight= height;
- p2d->pdib->biPlanes= 1;
- p2d->pdib->biBitCount= dib_bpp;
- p2d->pdib->biCompression= write_bitfields?BI_BITFIELDS:BI_RGB;
- // biSizeImage can also be 0 in uncompressed bitmaps
- p2d->pdib->biSizeImage= height*dib_bytesperrow;
-
- if(has_phys)
- {
- if(res_unit_type==1)
- {
- p2d->pdib->biXPelsPerMeter= res_x;
- p2d->pdib->biYPelsPerMeter= res_y;
- }
- }
- p2d->pdib->biClrUsed= palette_entries;
- p2d->pdib->biClrImportant= 0;
-
- if(has_bkgd || (p2d->use_custom_bg_flag))
- {
- // return the background color if one was used
- p2d->bgcolor.red = bkgd_color.red;
- p2d->bgcolor.green = bkgd_color.green;
- p2d->bgcolor.blue = bkgd_color.blue;
- p2d->bgcolor_returned=1;
- }
-
- return PNGD_E_SUCCESS;
+ // If we don't have any background color at all that we can use,
+ // strip the alpha channel.
+ if(!dib_alpha32 && has_alpha_channel && !has_bkgd &&
+ !(p2d->use_custom_bg_flag) )
+ {
+ png_set_strip_alpha(png_ptr);
+ }
+
+ if(png_bit_depth>8)
+ png_set_strip_16(png_ptr);
+
+ if (png_get_sRGB(png_ptr, info_ptr, &i)) {
+ has_gama=1;
+ file_gamma = 0.45455;
+ }
+ else if(png_get_gAMA(png_ptr, info_ptr, &file_gamma)) {
+ has_gama=1;
+ }
+ else {
+ has_gama=0;
+ file_gamma = 0.45455;
+ }
+
+ if(/*imginfo && */ has_gama) {
+ p2d->file_gamma=file_gamma;
+ p2d->gamma_returned=1;
+ }
+
+ manual_gamma=0;
+ if(p2d->gamma_correction) {
+
+ if(!is_grayscale || png_bit_depth>8 || has_alpha_channel) {
+ png_set_gamma(png_ptr, p2d->screen_gamma, file_gamma);
+ //png_ptr->transformations |= 0x2000; // hack for old libpng versions
+ }
+ else manual_gamma=1;
+
+ if(has_bkgd) {
+ // Gamma correct the background color (if we got it from the file)
+ // before returning it to the app.
+ gamma_correct(p2d->screen_gamma,file_gamma,&bkgd_color.red,&bkgd_color.green,&bkgd_color.blue);
+ }
+ }
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ // color type may have changed, due to our transformations
+ color_type = png_get_color_type(png_ptr,info_ptr);
+
+
+ switch(color_type) {
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ assert(dib_alpha32);
+ dib_bpp= 32;
+ palette_entries=0;
+ png_set_bgr(png_ptr);
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ dib_bpp= 24;
+ palette_entries=0;
+ png_set_bgr(png_ptr);
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ dib_bpp=png_bit_depth;
+ png_get_PLTE(png_ptr,info_ptr,&png_palette,&palette_entries);
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ dib_bpp=png_bit_depth;
+ if(png_bit_depth>8) dib_bpp=8;
+ palette_entries= 1<<dib_bpp;
+ // we'll construct a grayscale palette later
+ break;
+ default:
+ rv=PNGD_E_BADPNG;
+ goto abort;
+ }
+
+ if(dib_bpp==2) dib_bpp=4;
+
+ has_phys=png_get_valid(png_ptr,info_ptr,PNG_INFO_pHYs);
+ if(has_phys) {
+ png_get_pHYs(png_ptr,info_ptr,&res_x,&res_y,&res_unit_type);
+ if(res_x>0 && res_y>0) {
+ p2d->res_x=res_x;
+ p2d->res_y=res_y;
+ p2d->res_units=res_unit_type;
+ p2d->res_valid=1;
+ }
+ }
+
+ // DIB scanlines are padded to 4-byte boundaries.
+ dib_bytesperrow= (((width * dib_bpp)+31)/32)*4;
+
+ p2d->bitssize = height*dib_bytesperrow;
+
+ p2d->dibsize=sizeof(BITMAPINFOHEADER) + 4*palette_entries +
+ (write_bitfields?12:0) + p2d->bitssize;;
+
+ if(p2d->common.malloc_function) {
+ lpdib = (unsigned char*)(*(p2d->common.malloc_function))(p2d->common.userdata,p2d->dibsize);
+ }
+ else {
+ lpdib = (unsigned char*)calloc(p2d->dibsize,1);
+ }
+
+
+ if(!lpdib) { rv=PNGD_E_NOMEM; goto abort; }
+ p2d->pdib = (LPBITMAPINFOHEADER)lpdib;
+
+ row_pointers=(unsigned char**)malloc(height*sizeof(unsigned char*));
+ if(!row_pointers) { rv=PNGD_E_NOMEM; goto abort; }
+
+ // there is some redundancy here...
+ p2d->palette_offs=sizeof(BITMAPINFOHEADER);
+ p2d->bits_offs =sizeof(BITMAPINFOHEADER) + 4*palette_entries + (write_bitfields?12:0);
+ dib_palette= &lpdib[p2d->palette_offs];
+ p2d->palette= (RGBQUAD*)dib_palette;
+ dib_bits = &lpdib[p2d->bits_offs];
+ p2d->pbits = (VOID*)dib_bits;
+ p2d->palette_colors = palette_entries;
+
+ // set up the DIB palette, if needed
+ switch(color_type) {
+ case PNG_COLOR_TYPE_PALETTE:
+ for(i=0;i<palette_entries;i++) {
+ p2d->palette[i].rgbRed = png_palette[i].red;
+ p2d->palette[i].rgbGreen = png_palette[i].green;
+ p2d->palette[i].rgbBlue = png_palette[i].blue;
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ for(i=0;i<palette_entries;i++) {
+ p2d->palette[i].rgbRed =
+ p2d->palette[i].rgbGreen =
+ p2d->palette[i].rgbBlue = (i*255)/(palette_entries-1);
+ if(manual_gamma) {
+ gamma_correct(p2d->screen_gamma,file_gamma,
+ &(p2d->palette[i].rgbRed),
+ &(p2d->palette[i].rgbGreen),
+ &(p2d->palette[i].rgbBlue));
+ }
+ }
+ if(manual_trns) {
+ p2d->palette[trns_color].rgbRed = bkgd_color.red;
+ p2d->palette[trns_color].rgbGreen = bkgd_color.green;
+ p2d->palette[trns_color].rgbBlue = bkgd_color.blue;
+ }
+ break;
+ }
+
+ // set up BITFIELDS, if needed
+ if(dib_alpha32) {
+ static const unsigned char bf_data[12] = {
+ 0x00,0x00,0xff,0x00,
+ 0x00,0xff,0x00,0x00,
+ 0xff,0x00,0x00,0x00
+ };
+
+ for(i=0;i<12;i++) {
+ lpdib[p2d->palette_offs+i]=bf_data[i];
+ }
+
+ }
+
+ for(j=0;j<(int)height;j++) {
+ row_pointers[height-1-j]= &dib_bits[j*dib_bytesperrow];
+ }
+
+ png_read_image(png_ptr, row_pointers);
+
+ // special handling for this bit depth, since it doesn't exist in DIBs
+ // expand 2bpp to 4bpp
+ if(png_bit_depth==2) {
+ tmprow = (unsigned char*)malloc((width+3)/4 );
+ if(!tmprow) { rv=PNGD_E_NOMEM; goto abort; }
+
+ for(j=0;j<(int)height;j++) {
+ CopyMemory(tmprow, row_pointers[j], (width+3)/4 );
+ ZeroMemory(row_pointers[j], (width+1)/2 );
+
+ for(i=0;i<(int)width;i++) {
+ row_pointers[j][i/2] |=
+ ( ((tmprow[i/4] >> (2*(3-i%4)) ) & 0x03)<< (4*(1-i%2)) );
+ }
+ }
+ free((void*)tmprow);
+ }
+
+ free((void*)row_pointers);
+ row_pointers=NULL;
+
+ png_read_end(png_ptr, info_ptr);
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ png_ptr=NULL;
+
+ if(p2d->input_method==0) {
+ fclose(fp);
+ fp=NULL;
+ }
+
+ // fill in the DIB header fields
+ p2d->pdib->biSize= sizeof(BITMAPINFOHEADER);
+ p2d->pdib->biWidth= width;
+ p2d->pdib->biHeight= height;
+ p2d->pdib->biPlanes= 1;
+ p2d->pdib->biBitCount= dib_bpp;
+ p2d->pdib->biCompression= write_bitfields?BI_BITFIELDS:BI_RGB;
+ // biSizeImage can also be 0 in uncompressed bitmaps
+ p2d->pdib->biSizeImage= height*dib_bytesperrow;
+
+ if(has_phys) {
+ if(res_unit_type==1) {
+ p2d->pdib->biXPelsPerMeter= res_x;
+ p2d->pdib->biYPelsPerMeter= res_y;
+ }
+ }
+ p2d->pdib->biClrUsed= palette_entries;
+ p2d->pdib->biClrImportant= 0;
+
+ if(has_bkgd || (p2d->use_custom_bg_flag)) {
+ // return the background color if one was used
+ p2d->bgcolor.red = bkgd_color.red;
+ p2d->bgcolor.green = bkgd_color.green;
+ p2d->bgcolor.blue = bkgd_color.blue;
+ p2d->bgcolor_returned=1;
+ }
+
+ return PNGD_E_SUCCESS;
abort:
- if(png_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- if(p2d->input_method==0 && fp) fclose(fp);
- if(row_pointers) free((void*)row_pointers);
- if(lpdib)
- {
- pngdib_p2d_free_dib((PNGDIB*)p2d,NULL);
- }
-
- // If we don't have an error message yet, use a
- // default one based on the code
- if(!lstrlen(p2d->common.errmsg))
- {
- pngd_get_error_message(rv,p2d->common.errmsg);
- }
-
- return rv;
+ if(png_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ if(p2d->input_method==0 && fp) fclose(fp);
+ if(row_pointers) free((void*)row_pointers);
+ if(lpdib) {
+ pngdib_p2d_free_dib((PNGDIB*)p2d,NULL);
+ }
+
+ // If we don't have an error message yet, use a
+ // default one based on the code
+ if(!lstrlen(p2d->common.errmsg)) {
+ pngd_get_error_message(rv,p2d->common.errmsg,PNGDIB_ERRMSG_MAX);
+ }
+
+ return rv;
}
void PNGDIB_DECL pngdib_p2d_free_dib(PNGDIB *qq, BITMAPINFOHEADER* pdib)
{
- struct p2d_struct *p2d;
-
- if(!qq)
- {
- if(pdib) free((void*)pdib);
- return;
- }
-
- p2d=(struct p2d_struct*)qq;
- if(!pdib)
- {
- // DIB not explicitly given; use the one from the PNGDIB object.
- // (this is the normal case)
- pdib = p2d->pdib;
- p2d->pdib = NULL;
- }
- if(pdib)
- {
- if(p2d->common.free_function)
- {
- (*(p2d->common.free_function))(p2d->common.userdata,(void*)pdib);
- }
- else
- {
- free((void*)pdib);
- }
- }
+ struct p2d_struct *p2d;
+
+ if(!qq) {
+ if(pdib) free((void*)pdib);
+ return;
+ }
+
+ p2d=(struct p2d_struct*)qq;
+ if(!pdib) {
+ // DIB not explicitly given; use the one from the PNGDIB object.
+ // (this is the normal case)
+ pdib = p2d->pdib;
+ p2d->pdib = NULL;
+ }
+ if(pdib) {
+ if(p2d->common.free_function) {
+ (*(p2d->common.free_function))(p2d->common.userdata,(void*)pdib);
+ }
+ else {
+ free((void*)pdib);
+ }
+ }
}
int PNGDIB_DECL pngdib_d2p_run(PNGDIB *qq)
{
- struct d2p_struct *d2p;
- png_structp png_ptr;
- png_infop info_ptr;
- jmp_buf jbuf;
- struct errstruct errinfo;
- png_text text_ptr[1];
- unsigned char *bits;
- unsigned char *newimage;
- RGBQUAD* dib_palette;
- int headersize, dib_bpp;
- int png_color_type;
- png_uint_32 res_x, res_y;
- png_color_8 pngc8;
- int height,width;
- int palette_entries;
- int topdown;
- int dib_bytesperrow;
- int compression;
- FILE *fp;
- png_color png_palette[256];
- unsigned char **row_pointers;
- int i,x,y,size;
- DWORD *bitfields;
- unsigned int v;
- int bf_format; // bitfields format identifier
- int iscompressed;
- int bfsize; // bytes in "bitfields" section
- int palsize; // bytes in palette
-
- int palentsize; // bytes in a palette entry: 3 or 4;
- BITMAPCOREHEADER *lpolddib;
- int rv; // return code
- int dib_alpha32;
-
- d2p=(struct d2p_struct*)qq;
-
- rv=PNGD_E_ERROR; // this should always get changed before returning
- png_ptr=NULL;
- info_ptr=NULL;
- fp=NULL;
- row_pointers=NULL;
- newimage=NULL;
- dib_alpha32=0;
-
- lstrcpy(d2p->common.errmsg,_T(""));
-
- if(!d2p->output_filename)
- {
- wsprintf(d2p->common.errmsg,_T("Output filename not set"));
- rv=PNGD_E_ERROR;
- goto abort;
- }
-
- if(!d2p->pdib)
- {
- wsprintf(d2p->common.errmsg,_T("Input DIB not set"));
- rv=PNGD_E_ERROR;
- goto abort;
- }
-
-
- headersize= d2p->pdib->biSize;
-
- if(headersize<40 && headersize!=12)
- {
- wsprintf(d2p->common.errmsg,_T("Unexpected BMP header size (%d)"),headersize);
- rv=PNGD_E_BADBMP;
- goto abort;
- }
-
- if(headersize==12)
- {
- // This is to support an old kind of DIBs (OS/2) that aren't really
- // used anymore.
- palentsize= 3;
- lpolddib= (BITMAPCOREHEADER*) d2p->pdib;
- width= lpolddib->bcWidth;
- height= lpolddib->bcHeight;
- dib_bpp= lpolddib->bcBitCount;
- compression = BI_RGB;
- res_x = res_y = 0;
-
- // This will get adjusted later if there is a palette.
- // Not sure it's right, though. Do old DIBs always have a
- // full-sized palette?
- palette_entries=0;
- }
- else
- {
- palentsize=4;
- width = d2p->pdib->biWidth;
- height = d2p->pdib->biHeight;
- dib_bpp = d2p->pdib->biBitCount;
- compression = d2p->pdib->biCompression;
- res_x = d2p->pdib->biXPelsPerMeter;
- res_y = d2p->pdib->biYPelsPerMeter;
- palette_entries = d2p->pdib->biClrUsed;
- }
-
- // supposedly, if the height is negative, the top scanline is stored first
- topdown=0;
- if(height<0)
- {
- height= -height;
- topdown=1;
- }
-
- // sanity check
- if(height<1 || height>1000000 || width<1 || width>1000000)
- {
- wsprintf(d2p->common.errmsg,_T("Unreasonable image dimensions (%dx%d)"),width,height);
- rv=PNGD_E_BADBMP;
- goto abort;
- }
-
- if(dib_bpp==32 && (d2p->common.dib_alpha32))
- {
- dib_alpha32=1;
- }
-
- // only certain combinations of compression and bpp are allowed
- switch(compression)
- {
- case BI_RGB:
- if(dib_bpp!=1 && dib_bpp!=4 && dib_bpp!=8 && dib_bpp!=16
- && dib_bpp!=24 && dib_bpp!=32)
- {
- wsprintf(d2p->common.errmsg,_T("Unsupported bit depth (%d)"),dib_bpp);
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- break;
- case BI_RLE4:
- if(dib_bpp!=4)
- {
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- break;
- case BI_RLE8:
- if(dib_bpp!=8)
- {
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- break;
- case BI_BITFIELDS:
- if(dib_bpp!=16 && dib_bpp!=32)
- {
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- break;
- default:
- wsprintf(d2p->common.errmsg,_T("Unsupported compression scheme"));
- return PNGD_E_UNSUPP;
- }
-
- iscompressed= (compression==BI_RLE4 || compression==BI_RLE8);
-
- // uncompressed dibs are padded to 4-byte bondaries
- dib_bytesperrow= (((width * dib_bpp)+31)/32)*4;
-
- if(dib_bpp<16)
- {
- if(palette_entries==0) palette_entries = 1<<dib_bpp;
- }
-
- bfsize = (compression==BI_BITFIELDS)?12:0;
-
- palsize=palentsize*palette_entries;
-
- // bounds check
- size= headersize + bfsize + palsize;
- if(d2p->dibsize)
- {
- if(size>d2p->dibsize)
- {
- rv=PNGD_E_BADBMP;
- goto abort;
- }
- }
-
- if(d2p->pbits)
- {
- if(d2p->bitssize && !iscompressed) // bounds check
- {
- size=dib_bytesperrow*height;
- if(size>d2p->bitssize)
- {
- rv=PNGD_E_BADBMP;
- goto abort;
- }
- }
-
- bits=(unsigned char*)d2p->pbits;
- }
- else
- {
- // If not provided by user, assume the bits immediately
- // follow the palette.
-
- if(d2p->dibsize && !iscompressed) // bounds check
- {
- size= headersize+bfsize+palsize+dib_bytesperrow*height;
- if(size>d2p->dibsize)
- {
- rv=PNGD_E_BADBMP;
- goto abort;
- }
- }
-
- bits= &((unsigned char*)(d2p->pdib))[headersize+bfsize+palsize];
- }
-
- bitfields = (DWORD*) ( &((unsigned char*)(d2p->pdib))[headersize] );
- dib_palette = (RGBQUAD*) ( &((unsigned char*)(d2p->pdib))[headersize+bfsize] );
-
- bf_format=0;
- if(compression==BI_BITFIELDS)
- {
- if(dib_bpp==16)
- {
- if (bitfields[0]==0x00007c00 && bitfields[1]==0x000003e0 &&
- bitfields[2]==0x0000001f) bf_format=11; // 555
- else if(bitfields[0]==0x0000f800 && bitfields[1]==0x000007e0 &&
- bitfields[2]==0x0000001f) bf_format=12; // 565
- else
- {
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- }
- if(dib_bpp==32)
- {
- if (bitfields[0]==0x00ff0000 && bitfields[1]==0x0000ff00 &&
- bitfields[2]==0x000000ff) bf_format=21;
- else
- {
- rv=PNGD_E_UNSUPP;
- goto abort;
- }
- }
- }
-
- if(bf_format==0 && dib_bpp==16) bf_format=10;
- if(bf_format==0 && dib_bpp==32) bf_format=20;
-
-
- // Done analyzing the DIB, now time to convert it to PNG
-
- // FIXME: this probably isn't quite right
- // jbuf: see comments in read_png_to_dib()
- errinfo.jbufp = &jbuf;
- errinfo.errmsg = d2p->common.errmsg;
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void*)(&errinfo),
- my_png_error_fn, my_png_warning_fn);
- if (!png_ptr)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- //png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
- if(setjmp(jbuf))
- {
- // we'll get here if an error occurred in any of the following
- // png_ functions
- rv=PNGD_E_LIBPNG;
- goto abort;
- }
-
- fp= _tfopen(d2p->output_filename,_T("wb"));
- if(!fp)
- {
- rv=PNGD_E_WRITE;
- goto abort;
- }
-
- png_init_io(png_ptr, fp);
-
- if(dib_alpha32)
- {
- png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- }
- else
- {
- png_color_type = (dib_bpp>8)?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE;
- }
-
- png_set_IHDR(png_ptr, info_ptr, width, height, (dib_bpp>8)?8:dib_bpp,
- png_color_type,
- (d2p->interlaced)?PNG_INTERLACE_ADAM7:PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- // write sRGB and gAMA chunks
- if(d2p->file_gamma_valid)
- {
- if(d2p->file_gamma>0.454539 && d2p->file_gamma<0.454551)
- {
- png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_RELATIVE);
- }
- png_set_gAMA(png_ptr, info_ptr, d2p->file_gamma);
- }
-
- // For 16-bit DIBs, we get to write an sBIT chunk.
- if(bf_format==10 || bf_format==11)
- {
- pngc8.red= 5;
- pngc8.green= 5;
- pngc8.blue= 5;
- png_set_sBIT(png_ptr, info_ptr, &pngc8);
- }
- if(bf_format==12)
- {
- pngc8.red= 5;
- pngc8.green= 6;
- pngc8.blue= 5;
- png_set_sBIT(png_ptr, info_ptr, &pngc8);
- }
-
- // pHYs
- if(res_x>0 && res_y>0)
- png_set_pHYs(png_ptr, info_ptr, res_x, res_y, 1);
-
-
- if(palette_entries>0)
- {
- for(i=0; i<palette_entries; i++)
- {
- if(palentsize==3)
- {
- png_palette[i].red = ((RGBTRIPLE*)dib_palette)[i].rgbtRed;
- png_palette[i].green = ((RGBTRIPLE*)dib_palette)[i].rgbtGreen;
- png_palette[i].blue = ((RGBTRIPLE*)dib_palette)[i].rgbtBlue;
- }
- else
- {
- png_palette[i].red = dib_palette[i].rgbRed;
- png_palette[i].green = dib_palette[i].rgbGreen;
- png_palette[i].blue = dib_palette[i].rgbBlue;
- }
- }
- png_set_PLTE(png_ptr, info_ptr, png_palette, palette_entries);
- }
-
- if(dib_bpp>8)
- png_set_bgr(png_ptr);
-
- png_write_info(png_ptr, info_ptr);
-
- row_pointers=(unsigned char**)malloc(height*sizeof(unsigned char*));
- if(!row_pointers)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
-
- if(dib_bpp==16 || (dib_bpp==32 && !dib_alpha32))
- {
-
- // Special handling for these bit depths.
- // This uses a lot of memory, and could be improved by processing
- // one line at a time (but that makes it tricky to write interlaced
- // images).
-
- newimage=(unsigned char*)malloc(height*width*3);
- if(!newimage)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
-
- for(y=0; y<height; y++)
- {
- for(x=0; x<width; x++)
- {
- switch(bf_format)
- {
- case 10:
- case 11: // 16-bit, format 555 (xRRRRRGG GGGBBBBB)
- v= bits[y*dib_bytesperrow+x*2+0] | (bits[y*dib_bytesperrow+x*2+1]<<8);
- newimage[(y*width+x)*3+0]= (v & 0x0000001f)<<3 | (v & 0x0000001f)>>2; // blue
- newimage[(y*width+x)*3+1]= (v & 0x000003e0)>>2 | (v & 0x000003e0)>>7; // green
- newimage[(y*width+x)*3+2]= (v & 0x00007c00)>>7 | (v & 0x00007c00)>>12; // red
- break;
- case 12: // 16-bit, format 565 (RRRRRGGG GGGBBBBB)
- v= bits[y*dib_bytesperrow+x*2+0] | (bits[y*dib_bytesperrow+x*2+1]<<8);
- newimage[(y*width+x)*3+0]= (v & 0x0000001f)<<3 | (v & 0x0000001f)>>2; // blue
- newimage[(y*width+x)*3+1]= (v & 0x000007e0)>>3 | (v & 0x000007e0)>>9; // green
- newimage[(y*width+x)*3+2]= (v & 0x0000f800)>>8 | (v & 0x0000f800)>>13; // red
- break;
- case 20:
- case 21: // 32-bit, every 4th byte wasted (b g r x)
- newimage[(y*width+x)*3+0]= bits[y*dib_bytesperrow+x*4+0]; // blue
- newimage[(y*width+x)*3+1]= bits[y*dib_bytesperrow+x*4+1]; // green
- newimage[(y*width+x)*3+2]= bits[y*dib_bytesperrow+x*4+2]; // red
- break;
- }
- }
- }
-
- for(i=0; i<height; i++)
- {
- if(topdown)
- row_pointers[i]= &newimage[i*width*3];
- else
- row_pointers[height-1-i]= &newimage[i*width*3];
- }
- png_write_image(png_ptr, row_pointers);
-
- free(newimage);
- newimage=NULL;
- }
- else if(iscompressed)
- {
- newimage= uncompress_dib((LPBITMAPINFO)d2p->pdib, headersize+bfsize+palsize, bits);
- if(!newimage)
- {
- rv=PNGD_E_NOMEM;
- goto abort;
- }
- for(i=0; i<height; i++)
- {
- if(topdown)
- row_pointers[i]= &newimage[i*dib_bytesperrow];
- else
- row_pointers[height-1-i]= &newimage[i*dib_bytesperrow];
- }
- png_write_image(png_ptr, row_pointers);
-
- free(newimage);
- newimage=NULL;
- }
- else
- {
- for(i=0; i<height; i++)
- {
- if(topdown)
- row_pointers[i]= &bits[i*dib_bytesperrow];
- else
- row_pointers[height-1-i]= &bits[i*dib_bytesperrow];
- }
- png_write_image(png_ptr, row_pointers);
- }
-
- free((VOID*)row_pointers);
- row_pointers=NULL;
-
- if(d2p->software_id_string)
- {
- text_ptr[0].key = "Software";
- text_ptr[0].text = d2p->software_id_string;
- text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
- png_set_text(png_ptr, info_ptr, text_ptr, 1);
- }
-
- png_write_end(png_ptr, info_ptr);
-
- rv=PNGD_E_SUCCESS;
+ struct d2p_struct *d2p;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ jmp_buf jbuf;
+ struct errstruct errinfo;
+ png_text text_ptr[1];
+ unsigned char *bits;
+ unsigned char *newimage;
+ RGBQUAD* dib_palette;
+ int headersize, dib_bpp;
+ int png_color_type;
+ png_uint_32 res_x, res_y;
+ png_color_8 pngc8;
+ int height,width;
+ int palette_entries;
+ int topdown;
+ int dib_bytesperrow;
+ int compression;
+ FILE *fp;
+ png_color png_palette[256];
+ unsigned char **row_pointers;
+ int i,x,y,size;
+ DWORD *bitfields;
+ unsigned int v;
+ int bf_format; // bitfields format identifier
+ int iscompressed;
+ int bfsize; // bytes in "bitfields" section
+ int palsize; // bytes in palette
+
+ int palentsize; // bytes in a palette entry: 3 or 4;
+ BITMAPCOREHEADER *lpolddib;
+ int rv; // return code
+ int dib_alpha32;
+
+ d2p=(struct d2p_struct*)qq;
+
+ rv=PNGD_E_ERROR; // this should always get changed before returning
+ png_ptr=NULL;
+ info_ptr=NULL;
+ fp=NULL;
+ row_pointers=NULL;
+ newimage=NULL;
+ dib_alpha32=0;
+
+ StringCchCopy(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T(""));
+
+ if(!d2p->output_filename) {
+ StringCchCopy(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Output filename not set"));
+ rv=PNGD_E_ERROR; goto abort;
+ }
+
+ if(!d2p->pdib) {
+ StringCchCopy(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Input DIB not set"));
+ rv=PNGD_E_ERROR; goto abort;
+ }
+
+
+ headersize= d2p->pdib->biSize;
+
+ if(headersize<40 && headersize!=12) {
+ StringCchPrintf(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Unexpected BMP header size (%d)"),headersize);
+ rv=PNGD_E_BADBMP; goto abort;
+ }
+
+ if(headersize==12) {
+ // This is to support an old kind of DIBs (OS/2) that aren't really
+ // used anymore.
+ palentsize= 3;
+ lpolddib= (BITMAPCOREHEADER*) d2p->pdib;
+ width= lpolddib->bcWidth;
+ height= lpolddib->bcHeight;
+ dib_bpp= lpolddib->bcBitCount;
+ compression = BI_RGB;
+ res_x = res_y = 0;
+
+ // This will get adjusted later if there is a palette.
+ // Not sure it's right, though. Do old DIBs always have a
+ // full-sized palette?
+ palette_entries=0;
+ }
+ else {
+ palentsize=4;
+ width = d2p->pdib->biWidth;
+ height = d2p->pdib->biHeight;
+ dib_bpp = d2p->pdib->biBitCount;
+ compression = d2p->pdib->biCompression;
+ res_x = d2p->pdib->biXPelsPerMeter;
+ res_y = d2p->pdib->biYPelsPerMeter;
+ palette_entries = d2p->pdib->biClrUsed;
+ }
+
+ // supposedly, if the height is negative, the top scanline is stored first
+ topdown=0;
+ if(height<0) {
+ height= -height;
+ topdown=1;
+ }
+
+ // sanity check
+ if(height<1 || height>1000000 || width<1 || width>1000000) {
+ StringCchPrintf(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Unreasonable image dimensions (%dx%d)"),width,height);
+ rv=PNGD_E_BADBMP; goto abort;
+ }
+
+ if(dib_bpp==32 && (d2p->common.dib_alpha32)) {
+ dib_alpha32=1;
+ }
+
+ // only certain combinations of compression and bpp are allowed
+ switch(compression) {
+ case BI_RGB:
+ if(dib_bpp!=1 && dib_bpp!=4 && dib_bpp!=8 && dib_bpp!=16
+ && dib_bpp!=24 && dib_bpp!=32)
+ {
+ StringCchPrintf(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Unsupported bit depth (%d)"),dib_bpp);
+ rv=PNGD_E_UNSUPP; goto abort;
+ }
+ break;
+ case BI_RLE4:
+ if(dib_bpp!=4) {
+ rv=PNGD_E_UNSUPP; goto abort;
+ }
+ break;
+ case BI_RLE8:
+ if(dib_bpp!=8) {
+ rv=PNGD_E_UNSUPP; goto abort;
+ }
+ break;
+ case BI_BITFIELDS:
+ if(dib_bpp!=16 && dib_bpp!=32) {
+ rv=PNGD_E_UNSUPP; goto abort;
+ }
+ break;
+ default:
+ StringCchCopy(d2p->common.errmsg,PNGDIB_ERRMSG_MAX,_T("Unsupported compression scheme"));
+ return PNGD_E_UNSUPP;
+ }
+
+ iscompressed= (compression==BI_RLE4 || compression==BI_RLE8);
+
+ // uncompressed dibs are padded to 4-byte bondaries
+ dib_bytesperrow= (((width * dib_bpp)+31)/32)*4;
+
+ if(dib_bpp<16) {
+ if(palette_entries==0) palette_entries = 1<<dib_bpp;
+ }
+
+ bfsize = (compression==BI_BITFIELDS)?12:0;
+
+ palsize=palentsize*palette_entries;
+
+ // bounds check
+ size= headersize + bfsize + palsize;
+ if(d2p->dibsize) {
+ if(size>d2p->dibsize) {
+ rv=PNGD_E_BADBMP; goto abort;
+ }
+ }
+
+ if(d2p->pbits) {
+ if(d2p->bitssize && !iscompressed) { // bounds check
+ size=dib_bytesperrow*height;
+ if(size>d2p->bitssize) { rv=PNGD_E_BADBMP; goto abort; }
+ }
+
+ bits=(unsigned char*)d2p->pbits;
+ }
+ else {
+ // If not provided by user, assume the bits immediately
+ // follow the palette.
+
+ if(d2p->dibsize && !iscompressed) { // bounds check
+ size= headersize+bfsize+palsize+dib_bytesperrow*height;
+ if(size>d2p->dibsize) { rv=PNGD_E_BADBMP; goto abort; }
+ }
+
+ bits= &((unsigned char*)(d2p->pdib))[headersize+bfsize+palsize];
+ }
+
+ bitfields = (DWORD*) ( &((unsigned char*)(d2p->pdib))[headersize] );
+ dib_palette = (RGBQUAD*) ( &((unsigned char*)(d2p->pdib))[headersize+bfsize] );
+
+ bf_format=0;
+ if(compression==BI_BITFIELDS) {
+ if(dib_bpp==16) {
+ if (bitfields[0]==0x00007c00 && bitfields[1]==0x000003e0 &&
+ bitfields[2]==0x0000001f) bf_format=11; // 555
+ else if(bitfields[0]==0x0000f800 && bitfields[1]==0x000007e0 &&
+ bitfields[2]==0x0000001f) bf_format=12; // 565
+ else { rv=PNGD_E_UNSUPP; goto abort; }
+ }
+ if(dib_bpp==32) {
+ if (bitfields[0]==0x00ff0000 && bitfields[1]==0x0000ff00 &&
+ bitfields[2]==0x000000ff) bf_format=21;
+ else { rv=PNGD_E_UNSUPP; goto abort; }
+ }
+ }
+
+ if(bf_format==0 && dib_bpp==16) bf_format=10;
+ if(bf_format==0 && dib_bpp==32) bf_format=20;
+
+
+ // Done analyzing the DIB, now time to convert it to PNG
+
+ // FIXME: this probably isn't quite right
+ // jbuf: see comments in read_png_to_dib()
+ errinfo.jbufp = &jbuf;
+ errinfo.errmsg = d2p->common.errmsg;
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void*)(&errinfo),
+ my_png_error_fn, my_png_warning_fn);
+ if (!png_ptr) { rv=PNGD_E_NOMEM; goto abort; }
+
+ if(d2p->common.pngptrhook_function) {
+ (*(d2p->common.pngptrhook_function))(d2p->common.userdata,(void*)png_ptr);
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ //png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
+ rv=PNGD_E_NOMEM; goto abort;
+ }
+
+ if(setjmp(jbuf)) {
+ // we'll get here if an error occurred in any of the following
+ // png_ functions
+ rv=PNGD_E_LIBPNG;
+ goto abort;
+ }
+
+ fp= _tfopen(d2p->output_filename,_T("wb"));
+ if(!fp) {
+ rv=PNGD_E_WRITE;
+ goto abort;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ if(dib_alpha32) {
+ png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+ else {
+ png_color_type = (dib_bpp>8)?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE;
+ }
+
+ png_set_IHDR(png_ptr, info_ptr, width, height, (dib_bpp>8)?8:dib_bpp,
+ png_color_type,
+ (d2p->interlaced)?PNG_INTERLACE_ADAM7:PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ // write sRGB and gAMA chunks
+ if(d2p->file_gamma_valid) {
+ if(d2p->file_gamma>0.454539 && d2p->file_gamma<0.454551) {
+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_RELATIVE);
+ }
+ png_set_gAMA(png_ptr, info_ptr, d2p->file_gamma);
+ }
+
+ // For 16-bit DIBs, we get to write an sBIT chunk.
+ if(bf_format==10 || bf_format==11) {
+ pngc8.red= 5; pngc8.green= 5; pngc8.blue= 5;
+ png_set_sBIT(png_ptr, info_ptr, &pngc8);
+ }
+ if(bf_format==12) {
+ pngc8.red= 5; pngc8.green= 6; pngc8.blue= 5;
+ png_set_sBIT(png_ptr, info_ptr, &pngc8);
+ }
+
+ // pHYs
+ if(res_x>0 && res_y>0)
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, 1);
+
+
+ if(palette_entries>0) {
+ for(i=0;i<palette_entries;i++) {
+ if(palentsize==3) {
+ png_palette[i].red = ((RGBTRIPLE*)dib_palette)[i].rgbtRed;
+ png_palette[i].green = ((RGBTRIPLE*)dib_palette)[i].rgbtGreen;
+ png_palette[i].blue = ((RGBTRIPLE*)dib_palette)[i].rgbtBlue;
+ }
+ else {
+ png_palette[i].red = dib_palette[i].rgbRed;
+ png_palette[i].green = dib_palette[i].rgbGreen;
+ png_palette[i].blue = dib_palette[i].rgbBlue;
+ }
+ }
+ png_set_PLTE(png_ptr, info_ptr, png_palette, palette_entries);
+ }
+
+ if(dib_bpp>8)
+ png_set_bgr(png_ptr);
+
+ png_write_info(png_ptr, info_ptr);
+
+ row_pointers=(unsigned char**)malloc(height*sizeof(unsigned char*));
+ if(!row_pointers) { rv=PNGD_E_NOMEM; goto abort; }
+
+
+ if(dib_bpp==16 || (dib_bpp==32 && !dib_alpha32)) {
+
+ // Special handling for these bit depths.
+ // This uses a lot of memory, and could be improved by processing
+ // one line at a time (but that makes it tricky to write interlaced
+ // images).
+
+ newimage=(unsigned char*)malloc(height*width*3);
+ if(!newimage) { rv=PNGD_E_NOMEM; goto abort; }
+
+ for(y=0;y<height;y++) {
+ for(x=0;x<width;x++) {
+ switch(bf_format) {
+ case 10: case 11: // 16-bit, format 555 (xRRRRRGG GGGBBBBB)
+ v= bits[y*dib_bytesperrow+x*2+0] | (bits[y*dib_bytesperrow+x*2+1]<<8);
+ newimage[(y*width+x)*3+0]= (v & 0x0000001f)<<3 | (v & 0x0000001f)>>2; // blue
+ newimage[(y*width+x)*3+1]= (v & 0x000003e0)>>2 | (v & 0x000003e0)>>7; // green
+ newimage[(y*width+x)*3+2]= (v & 0x00007c00)>>7 | (v & 0x00007c00)>>12; // red
+ break;
+ case 12: // 16-bit, format 565 (RRRRRGGG GGGBBBBB)
+ v= bits[y*dib_bytesperrow+x*2+0] | (bits[y*dib_bytesperrow+x*2+1]<<8);
+ newimage[(y*width+x)*3+0]= (v & 0x0000001f)<<3 | (v & 0x0000001f)>>2; // blue
+ newimage[(y*width+x)*3+1]= (v & 0x000007e0)>>3 | (v & 0x000007e0)>>9; // green
+ newimage[(y*width+x)*3+2]= (v & 0x0000f800)>>8 | (v & 0x0000f800)>>13; // red
+ break;
+ case 20: case 21: // 32-bit, every 4th byte wasted (b g r x)
+ newimage[(y*width+x)*3+0]= bits[y*dib_bytesperrow+x*4+0]; // blue
+ newimage[(y*width+x)*3+1]= bits[y*dib_bytesperrow+x*4+1]; // green
+ newimage[(y*width+x)*3+2]= bits[y*dib_bytesperrow+x*4+2]; // red
+ break;
+ }
+ }
+ }
+
+ for(i=0;i<height;i++) {
+ if(topdown)
+ row_pointers[i]= &newimage[i*width*3];
+ else
+ row_pointers[height-1-i]= &newimage[i*width*3];
+ }
+ png_write_image(png_ptr, row_pointers);
+
+ free(newimage);
+ newimage=NULL;
+ }
+ else if(iscompressed) {
+ newimage= uncompress_dib((LPBITMAPINFO)d2p->pdib, headersize+bfsize+palsize, bits);
+ if(!newimage) { rv=PNGD_E_NOMEM; goto abort; }
+ for(i=0;i<height;i++) {
+ if(topdown)
+ row_pointers[i]= &newimage[i*dib_bytesperrow];
+ else
+ row_pointers[height-1-i]= &newimage[i*dib_bytesperrow];
+ }
+ png_write_image(png_ptr, row_pointers);
+
+ free(newimage);
+ newimage=NULL;
+ }
+ else {
+ for(i=0;i<height;i++) {
+ if(topdown)
+ row_pointers[i]= &bits[i*dib_bytesperrow];
+ else
+ row_pointers[height-1-i]= &bits[i*dib_bytesperrow];
+ }
+ png_write_image(png_ptr, row_pointers);
+ }
+
+ free((VOID*)row_pointers);
+ row_pointers=NULL;
+
+ if(d2p->software_id_string) {
+ text_ptr[0].key = "Software";
+ text_ptr[0].text = d2p->software_id_string;
+ text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
+ png_set_text(png_ptr, info_ptr, text_ptr, 1);
+ }
+
+ png_write_end(png_ptr, info_ptr);
+
+ rv=PNGD_E_SUCCESS;
abort:
- if(png_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
- if(fp) fclose(fp);
- if(row_pointers) free(row_pointers);
- if(newimage) free(newimage);
-
- // If we don't have an error message yet, use a
- // default one based on the code
- if(!lstrlen(d2p->common.errmsg))
- {
- pngd_get_error_message(rv,d2p->common.errmsg);
- }
- return rv;
+ if(png_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
+ if(fp) fclose(fp);
+ if(row_pointers) free(row_pointers);
+ if(newimage) free(newimage);
+
+ // If we don't have an error message yet, use a
+ // default one based on the code
+ if(!lstrlen(d2p->common.errmsg)) {
+ pngd_get_error_message(rv,d2p->common.errmsg,PNGDIB_ERRMSG_MAX);
+ }
+ return rv;
}
TCHAR* PNGDIB_DECL pngdib_get_version_string(void)
{
- return PNGDIB_SRC_VERSION_STRING;
+ return PNGDIB_SRC_VERSION_STRING;
}
int PNGDIB_DECL pngdib_get_version(void)
{
- return PNGDIB_SRC_VERSION;
+ return PNGDIB_SRC_VERSION;
}
PNGDIB* PNGDIB_DECL _pngdib_init(int structtype, int caller_header_vers)
{
- PNGDIB *qq = NULL;
-
- if(structtype==PNGD_ST_D2P)
- {
- struct d2p_struct *d2p;
-
- d2p = (struct d2p_struct *)calloc(sizeof(struct d2p_struct),1);
- if(d2p)
- {
- d2p->common.structtype = PNGD_ST_D2P;
- d2p->file_gamma_valid = 1;
- d2p->file_gamma = PNGDIB_DEFAULT_FILE_GAMMA;
- }
- qq=(PNGDIB*)d2p;
-
- }
- else if(structtype==PNGD_ST_P2D)
- {
- struct p2d_struct *p2d;
-
- p2d = (struct p2d_struct *)calloc(sizeof(struct p2d_struct),1);
- if(p2d)
- {
- p2d->common.structtype = PNGD_ST_P2D;
- }
- qq=(PNGDIB*)p2d;
- }
-
- // initialize common fields:
- if(qq)
- {
- qq->errmsg = calloc(PNGDIB_ERRMSG_MAX,sizeof(TCHAR));
- }
-
- return qq;
+ PNGDIB *qq = NULL;
+
+ if(structtype==PNGD_ST_D2P) {
+ struct d2p_struct *d2p;
+
+ d2p = (struct d2p_struct *)calloc(sizeof(struct d2p_struct),1);
+ if(d2p) {
+ d2p->common.structtype = PNGD_ST_D2P;
+ d2p->file_gamma_valid = 1;
+ d2p->file_gamma = PNGDIB_DEFAULT_FILE_GAMMA;
+ }
+ qq=(PNGDIB*)d2p;
+
+ }
+ else if(structtype==PNGD_ST_P2D) {
+ struct p2d_struct *p2d;
+
+ p2d = (struct p2d_struct *)calloc(sizeof(struct p2d_struct),1);
+ if(p2d) {
+ p2d->common.structtype = PNGD_ST_P2D;
+ }
+ qq=(PNGDIB*)p2d;
+ }
+
+ // initialize common fields:
+ if(qq) {
+ qq->errmsg = calloc(PNGDIB_ERRMSG_MAX,sizeof(TCHAR));
+ }
+
+ return qq;
}
int PNGDIB_DECL pngdib_d2p_set_dib(PNGDIB *qq,
- const BITMAPINFOHEADER* lpdib, int dibsize,
- const void* lpbits, int bitssize)
+ const BITMAPINFOHEADER* lpdib, int dibsize,
+ const void* lpbits, int bitssize)
{
- struct d2p_struct *d2p;
- if(qq->structtype!=PNGD_ST_D2P) return 0;
- d2p=(struct d2p_struct*)qq;
-
- d2p->pdib = lpdib;
- d2p->dibsize = dibsize;
- d2p->pbits = lpbits;
- d2p->bitssize = bitssize;
- return 1;
+ struct d2p_struct *d2p;
+ if(qq->structtype!=PNGD_ST_D2P) return 0;
+ d2p=(struct d2p_struct*)qq;
+
+ d2p->pdib = lpdib;
+ d2p->dibsize = dibsize;
+ d2p->pbits = lpbits;
+ d2p->bitssize = bitssize;
+ return 1;
}
void PNGDIB_DECL pngdib_d2p_set_interlace(PNGDIB *qq, int interlaced)
{
- struct d2p_struct *d2p;
- d2p=(struct d2p_struct*)qq;
- d2p->interlaced = interlaced;
+ struct d2p_struct *d2p;
+ d2p=(struct d2p_struct*)qq;
+ d2p->interlaced = interlaced;
}
int PNGDIB_DECL pngdib_d2p_set_png_filename(PNGDIB *qq, const TCHAR *fn)
{
- struct d2p_struct *d2p;
- d2p=(struct d2p_struct*)qq;
- d2p->output_filename = _tcsdup(fn);
- return (d2p->output_filename)?1:0;
+ struct d2p_struct *d2p;
+ d2p=(struct d2p_struct*)qq;
+ d2p->output_filename = _tcsdup(fn);
+ return (d2p->output_filename)?1:0;
}
int PNGDIB_DECL pngdib_d2p_set_software_id(PNGDIB *qq, const TCHAR *s)
{
- struct d2p_struct *d2p;
- int len;
+ struct d2p_struct *d2p;
+ int len;
- d2p=(struct d2p_struct*)qq;
- len= lstrlen(s);
+ d2p=(struct d2p_struct*)qq;
+ len= lstrlen(s);
- // The software id is never stored as UNICODE.
+ // The software id is never stored as UNICODE.
#ifdef _UNICODE
- d2p->software_id_string = calloc(len+10,1);
- _snprintf(d2p->software_id_string,len+10,"%S",s);
+ d2p->software_id_string = calloc(len+10,1);
+ StringCchPrintfA(d2p->software_id_string,len+10,"%S",s);
#else
- d2p->software_id_string = _strdup(s);
+ d2p->software_id_string = _strdup(s);
#endif
- return (d2p->output_filename)?1:0;
+ return (d2p->output_filename)?1:0;
}
void PNGDIB_DECL pngdib_d2p_set_gamma_label(PNGDIB *qq, int flag, double file_gamma)
{
- struct d2p_struct *d2p;
- d2p=(struct d2p_struct*)qq;
- d2p->file_gamma_valid = flag;
- d2p->file_gamma = file_gamma;
+ struct d2p_struct *d2p;
+ d2p=(struct d2p_struct*)qq;
+ d2p->file_gamma_valid = flag;
+ d2p->file_gamma = file_gamma;
}
int PNGDIB_DECL pngdib_done(PNGDIB *qq)
{
- struct d2p_struct *d2p;
- struct p2d_struct *p2d;
-
- if(!qq) return 0;
-
- if(qq->errmsg) free(qq->errmsg);
-
- switch(qq->structtype)
- {
- case PNGD_ST_D2P:
- d2p=(struct d2p_struct*)qq;
- if(d2p->output_filename) free(d2p->output_filename);
- if(d2p->software_id_string) free(d2p->software_id_string);
- free(d2p);
- return 1;
- case PNGD_ST_P2D:
- p2d=(struct p2d_struct*)qq;
- if(p2d->input_filename) free(p2d->input_filename);
- free(p2d);
- return 1;
- }
- return 0;
+ struct d2p_struct *d2p;
+ struct p2d_struct *p2d;
+
+ if(!qq) return 0;
+
+ if(qq->errmsg) free(qq->errmsg);
+
+ switch(qq->structtype) {
+ case PNGD_ST_D2P:
+ d2p=(struct d2p_struct*)qq;
+ if(d2p->output_filename) free(d2p->output_filename);
+ if(d2p->software_id_string) free(d2p->software_id_string);
+ free(d2p);
+ return 1;
+ case PNGD_ST_P2D:
+ p2d=(struct p2d_struct*)qq;
+ if(p2d->input_filename) free(p2d->input_filename);
+ free(p2d);
+ return 1;
+ }
+ return 0;
}
void PNGDIB_DECL pngdib_setcallback_malloc(PNGDIB *qq,
- pngdib_malloc_cb_type mallocfunc,
- pngdib_free_cb_type freefunc,
- pngdib_realloc_cb_type reallocfunc)
+ pngdib_malloc_cb_type mallocfunc,
+ pngdib_free_cb_type freefunc,
+ pngdib_realloc_cb_type reallocfunc)
{
- qq->malloc_function = mallocfunc;
- qq->free_function = freefunc;
- qq->realloc_function = reallocfunc;
+ qq->malloc_function = mallocfunc;
+ qq->free_function = freefunc;
+ qq->realloc_function = reallocfunc;
}
+void PNGDIB_DECL pngdib_setcallback_pngptrhook(PNGDIB *qq,
+ pngdib_pngptrhook_cb_type pngptrhookfn)
+{
+ qq->pngptrhook_function = pngptrhookfn;
+}
TCHAR* PNGDIB_DECL pngdib_get_error_msg(PNGDIB *qq)
{
- return qq->errmsg;
+ return qq->errmsg;
}
void PNGDIB_DECL pngdib_set_userdata(PNGDIB* qq, void* userdata)
{
- qq->userdata = userdata;
+ qq->userdata = userdata;
}
void* PNGDIB_DECL pngdib_get_userdata(PNGDIB* qq)
{
- return qq->userdata;
+ return qq->userdata;
}
int PNGDIB_DECL pngdib_p2d_set_png_filename(PNGDIB *qq, const TCHAR *fn)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- p2d->input_filename = _tcsdup(fn);
- p2d->input_method = 0;
- return (p2d->input_filename)?1:0;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ p2d->input_filename = _tcsdup(fn);
+ p2d->input_method = 0;
+ return (p2d->input_filename)?1:0;
}
void PNGDIB_DECL pngdib_p2d_set_png_memblk(PNGDIB *qq, const void *mem, int memsize)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- p2d->input_memblk = (unsigned char*)mem;
- p2d->input_method = 1;
- if(memsize>=0)
- p2d->input_memblk_size = memsize;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ p2d->input_memblk = (unsigned char*)mem;
+ p2d->input_method = 1;
+ if(memsize>=0)
+ p2d->input_memblk_size = memsize;
}
void PNGDIB_DECL pngdib_p2d_set_use_file_bg(PNGDIB *qq, int flag)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- p2d->use_file_bg_flag = flag;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ p2d->use_file_bg_flag = flag;
}
void PNGDIB_DECL pngdib_p2d_set_custom_bg(PNGDIB *qq, unsigned char r,
- unsigned char g, unsigned char b)
+ unsigned char g, unsigned char b)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- p2d->bgcolor.red = r;
- p2d->bgcolor.green = g;
- p2d->bgcolor.blue = b;
- p2d->use_custom_bg_flag = 1;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ p2d->bgcolor.red = r;
+ p2d->bgcolor.green = g;
+ p2d->bgcolor.blue = b;
+ p2d->use_custom_bg_flag = 1;
}
void PNGDIB_DECL pngdib_p2d_set_gamma_correction(PNGDIB *qq, int flag, double screen_gamma)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- p2d->screen_gamma = screen_gamma;
- p2d->gamma_correction = flag;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ p2d->screen_gamma = screen_gamma;
+ p2d->gamma_correction = flag;
}
int PNGDIB_DECL pngdib_p2d_get_dib(PNGDIB *qq,
- BITMAPINFOHEADER **ppdib, int *pdibsize)
+ BITMAPINFOHEADER **ppdib, int *pdibsize)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- *ppdib = p2d->pdib;
- if(pdibsize) *pdibsize = p2d->dibsize;
- return 1;
-}
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ *ppdib = p2d->pdib;
+ if(pdibsize) *pdibsize = p2d->dibsize;
+ return 1;
+}
int PNGDIB_DECL pngdib_p2d_get_dibbits(PNGDIB *qq, void **ppbits, int *pbitsoffset, int *pbitssize)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- *ppbits = p2d->pbits;
- if(pbitsoffset) *pbitsoffset = p2d->bits_offs;
- if(pbitssize) *pbitssize = p2d->bitssize;
- return 1;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ *ppbits = p2d->pbits;
+ if(pbitsoffset) *pbitsoffset = p2d->bits_offs;
+ if(pbitssize) *pbitssize = p2d->bitssize;
+ return 1;
}
int PNGDIB_DECL pngdib_p2d_get_palette(PNGDIB *qq, RGBQUAD **ppal, int *ppaloffset, int *ppalnumcolors)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- if(ppal) *ppal = p2d->palette;
- if(ppaloffset) *ppaloffset = p2d->palette_offs;
- if(ppalnumcolors) *ppalnumcolors = p2d->palette_colors;
- return 1;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ if(ppal) *ppal = p2d->palette;
+ if(ppaloffset) *ppaloffset = p2d->palette_offs;
+ if(ppalnumcolors) *ppalnumcolors = p2d->palette_colors;
+ return 1;
}
int PNGDIB_DECL pngdib_p2d_get_colortype(PNGDIB *qq)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- return p2d->color_type;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ return p2d->color_type;
}
int PNGDIB_DECL pngdib_p2d_get_bitspersample(PNGDIB *qq)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- return p2d->bits_per_sample;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ return p2d->bits_per_sample;
}
int PNGDIB_DECL pngdib_p2d_get_bitsperpixel(PNGDIB *qq)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- return p2d->bits_per_pixel;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ return p2d->bits_per_pixel;
}
int PNGDIB_DECL pngdib_p2d_get_samplesperpixel(PNGDIB *qq)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- return p2d->bits_per_pixel/p2d->bits_per_sample;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ return p2d->bits_per_pixel/p2d->bits_per_sample;
}
int PNGDIB_DECL pngdib_p2d_get_interlace(PNGDIB *qq)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- return p2d->interlace;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ return p2d->interlace;
}
int PNGDIB_DECL pngdib_p2d_get_density(PNGDIB *qq, int *pres_x, int *pres_y, int *pres_units)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- if(p2d->res_valid)
- {
- *pres_x = p2d->res_x;
- *pres_y = p2d->res_y;
- *pres_units = p2d->res_units;
- return 1;
- }
- *pres_x = 1;
- *pres_y = 1;
- *pres_units = 0;
- return 0;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ if(p2d->res_valid) {
+ *pres_x = p2d->res_x;
+ *pres_y = p2d->res_y;
+ *pres_units = p2d->res_units;
+ return 1;
+ }
+ *pres_x = 1;
+ *pres_y = 1;
+ *pres_units = 0;
+ return 0;
}
int PNGDIB_DECL pngdib_p2d_get_file_gamma(PNGDIB *qq, double *pgamma)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
- if(p2d->gamma_returned)
- {
- *pgamma = p2d->file_gamma;
- return 1;
- }
- return 0;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+ if(p2d->gamma_returned) {
+ *pgamma = p2d->file_gamma;
+ return 1;
+ }
+ return 0;
}
int PNGDIB_DECL pngdib_p2d_get_bgcolor(PNGDIB *qq, unsigned char *pr, unsigned char *pg, unsigned char *pb)
{
- struct p2d_struct *p2d;
- p2d=(struct p2d_struct*)qq;
-
- if(p2d->bgcolor_returned)
- {
- *pr = p2d->bgcolor.red;
- *pg = p2d->bgcolor.green;
- *pb = p2d->bgcolor.blue;
- return 1;
- }
- return 0;
+ struct p2d_struct *p2d;
+ p2d=(struct p2d_struct*)qq;
+
+ if(p2d->bgcolor_returned) {
+ *pr = p2d->bgcolor.red;
+ *pg = p2d->bgcolor.green;
+ *pb = p2d->bgcolor.blue;
+ return 1;
+ }
+ return 0;
}
void PNGDIB_DECL pngdib_set_dibalpha32(PNGDIB *qq, int flag)
{
- qq->dib_alpha32 = flag;
+ qq->dib_alpha32 = flag;
}
@@ -1656,169 +1446,157 @@ void PNGDIB_DECL pngdib_set_dibalpha32(PNGDIB *qq, int flag)
static void* PNGDIB_DECL globalalloc_callback(void *userdata, int memblksize)
{
- return (void*)GlobalAlloc(GPTR,memblksize);
+ return (void*)GlobalAlloc(GPTR,memblksize);
}
static void PNGDIB_DECL globalfree_callback(void *userdata, void *memblk)
{
- GlobalFree((HGLOBAL)memblk);
+ GlobalFree((HGLOBAL)memblk);
}
static void* PNGDIB_DECL heapalloc_callback(void *userdata, int memblksize)
{
- return HeapAlloc((HANDLE)userdata,HEAP_ZERO_MEMORY,memblksize);
+ return HeapAlloc((HANDLE)userdata,HEAP_ZERO_MEMORY,memblksize);
}
static void PNGDIB_DECL heapfree_callback(void *userdata, void *memblk)
{
- HeapFree((HANDLE)userdata,0,memblk);
+ HeapFree((HANDLE)userdata,0,memblk);
}
int read_png_to_dib(PNGD_P2DINFO *p2dp)
{
- PNGDIB *qq;
- int errcode;
- char *msg;
- HANDLE heap;
- int use_heapalloc;
- int imginfo;
-
- imginfo=0;
- use_heapalloc=0;
-
-
- qq=pngdib_p2d_init();
- if(!qq) return PNGD_E_NOMEM;
-
-
- // fields through errmsg must exist
- if(p2dp->structsize<48) return PNGD_E_VERSION;
-
- // try to be somewhat backward-compatible
- if(p2dp->structsize>=88)
- {
- imginfo=1;
- }
-
- if(p2dp->structsize>=96)
- {
- if(p2dp->flags & PNGD_USE_HEAPALLOC)
- {
- use_heapalloc=1;
- heap = p2dp->heap;
- if(!heap) heap = GetProcessHeap();
- }
- }
-
- if(use_heapalloc)
- {
- pngdib_set_userdata(qq,(void*)heap);
- pngdib_setcallback_malloc(qq,heapalloc_callback,heapfree_callback,NULL);
- }
- else
- {
- pngdib_setcallback_malloc(qq,globalalloc_callback,globalfree_callback,NULL);
- }
-
- pngdib_p2d_set_png_filename(qq,p2dp->pngfn);
-
- pngdib_p2d_set_gamma_correction(qq,(p2dp->flags&PNGD_GAMMA_CORRECTION)?1:0,PNGDIB_DEFAULT_SCREEN_GAMMA);
-
- if(p2dp->flags&PNGD_USE_BKGD)
- pngdib_p2d_set_use_file_bg(qq,1);
-
-
- if(p2dp->flags&PNGD_USE_CUSTOM_BG)
- {
- pngdib_p2d_set_custom_bg(qq,p2dp->bgcolor.red,
- p2dp->bgcolor.green,p2dp->bgcolor.blue);
- }
-
- if(p2dp->flags&PNGD_DIB_ALPHA32)
- pngdib_set_dibalpha32(qq,1);
-
- errcode=pngdib_p2d_run(qq);
-
- if(!errcode)
- {
-
- pngdib_p2d_get_dib(qq,&p2dp->lpdib, &p2dp->dibsize);
- pngdib_p2d_get_dibbits(qq,&p2dp->lpbits, &p2dp->bits_offs, NULL);
- pngdib_p2d_get_palette(qq,&p2dp->palette, &p2dp->palette_offs, &p2dp->palette_colors);
-
- if(imginfo)
- {
- p2dp->color_type = pngdib_p2d_get_colortype(qq);
- p2dp->bits_per_sample = pngdib_p2d_get_bitspersample(qq);
- p2dp->interlace = pngdib_p2d_get_interlace(qq);
- p2dp->bits_per_pixel = pngdib_p2d_get_bitsperpixel(qq);
- if(pngdib_p2d_get_file_gamma(qq, &p2dp->file_gamma))
- {
- p2dp->flags |= PNGD_GAMMA_RETURNED;
- }
- if(pngdib_p2d_get_density(qq, &p2dp->res_x, &p2dp->res_y, &p2dp->res_units))
- {
- p2dp->flags |= PNGD_RES_RETURNED;
- }
- if(pngdib_p2d_get_bgcolor(qq, &p2dp->bgcolor.red, &p2dp->bgcolor.green,
- &p2dp->bgcolor.blue))
- {
- p2dp->flags |= PNGD_BG_RETURNED;
- }
- }
- }
-
- if(p2dp->errmsg)
- {
- msg=pngdib_get_error_msg(qq);
- lstrcpyn(p2dp->errmsg,msg,100);
- }
-
- pngdib_done(qq);
-
- return errcode;
+ PNGDIB *qq;
+ int errcode;
+ char *msg;
+ HANDLE heap;
+ int use_heapalloc;
+ int imginfo;
+
+ imginfo=0;
+ use_heapalloc=0;
+
+
+ qq=pngdib_p2d_init();
+ if(!qq) return PNGD_E_NOMEM;
+
+
+ // fields through errmsg must exist
+ if(p2dp->structsize<48) return PNGD_E_VERSION;
+
+ // try to be somewhat backward-compatible
+ if(p2dp->structsize>=88) {
+ imginfo=1;
+ }
+
+ if(p2dp->structsize>=96) {
+ if(p2dp->flags & PNGD_USE_HEAPALLOC) {
+ use_heapalloc=1;
+ heap = p2dp->heap;
+ if(!heap) heap = GetProcessHeap();
+ }
+ }
+
+ if(use_heapalloc) {
+ pngdib_set_userdata(qq,(void*)heap);
+ pngdib_setcallback_malloc(qq,heapalloc_callback,heapfree_callback,NULL);
+ }
+ else {
+ pngdib_setcallback_malloc(qq,globalalloc_callback,globalfree_callback,NULL);
+ }
+
+ pngdib_p2d_set_png_filename(qq,p2dp->pngfn);
+
+ pngdib_p2d_set_gamma_correction(qq,(p2dp->flags&PNGD_GAMMA_CORRECTION)?1:0,PNGDIB_DEFAULT_SCREEN_GAMMA);
+
+ if(p2dp->flags&PNGD_USE_BKGD)
+ pngdib_p2d_set_use_file_bg(qq,1);
+
+
+ if(p2dp->flags&PNGD_USE_CUSTOM_BG) {
+ pngdib_p2d_set_custom_bg(qq,p2dp->bgcolor.red,
+ p2dp->bgcolor.green,p2dp->bgcolor.blue);
+ }
+
+ if(p2dp->flags&PNGD_DIB_ALPHA32)
+ pngdib_set_dibalpha32(qq,1);
+
+ errcode=pngdib_p2d_run(qq);
+
+ if(!errcode) {
+
+ pngdib_p2d_get_dib(qq,&p2dp->lpdib, &p2dp->dibsize);
+ pngdib_p2d_get_dibbits(qq,&p2dp->lpbits, &p2dp->bits_offs, NULL);
+ pngdib_p2d_get_palette(qq,&p2dp->palette, &p2dp->palette_offs, &p2dp->palette_colors);
+
+ if(imginfo) {
+ p2dp->color_type = pngdib_p2d_get_colortype(qq);
+ p2dp->bits_per_sample = pngdib_p2d_get_bitspersample(qq);
+ p2dp->interlace = pngdib_p2d_get_interlace(qq);
+ p2dp->bits_per_pixel = pngdib_p2d_get_bitsperpixel(qq);
+ if(pngdib_p2d_get_file_gamma(qq, &p2dp->file_gamma)) {
+ p2dp->flags |= PNGD_GAMMA_RETURNED;
+ }
+ if(pngdib_p2d_get_density(qq, &p2dp->res_x, &p2dp->res_y, &p2dp->res_units)) {
+ p2dp->flags |= PNGD_RES_RETURNED;
+ }
+ if(pngdib_p2d_get_bgcolor(qq, &p2dp->bgcolor.red, &p2dp->bgcolor.green,
+ &p2dp->bgcolor.blue))
+ {
+ p2dp->flags |= PNGD_BG_RETURNED;
+ }
+ }
+ }
+
+ if(p2dp->errmsg) {
+ msg=pngdib_get_error_msg(qq);
+ lstrcpyn(p2dp->errmsg,msg,PNGDIB_ERRMSG_MAX);
+ }
+
+ pngdib_done(qq);
+
+ return errcode;
}
int write_dib_to_png(PNGD_D2PINFO *d2pp)
{
- PNGDIB *qq;
- int errcode;
- char *msg;
+ PNGDIB *qq;
+ int errcode;
+ char *msg;
- if(d2pp->structsize != sizeof(PNGD_D2PINFO)) return PNGD_E_VERSION;
+ if(d2pp->structsize != sizeof(PNGD_D2PINFO)) return PNGD_E_VERSION;
- qq=pngdib_d2p_init();
- if(!qq) return PNGD_E_NOMEM;
- pngdib_d2p_set_dib(qq,d2pp->lpdib,d2pp->dibsize,
- d2pp->lpbits,d2pp->bitssize);
- if(d2pp->flags&PNGD_INTERLACED)
- pngdib_d2p_set_interlace(qq,1);
+ qq=pngdib_d2p_init();
+ if(!qq) return PNGD_E_NOMEM;
+ pngdib_d2p_set_dib(qq,d2pp->lpdib,d2pp->dibsize,
+ d2pp->lpbits,d2pp->bitssize);
+ if(d2pp->flags&PNGD_INTERLACED)
+ pngdib_d2p_set_interlace(qq,1);
- if(d2pp->flags&PNGD_NO_GAMMA_LABEL)
- pngdib_d2p_set_gamma_label(qq,0,0.0);
- else
- pngdib_d2p_set_gamma_label(qq,1,PNGDIB_DEFAULT_FILE_GAMMA);
+ if(d2pp->flags&PNGD_NO_GAMMA_LABEL)
+ pngdib_d2p_set_gamma_label(qq,0,0.0);
+ else
+ pngdib_d2p_set_gamma_label(qq,1,PNGDIB_DEFAULT_FILE_GAMMA);
- pngdib_d2p_set_png_filename(qq,d2pp->pngfn);
+ pngdib_d2p_set_png_filename(qq,d2pp->pngfn);
- if(d2pp->software)
- pngdib_d2p_set_software_id(qq, d2pp->software);
+ if(d2pp->software)
+ pngdib_d2p_set_software_id(qq, d2pp->software);
- if(d2pp->flags&PNGD_DIB_ALPHA32)
- pngdib_set_dibalpha32(qq,1);
+ if(d2pp->flags&PNGD_DIB_ALPHA32)
+ pngdib_set_dibalpha32(qq,1);
- errcode=pngdib_d2p_run(qq);
+ errcode=pngdib_d2p_run(qq);
- if(d2pp->errmsg)
- {
- msg=pngdib_get_error_msg(qq);
- lstrcpyn(d2pp->errmsg,msg,100);
- }
+ if(d2pp->errmsg) {
+ msg=pngdib_get_error_msg(qq);
+ lstrcpyn(d2pp->errmsg,msg,PNGDIB_ERRMSG_MAX);
+ }
- pngdib_done(qq);
- return errcode;
+ pngdib_done(qq);
+ return errcode;
}
#endif // PNGDIB_V2COMPATIBLE
diff --git a/src/apps/mplayerc/pngdib.h b/src/apps/mplayerc/pngdib.h
index a4e5ff66e..e492e4e73 100644
--- a/src/apps/mplayerc/pngdib.h
+++ b/src/apps/mplayerc/pngdib.h
@@ -20,7 +20,7 @@ extern "C" {
#define PNGDIB_V2COMPATIBLE 1
#endif
-#define PNGDIB_HEADER_VERSION 30001
+#define PNGDIB_HEADER_VERSION 30002
#define PNGDIB_DEFAULT_SCREEN_GAMMA 2.20000
@@ -47,50 +47,46 @@ extern "C" {
#if (PNGDIB_V2COMPATIBLE) || defined(PNGDIB_INTERNALS)
- struct PNGD_COLOR_struct
- {
- unsigned char red, green, blue, reserved;
- };
+struct PNGD_COLOR_struct {
+ unsigned char red, green, blue, reserved;
+};
#endif
#if PNGDIB_V2COMPATIBLE
- typedef struct PNGD_D2PINFO_struct
- {
- DWORD structsize; // sizeof(PNGD_D2PINFO)
- DWORD flags;
+typedef struct PNGD_D2PINFO_struct {
+ DWORD structsize; // sizeof(PNGD_D2PINFO)
+ DWORD flags;
#define PNGD_INTERLACED 0x00000001
#define PNGD_NO_GAMMA_LABEL 0x00000002
#define PNGD_DIB_ALPHA32 0x00000010
- char* pngfn; // PNG filename to write
+ char* pngfn; // PNG filename to write
- LPBITMAPINFOHEADER lpdib;
- int dibsize; // can be 0
+ LPBITMAPINFOHEADER lpdib;
+ int dibsize; // can be 0
- VOID* lpbits; // can be NULL
- int bitssize; // can be 0
+ VOID* lpbits; // can be NULL
+ int bitssize; // can be 0
- char* software; // (NULL==don't include)
+ char* software; // (NULL==don't include)
// added in v2.0
- char* errmsg; // user can set to null or 100-char buffer
- } PNGD_D2PINFO;
+ char* errmsg; // user can set to null or 100-char buffer
+} PNGD_D2PINFO;
- typedef struct PNGD_IMAGEINFO_struct
- {
- DWORD structsize; // sizeof(PNGD_IMAGEINFO)
- DWORD flags;
+typedef struct PNGD_IMAGEINFO_struct {
+ DWORD structsize; // sizeof(PNGD_IMAGEINFO)
+ DWORD flags;
- } PNGD_IMAGEINFO;
+} PNGD_IMAGEINFO;
- typedef struct PNGD_P2DINFO_struct
- {
- DWORD structsize; // sizeof(PNGD_P2DINFO)
+typedef struct PNGD_P2DINFO_struct {
+ DWORD structsize; // sizeof(PNGD_P2DINFO)
- DWORD flags; // combination of below:
+ DWORD flags; // combination of below:
#define PNGD_USE_BKGD 0x00000001
#define PNGD_USE_CUSTOM_BG 0x00000002
#define PNGD_GAMMA_CORRECTION 0x00000004
@@ -101,47 +97,48 @@ extern "C" {
#define PNGD_RES_RETURNED 0x00020000 // set if xres,yres,res_units are valid
#define PNGD_GAMMA_RETURNED 0x00040000 // set if file_gamma is valid
- char* pngfn; // PNG filename to read
+ char* pngfn; // PNG filename to read
- LPBITMAPINFOHEADER lpdib; // return value only
- int dibsize; // return value only
- int palette_offs; // return value only
- int bits_offs; // return value only
- RGBQUAD* palette; // return value only
- int palette_colors; // return value only
- VOID* lpbits; // return value only
+ LPBITMAPINFOHEADER lpdib; // return value only
+ int dibsize; // return value only
+ int palette_offs; // return value only
+ int bits_offs; // return value only
+ RGBQUAD* palette; // return value only
+ int palette_colors; // return value only
+ VOID* lpbits; // return value only
// added in v2.0 (size=48)
- struct PNGD_COLOR_struct bgcolor; // IN OUT
- char* errmsg; // user can set to null or 100-char buffer
+ struct PNGD_COLOR_struct bgcolor; // IN OUT
+ char* errmsg; // user can set to null or 100-char buffer
// added in v2.1 (size=88)
- int color_type;
- int bits_per_sample;
- int bits_per_pixel;
- int interlace;
- int res_x,res_y;
- int res_units;
- int reserved1;
- double file_gamma;
+ int color_type;
+ int bits_per_sample;
+ int bits_per_pixel;
+ int interlace;
+ int res_x,res_y;
+ int res_units;
+ int reserved1;
+ double file_gamma;
// added in v2.2 (size=96)
- HANDLE heap;
- int reserved2;
+ HANDLE heap;
+ int reserved2;
- } PNGD_P2DINFO;
+} PNGD_P2DINFO;
- int read_png_to_dib(PNGD_P2DINFO *p2dinfo);
- int write_dib_to_png(PNGD_D2PINFO *d2pinfo);
+int read_png_to_dib(PNGD_P2DINFO *p2dinfo);
+int write_dib_to_png(PNGD_D2PINFO *d2pinfo);
#endif // PNGDIB_V2COMPATIBLE
// public definitions
- typedef void* (PNGDIB_DECL *pngdib_malloc_cb_type)(void *userdata, int memblksize);
- typedef void (PNGDIB_DECL *pngdib_free_cb_type)(void *userdata, void *memblk);
- typedef void* (PNGDIB_DECL *pngdib_realloc_cb_type)(void *userdata, void *memblk, int memblksize);
+typedef void* (PNGDIB_DECL *pngdib_malloc_cb_type)(void *userdata, int memblksize);
+typedef void (PNGDIB_DECL *pngdib_free_cb_type)(void *userdata, void *memblk);
+typedef void* (PNGDIB_DECL *pngdib_realloc_cb_type)(void *userdata, void *memblk, int memblksize);
+typedef void (PNGDIB_DECL *pngdib_pngptrhook_cb_type)(void *userdata, void *pngptr);
- struct pngdib_common_struct;
- typedef struct pngdib_common_struct PNGDIB;
+struct pngdib_common_struct;
+typedef struct pngdib_common_struct PNGDIB;
#define PNGD_ST_D2P 1
@@ -155,70 +152,65 @@ extern "C" {
#define PNGDIB_ERRMSG_MAX 200
- struct pngdib_common_struct
- {
- int structtype;
- void *userdata;
- TCHAR *errmsg;
- pngdib_malloc_cb_type malloc_function;
- pngdib_free_cb_type free_function;
- pngdib_realloc_cb_type realloc_function;
- int dib_alpha32;
- };
-
- struct d2p_struct
- {
- struct pngdib_common_struct common;
-
- const BITMAPINFOHEADER* pdib;
- int dibsize;
- const void* pbits;
- int bitssize;
- int interlaced;
- TCHAR* output_filename;
- char* software_id_string;
- int file_gamma_valid;
- double file_gamma;
- };
-
- struct p2d_struct
- {
- struct pngdib_common_struct common;
-
- int input_method; // 0=filename, 1=memory
- TCHAR* input_filename;
- unsigned char* input_memblk;
- int input_memblk_size;
- int input_memblk_curpos;
-
- int use_file_bg_flag;
- int use_custom_bg_flag;
- struct PNGD_COLOR_struct bgcolor;
- int gamma_correction; // should we gamma correct (using screen_gamma)?
- double screen_gamma;
-
- BITMAPINFOHEADER* pdib;
- int dibsize;
- int palette_offs;
- int bits_offs;
- int bitssize;
- RGBQUAD* palette;
- int palette_colors;
- void* pbits;
- int color_type;
- int bits_per_sample;
- int bits_per_pixel;
- int interlace;
- int res_x,res_y;
- int res_units;
- int res_valid; // are res_x, res_y, res_units valid?
- double file_gamma;
- int gamma_returned; // set if we know the file gamma
- int bgcolor_returned;
- };
-
-#undef _PNGD_DEFINE_COMMON_FIELDS
-
+struct pngdib_common_struct {
+ int structtype;
+ void *userdata;
+ TCHAR *errmsg;
+ pngdib_malloc_cb_type malloc_function;
+ pngdib_free_cb_type free_function;
+ pngdib_realloc_cb_type realloc_function;
+ pngdib_pngptrhook_cb_type pngptrhook_function;
+ int dib_alpha32;
+};
+
+struct d2p_struct {
+ struct pngdib_common_struct common;
+
+ const BITMAPINFOHEADER* pdib;
+ int dibsize;
+ const void* pbits;
+ int bitssize;
+ int interlaced;
+ TCHAR* output_filename;
+ char* software_id_string;
+ int file_gamma_valid;
+ double file_gamma;
+};
+
+struct p2d_struct {
+ struct pngdib_common_struct common;
+
+ int input_method; // 0=filename, 1=memory
+ TCHAR* input_filename;
+ unsigned char* input_memblk;
+ int input_memblk_size;
+ int input_memblk_curpos;
+
+ int use_file_bg_flag;
+ int use_custom_bg_flag;
+ struct PNGD_COLOR_struct bgcolor;
+ int gamma_correction; // should we gamma correct (using screen_gamma)?
+ double screen_gamma;
+
+ BITMAPINFOHEADER* pdib;
+ int dibsize;
+ int palette_offs;
+ int bits_offs;
+ int bitssize;
+ RGBQUAD* palette;
+ int palette_colors;
+ void* pbits;
+ int color_type;
+ int bits_per_sample;
+ int bits_per_pixel;
+ int interlace;
+ int res_x,res_y;
+ int res_units;
+ int res_valid; // are res_x, res_y, res_units valid?
+ double file_gamma;
+ int gamma_returned; // set if we know the file gamma
+ int bgcolor_returned;
+};
#endif // PNGDIB_INTERNALS
@@ -226,16 +218,16 @@ extern "C" {
#define pngdib_d2p_init() _pngdib_init(PNGD_ST_D2P,PNGDIB_HEADER_VERSION)
- PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_dib(PNGDIB *d2p,
- const BITMAPINFOHEADER* pdib, int dibsize,
- const void* pbits, int bitssize);
+PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_dib(PNGDIB *d2p,
+ const BITMAPINFOHEADER* pdib, int dibsize,
+ const void* pbits, int bitssize);
- PNGDIB_EXT void PNGDIB_DECL pngdib_d2p_set_interlace(PNGDIB *d2p, int interlaced);
- PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_png_filename(PNGDIB *d2p, const TCHAR *fn);
- PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_software_id(PNGDIB *d2p, const TCHAR *s);
- PNGDIB_EXT void PNGDIB_DECL pngdib_d2p_set_gamma_label(PNGDIB *d2p, int flag, double file_gamma);
+PNGDIB_EXT void PNGDIB_DECL pngdib_d2p_set_interlace(PNGDIB *d2p, int interlaced);
+PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_png_filename(PNGDIB *d2p, const TCHAR *fn);
+PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_set_software_id(PNGDIB *d2p, const TCHAR *s);
+PNGDIB_EXT void PNGDIB_DECL pngdib_d2p_set_gamma_label(PNGDIB *d2p, int flag, double file_gamma);
- PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_run(PNGDIB *d2p);
+PNGDIB_EXT int PNGDIB_DECL pngdib_d2p_run(PNGDIB *d2p);
////////////
@@ -243,50 +235,53 @@ extern "C" {
#define pngdib_p2d_init() _pngdib_init(PNGD_ST_P2D,PNGDIB_HEADER_VERSION)
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_set_png_filename(PNGDIB *p2d, const TCHAR *fn);
- PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_png_memblk(PNGDIB *p2d, const void *mem, int memsize);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_set_png_filename(PNGDIB *p2d, const TCHAR *fn);
+PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_png_memblk(PNGDIB *p2d, const void *mem, int memsize);
- PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_use_file_bg(PNGDIB *p2d, int flag);
- PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_custom_bg(PNGDIB *p2d, unsigned char r,
- unsigned char g, unsigned char b);
- PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_gamma_correction(PNGDIB *p2d, int flag, double screen_gamma);
+PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_use_file_bg(PNGDIB *p2d, int flag);
+PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_custom_bg(PNGDIB *p2d, unsigned char r,
+ unsigned char g, unsigned char b);
+PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_set_gamma_correction(PNGDIB *p2d, int flag, double screen_gamma);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_run(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_run(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_dib(PNGDIB *p2d, BITMAPINFOHEADER **ppdib, int *pdibsize);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_dibbits(PNGDIB *p2d, void **ppbits, int *pbitsoffset, int *pbitssize);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_palette(PNGDIB *p2d, RGBQUAD **ppal, int *ppaloffset, int *ppalnumcolors);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_dib(PNGDIB *p2d, BITMAPINFOHEADER **ppdib, int *pdibsize);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_dibbits(PNGDIB *p2d, void **ppbits, int *pbitsoffset, int *pbitssize);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_palette(PNGDIB *p2d, RGBQUAD **ppal, int *ppaloffset, int *ppalnumcolors);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_colortype(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bitspersample(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bitsperpixel(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_samplesperpixel(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_interlace(PNGDIB *p2d);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_density(PNGDIB *p2d, int *pres_x, int *pres_y, int *pres_units);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_file_gamma(PNGDIB *p2d, double *pgamma);
- PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bgcolor(PNGDIB *p2d, unsigned char *pr, unsigned char *pg, unsigned char *pb);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_colortype(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bitspersample(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bitsperpixel(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_samplesperpixel(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_interlace(PNGDIB *p2d);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_density(PNGDIB *p2d, int *pres_x, int *pres_y, int *pres_units);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_file_gamma(PNGDIB *p2d, double *pgamma);
+PNGDIB_EXT int PNGDIB_DECL pngdib_p2d_get_bgcolor(PNGDIB *p2d, unsigned char *pr, unsigned char *pg, unsigned char *pb);
- PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_free_dib(PNGDIB *p2d, BITMAPINFOHEADER *pdib);
+PNGDIB_EXT void PNGDIB_DECL pngdib_p2d_free_dib(PNGDIB *p2d, BITMAPINFOHEADER *pdib);
//////////// common functions
- PNGDIB_EXT PNGDIB* PNGDIB_DECL _pngdib_init(int structtype, int caller_header_vers);
+PNGDIB_EXT PNGDIB* PNGDIB_DECL _pngdib_init(int structtype, int caller_header_vers);
+
+PNGDIB_EXT int PNGDIB_DECL pngdib_done(PNGDIB *xx);
- PNGDIB_EXT int PNGDIB_DECL pngdib_done(PNGDIB *xx);
+PNGDIB_EXT void PNGDIB_DECL pngdib_setcallback_malloc(PNGDIB *xx,
+ pngdib_malloc_cb_type mallocfunc,
+ pngdib_free_cb_type freefunc,
+ pngdib_realloc_cb_type reallocfunc);
- PNGDIB_EXT void PNGDIB_DECL pngdib_setcallback_malloc(PNGDIB *xx,
- pngdib_malloc_cb_type mallocfunc,
- pngdib_free_cb_type freefunc,
- pngdib_realloc_cb_type reallocfunc);
+PNGDIB_EXT void PNGDIB_DECL pngdib_setcallback_pngptrhook(PNGDIB *xx,
+ pngdib_pngptrhook_cb_type pngptrhookfn);
- PNGDIB_EXT void PNGDIB_DECL pngdib_set_userdata(PNGDIB *xx, void *userdata);
- PNGDIB_EXT void* PNGDIB_DECL pngdib_get_userdata(PNGDIB *xx);
- PNGDIB_EXT TCHAR* PNGDIB_DECL pngdib_get_error_msg(PNGDIB *xx);
+PNGDIB_EXT void PNGDIB_DECL pngdib_set_userdata(PNGDIB *xx, void *userdata);
+PNGDIB_EXT void* PNGDIB_DECL pngdib_get_userdata(PNGDIB *xx);
+PNGDIB_EXT TCHAR* PNGDIB_DECL pngdib_get_error_msg(PNGDIB *xx);
- PNGDIB_EXT TCHAR* PNGDIB_DECL pngdib_get_version_string(void);
- PNGDIB_EXT int PNGDIB_DECL pngdib_get_version(void);
+PNGDIB_EXT TCHAR* PNGDIB_DECL pngdib_get_version_string(void);
+PNGDIB_EXT int PNGDIB_DECL pngdib_get_version(void);
- PNGDIB_EXT void PNGDIB_DECL pngdib_set_dibalpha32(PNGDIB *xx, int flag);
+PNGDIB_EXT void PNGDIB_DECL pngdib_set_dibalpha32(PNGDIB *xx, int flag);
////////////