Solid Fluid System Solutions  
Home Software About Hardware Firmware
Document Icon LibPNG
Current Document Icon Modifications
Document Icon ToPNG
Document Icon FromPNG

Modifications made to the LibPNG library

The prototypes for the "file side" of the PNG Library were mentioned as being modified;

void PNGAPI png_buffered_read_data PNGARG((png_structp png_ptr,png_bytep data, png_size_t length));
void PNGAPI png_buffered_write_data PNGARG((png_structp png_ptr,png_bytep data, png_size_t length));
void PNGAPI png_buffered_flush_data PNGARG((png_structp png_ptr));

The implementations of these functions are shown below;

pbufferdst.cpp

#include "png.h"
#include "pngbufferdst.h"
#include "..\ImgAlloc.h"

#define ALLOC_SIZE	4096

void PNGAPI
png_buffered_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
	if(png_ptr == NULL) return;

	buffered_write_info* pInfo = (buffered_write_info*) png_ptr->io_ptr;

	unsigned long RequiredSize;
	if(pInfo->pBuf == NULL)
	{
		pInfo->Ptr = 0;
		pInfo->Size = 0;
		RequiredSize = length;

		while(RequiredSize > pInfo->Size) 
		 pInfo->Size += ALLOC_SIZE;

		pInfo->pBuf = (char*) img_malloc(pInfo->Size);
	}
	else
	{
		RequiredSize = (pInfo->Ptr + length);
		if(RequiredSize > pInfo->Size)
		{
			while(RequiredSize > pInfo->Size) 
			 pInfo->Size += ALLOC_SIZE;

			pInfo->pBuf = (char*) img_realloc(pInfo->pBuf,pInfo->Size);
		}
	}

	if(pInfo->pBuf == NULL)
     png_error(png_ptr, "Write Error");

	img_memcpy(&(((char*)pInfo->pBuf)[pInfo->Ptr]),data,length);
	pInfo->Ptr += length;
}

void PNGAPI
png_buffered_flush_data(png_structp png_ptr)
{
	if(png_ptr == NULL) return;

	buffered_write_info* pInfo = (buffered_write_info*) png_ptr->io_ptr;

	if(pInfo->pBuf == NULL)
	{
		pInfo->Ptr = 0;
		pInfo->Size = 0;
	}
	else
	{
		if(pInfo->Ptr < pInfo->Size)
		{
			pInfo->pBuf = (char*) img_realloc(pInfo->pBuf,pInfo->Ptr);
			pInfo->Size = pInfo->Ptr;
		}
	}
}

pbuffersrc.cpp

#include "png.h"
#include "pngbuffersrc.h"
#include "..\ImgAlloc.h"

void PNGAPI
png_buffered_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
	if(png_ptr == NULL) return;

	buffered_read_info* pInfo = (buffered_read_info*) png_ptr->io_ptr;

	if(((pInfo->Ptr) + length) < pInfo->Size)
	{
		img_memcpy(data,&pInfo->pBuf[pInfo->Ptr],length);
		pInfo->Ptr += length;
	}
	else
     png_error(png_ptr, "Read Error");
}

The prototypes for memory allocation in the PNG library were also mentioned as being modified;

png_voidp /* PRIVATE */ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr);
void /* PRIVATE */ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,png_voidp mem_ptr);
png_voidp PNGAPI png_malloc_default(png_structp png_ptr, png_uint_32 size);
void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr);

pngmem.cpp

The following function excerpts have been taken from pngmem.cpp, where modifications are marked "//here"

/* Allocate memory for a png_struct or a png_info.  The malloc and
   memset can be replaced by a single call to calloc() if this is thought
   to improve performance noticably. */
png_voidp /* PRIVATE */
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
   png_size_t size;
   png_voidp struct_ptr;

   if (type == PNG_STRUCT_INFO)
      size = png_sizeof(png_info);
   else if (type == PNG_STRUCT_PNG)
      size = png_sizeof(png_struct);
   else
      return (NULL);

#ifdef PNG_USER_MEM_SUPPORTED
   if (malloc_fn != NULL)
   {
      png_struct dummy_struct;
      png_structp png_ptr = &dummy_struct;
      png_ptr->mem_ptr=mem_ptr;
      struct_ptr = (*(malloc_fn))(png_ptr, size);
      if (struct_ptr != NULL)
         png_memset(struct_ptr, 0, size);
      return (struct_ptr);
   }
#endif /* PNG_USER_MEM_SUPPORTED */

#if defined(__TURBOC__) && !defined(__FLAT__)
   struct_ptr = (png_voidp)farmalloc(size);
#else
#if defined(_MSC_VER) && defined(MAXSEG_64K)
   struct_ptr = (png_voidp)halloc(size, 1);
#else
   struct_ptr = (png_voidp)img_malloc(size);										//here
#endif
#endif
   if (struct_ptr != NULL)
      png_memset(struct_ptr, 0, size);

   return (struct_ptr);
}

/* Free memory allocated by a png_create_struct() call */
void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
    png_voidp mem_ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
   if (struct_ptr != NULL)
   {
#ifdef PNG_USER_MEM_SUPPORTED
      if (free_fn != NULL)
      {
         png_struct dummy_struct;
         png_structp png_ptr = &dummy_struct;
         png_ptr->mem_ptr=mem_ptr;
         (*(free_fn))(png_ptr, struct_ptr);
         return;
      }
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
      farfree(struct_ptr);
#else
#if defined(_MSC_VER) && defined(MAXSEG_64K)
      hfree(struct_ptr);
#else
      img_free(struct_ptr);														//here
#endif
#endif
   }
}

png_voidp PNGAPI
png_malloc_default(png_structp png_ptr, png_uint_32 size)
{
   png_voidp ret;
#endif /* PNG_USER_MEM_SUPPORTED */

   if (png_ptr == NULL || size == 0)
      return (NULL);

#ifdef PNG_MAX_MALLOC_64K
   if (size > (png_uint_32)65536L)
   {
#ifndef PNG_USER_MEM_SUPPORTED
      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
         png_error(png_ptr, "Cannot Allocate > 64K");
      else
#endif
         return NULL;
   }
#endif

 /* Check for overflow */
#if defined(__TURBOC__) && !defined(__FLAT__)
 if (size != (unsigned long)size)
   ret = NULL;
 else
   ret = farmalloc(size);
#else
#if defined(_MSC_VER) && defined(MAXSEG_64K)
 if (size != (unsigned long)size)
   ret = NULL;
 else
   ret = halloc(size, 1);
#else
 if (size != (size_t)size)
   ret = NULL;
 else
   ret = img_malloc((size_t)size);											//here
#endif
#endif

#ifndef PNG_USER_MEM_SUPPORTED
   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
      png_error(png_ptr, "Out of Memory");
#endif

   return (ret);
}

/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
   without taking any action. */
void PNGAPI
png_free(png_structp png_ptr, png_voidp ptr)
{
   if (png_ptr == NULL || ptr == NULL)
      return;

#ifdef PNG_USER_MEM_SUPPORTED
   if (png_ptr->free_fn != NULL)
   {
      (*(png_ptr->free_fn))(png_ptr, ptr);
      return;
   }
   else png_free_default(png_ptr, ptr);
}
void PNGAPI
png_free_default(png_structp png_ptr, png_voidp ptr)
{
   if (png_ptr == NULL || ptr == NULL)
      return;

#endif /* PNG_USER_MEM_SUPPORTED */

#if defined(__TURBOC__) && !defined(__FLAT__)
   farfree(ptr);
#else
#if defined(_MSC_VER) && defined(MAXSEG_64K)
   hfree(ptr);
#else
   img_free(ptr);															//here
#endif
#endif
}
Copyright © Solid Fluid 2007-2022
Last modified: SolFlu  Sun, 14 Jun 2009 09:23:40 GMT