Example #1
0
/*
====================
PNG_OpenLibrary

Try to load the PNG DLL
====================
*/
qboolean PNG_OpenLibrary (void)
{
#ifndef LINK_TO_LIBPNG
	const char* dllnames [] =
	{
#if WIN32
        "libpng16.dll",
        "libpng16-16.dll",
		"libpng15-15.dll",
		"libpng15.dll",
		"libpng14-14.dll",
		"libpng14.dll",
		"libpng12.dll",
#elif defined(MACOSX)
        "libpng16.16.dylib",
		"libpng15.15.dylib",
		"libpng14.14.dylib",
		"libpng12.0.dylib",
#else
        "libpng16.so",
        "libpng16.so.16",
		"libpng15.so.15", // WTF libtool guidelines anyone?
		"libpng14.so.14", // WTF libtool guidelines anyone?
		"libpng12.so.0",
		"libpng.so", // FreeBSD
#endif
		NULL
	};

	// Already loaded?
	if (png_dll)
		return true;

	// Load the DLL
	if(!Sys_LoadLibrary (dllnames, &png_dll, pngfuncs))
		return false;
	if(qpng_access_version_number() / 100 >= 104)
		if(!Sys_LoadLibrary (dllnames, &png14_dll, png14funcs))
		{
			Sys_UnloadLibrary (&png_dll);
			return false;
		}
#endif
	return true;
}
Example #2
0
unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize, int *miplevel)
{
	unsigned int c;
	unsigned int	y;
	void *png, *pnginfo;
	unsigned char *imagedata = NULL;
	unsigned char ioBuffer[8192];

	// FIXME: register an error handler so that abort() won't be called on error

	// No DLL = no PNGs
	if (!png_dll)
		return NULL;

	if(qpng_sig_cmp(raw, 0, filesize))
		return NULL;
	png = (void *)qpng_create_read_struct(
		(qpng_access_version_number() / 100 == 102) ? PNG_LIBPNG_VER_STRING_12 :
		(qpng_access_version_number() / 100 == 104) ? PNG_LIBPNG_VER_STRING_14 :
		PNG_LIBPNG_VER_STRING_15, // nasty hack... whatever
		0, PNG_error_fn, PNG_warning_fn
	);
	if(!png)
		return NULL;

	// this must be memset before the setjmp error handler, because it relies
	// on the fields in this struct for cleanup
	memset(&my_png, 0, sizeof(my_png));

	// NOTE: this relies on jmp_buf being the first thing in the png structure
	// created by libpng! (this is correct for libpng 1.2.x)
	if (setjmp(qpng_jmpbuf(png)))
	{
		if (my_png.Data)
			Mem_Free(my_png.Data);
		my_png.Data = NULL;
		if (my_png.FRowPtrs)
			Mem_Free(my_png.FRowPtrs);
		my_png.FRowPtrs = NULL;
		qpng_destroy_read_struct(&png, &pnginfo, 0);
		return NULL;
	}
	//

	pnginfo = qpng_create_info_struct(png);
	if(!pnginfo)
	{
		qpng_destroy_read_struct(&png, &pnginfo, 0);
		return NULL;
	}
	qpng_set_sig_bytes(png, 0);

	my_png.tmpBuf = raw;
	my_png.tmpBuflength = filesize;
	my_png.tmpi = 0;
	//my_png.Data		= NULL;
	//my_png.FRowPtrs	= NULL;
	//my_png.Height		= 0;
	//my_png.Width		= 0;
	my_png.ColorType	= PNG_COLOR_TYPE_RGB;
	//my_png.Interlace	= 0;
	//my_png.Compression	= 0;
	//my_png.Filter		= 0;
	qpng_set_read_fn(png, ioBuffer, PNG_fReadData);
	qpng_read_info(png, pnginfo);
	qpng_get_IHDR(png, pnginfo, &my_png.Width, &my_png.Height,&my_png.BitDepth, &my_png.ColorType, &my_png.Interlace, &my_png.Compression, &my_png.Filter);

	// this check guards against pngconf.h with unsigned int *width/height parameters on big endian systems by detecting the strange values and shifting them down 32bits
	// (if it's little endian the unwritten bytes are the most significant
	//  ones and we don't worry about that)
	//
	// this is only necessary because of retarded 64bit png_uint_32 types in libpng 1.2, which can (conceivably) vary by platform
#if LONG_MAX > 4000000000
	if (my_png.Width > LONG_MAX || my_png.Height > LONG_MAX)
	{
		my_png.Width >>= 32;
		my_png.Height >>= 32;
	}