コード例 #1
0
ファイル: pngmem.c プロジェクト: GRGSIBERIA/EAWebKit
/* 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 (g_png_default_malloc_ptr)
       struct_ptr = (png_voidp)(*g_png_default_malloc_ptr)(size);
   else
       struct_ptr = (png_voidp)malloc(size);

   if (struct_ptr != NULL)
      png_memset(struct_ptr, 0, size);

   return (struct_ptr);
}
コード例 #2
0
ファイル: pngtest.c プロジェクト: 0ryuO/dolphin-avsync
png_voidp
png_debug_malloc(png_structp png_ptr, png_uint_32 size)
{

   /* png_malloc has already tested for NULL; png_create_struct calls
    * png_debug_malloc directly, with png_ptr == NULL which is OK
    */

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

   /* This calls the library allocator twice, once to get the requested
      buffer and once to get a new free list entry. */
   {
      /* Disable malloc_fn and free_fn */
      memory_infop pinfo;
      png_set_mem_fn(png_ptr, NULL, NULL, NULL);
      pinfo = (memory_infop)png_malloc(png_ptr,
         (png_uint_32)png_sizeof(*pinfo));
      pinfo->size = size;
      current_allocation += size;
      total_allocation += size;
      num_allocations ++;
      if (current_allocation > maximum_allocation)
         maximum_allocation = current_allocation;
      pinfo->pointer = (png_voidp)png_malloc(png_ptr, size);
      /* Restore malloc_fn and free_fn */
      png_set_mem_fn(png_ptr,
          png_voidp_NULL, (png_malloc_ptr)png_debug_malloc,
          (png_free_ptr)png_debug_free);
      if (size != 0 && pinfo->pointer == NULL)
      {
         current_allocation -= size;
         total_allocation -= size;
         png_error(png_ptr,
           "out of memory in pngtest->png_debug_malloc.");
      }
      pinfo->next = pinformation;
      pinformation = pinfo;
      /* Make sure the caller isn't assuming zeroed memory. */
      png_memset(pinfo->pointer, 0xdd, pinfo->size);
      if (verbose)
         printf("png_malloc %lu bytes at %x\n", (unsigned long)size,
            pinfo->pointer);
      return (png_voidp)(pinfo->pointer);
   }
}
コード例 #3
0
ファイル: png.cpp プロジェクト: trainman419/raytracer
// write 24-bit image data to a file
int writePng(FILE * fp, int w, int h, char * data) {
   // set up row pointers
   png_byte ** row_pointers = (png_byte**)malloc(h*png_sizeof(png_bytep));
   if( !row_pointers ) {
      return -1;
   }
   for( int i=0; i<h; i++ ) {
      row_pointers[i] = (png_byte*)(data + i*w*3);
   }

   // set up png structures
   png_structp png_ptr = png_create_write_struct(
         PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
   if(!png_ptr)
      return -1;

   png_infop info_ptr = png_create_info_struct(png_ptr);
   if(!info_ptr) {
      png_destroy_write_struct(&png_ptr, (png_infopp)NULL);

      return -1;
   }

   // set up error-handling
   if( setjmp(png_jmpbuf(png_ptr)) ) {
      png_destroy_write_struct(&png_ptr, &info_ptr);
      return -1;
   }

   png_init_io(png_ptr, fp);

   // set up width, height, RGB with 8-bits/color
   png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB,
         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, 
         PNG_FILTER_TYPE_DEFAULT);

   png_set_rows(png_ptr, info_ptr, row_pointers);

   png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

   // clean up
   png_destroy_write_struct(&png_ptr, &info_ptr);
   free(row_pointers);

   return 0;
}
コード例 #4
0
ファイル: yggdrasil_pv.c プロジェクト: kuriel07/Yggdrasil
png_info * png_create_info_struct_2(png_struct * png_ptr)
{
   png_info * info_ptr;
   
   //png_debug(1, "in png_create_info_struct");
   if (png_ptr == NULL)
      return (NULL);

#ifdef PNG_USER_MEM_SUPPORTED
   info_ptr = (png_info *)png_create_struct_3(PNG_STRUCT_INFO,
      png_ptr->malloc_fn, png_ptr->mem_ptr);
#endif
   Uart_Printf("init info struct\n");
   if (info_ptr != NULL)
      png_info_init_4(&info_ptr, png_sizeof(png_info));
   Uart_Printf("initialized\n");
   return info_ptr;
}
コード例 #5
0
ファイル: yggdrasil_pv.c プロジェクト: kuriel07/Yggdrasil
void png_info_init_4(png_info ** ptr_ptr, png_size_t png_info_struct_size)
{
   png_info * info_ptr = * ptr_ptr;

   //png_debug(1, "in png_info_init_3");

   if (info_ptr == NULL)
      return;

   /*if (png_sizeof(png_info) > png_info_struct_size)
   {
      png_destroy_struct_4(info_ptr);
      info_ptr = (png_info *)png_create_struct(PNG_STRUCT_INFO);
      *ptr_ptr = info_ptr;
   }*/

   memset(info_ptr, 0, png_sizeof(png_info));
}
コード例 #6
0
ファイル: png.c プロジェクト: bubbg/lambdanative
/* Allocate the memory for an info_struct for the application.  We don't
 * really need the png_ptr, but it could potentially be useful in the
 * future.  This should be used in favour of malloc(png_sizeof(png_info))
 * and png_info_init() so that applications that want to use a shared
 * libpng don't have to be recompiled if png_info changes size.
 */
png_infop PNGAPI
png_create_info_struct(png_structp png_ptr)
{
   png_infop info_ptr;

   png_debug(1, "in png_create_info_struct\n");
   if(png_ptr == NULL) return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
      png_ptr->malloc_fn, png_ptr->mem_ptr);
#else
   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
#endif
   if (info_ptr != NULL)
      png_info_init_3(&info_ptr, png_sizeof(png_info));

   return (info_ptr);
}
コード例 #7
0
ファイル: png.c プロジェクト: bubbg/lambdanative
/* This is an internal routine to free any memory that the info struct is
 * pointing to before re-using it or freeing the struct itself.  Recall
 * that png_free() checks for NULL pointers for us.
 */
void /* PRIVATE */
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
{
   png_debug(1, "in png_info_destroy\n");

   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
   if (png_ptr->num_chunk_list)
   {
       png_free(png_ptr, png_ptr->chunk_list);
       png_ptr->chunk_list=NULL;
       png_ptr->num_chunk_list=0;
   }
#endif

   png_info_init_3(&info_ptr, png_sizeof(png_info));
}
コード例 #8
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
void PNGAPI
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
{
    png_debug1(1, "in %s storage function", "tIME");

    if (png_ptr == NULL || info_ptr == NULL ||
            (png_ptr->mode & PNG_WROTE_tIME))
        return;

    if (mod_time->month == 0   || mod_time->month > 12  ||
            mod_time->day   == 0   || mod_time->day   > 31  ||
            mod_time->hour  > 23   || mod_time->minute > 59 ||
            mod_time->second > 60)
    {
        png_warning(png_ptr, "Ignoring invalid time value");
        return;
    }

    png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
    info_ptr->valid |= PNG_INFO_tIME;
}
コード例 #9
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
void PNGAPI
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
{
    int i;

    png_debug1(1, "in %s storage function", "hIST");

    if (png_ptr == NULL || info_ptr == NULL)
        return;

    if (info_ptr->num_palette == 0 || info_ptr->num_palette
            > PNG_MAX_PALETTE_LENGTH)
    {
        png_warning(png_ptr,
                    "Invalid palette size, hIST allocation skipped");

        return;
    }

    png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);

    /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
     * version 1.2.1
     */
    png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
                    PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));

    if (png_ptr->hist == NULL)
    {
        png_warning(png_ptr, "Insufficient memory for hIST chunk data");
        return;
    }

    for (i = 0; i < info_ptr->num_palette; i++)
        png_ptr->hist[i] = hist[i];

    info_ptr->hist = png_ptr->hist;
    info_ptr->valid |= PNG_INFO_hIST;
    info_ptr->free_me |= PNG_FREE_HIST;
}
コード例 #10
0
void wrPng(BYTE *bits, int w, int h, int line, FILE *f)
{
	png_structp png_ptr;
	png_infop info_ptr;

	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
	if(png_ptr){
		info_ptr = png_create_info_struct(png_ptr);
		if(info_ptr){
			if(!setjmp(png_jmpbuf(png_ptr))){
				png_init_io(png_ptr, f);
				png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
				BYTE **row_pointers = (BYTE**)png_malloc(png_ptr, h*png_sizeof(png_bytep));
				for(int i=0; i<h; i++){
					row_pointers[i]= bits+(h-i-1)*line;
				}
				png_set_rows(png_ptr, info_ptr, row_pointers);
				png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, 0);
				png_free(png_ptr, row_pointers);
			}
		}
		png_destroy_write_struct(&png_ptr, &info_ptr);
	}
}
コード例 #11
0
ファイル: pngpread.c プロジェクト: AGenews/GUI
void /* PRIVATE */
png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
{
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
      png_size_t text_size;

      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
      else
         text_size = png_ptr->current_text_left;
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
      png_ptr->current_text_left -= text_size;
      png_ptr->current_text_ptr += text_size;
   }
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp text;
      png_charp key;
      int ret;
      png_size_t text_size, key_size;

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

      png_push_crc_finish(png_ptr);

      key = png_ptr->current_text;

      for (text = key; *text; text++)
         /* empty loop */ ;

      /* zTXt can't have zero text */
      if (text >= key + png_ptr->current_text_size)
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         return;
      }

      text++;

      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         return;
      }

      text++;

      png_ptr->zstream.next_in = (png_bytep )text;
      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
         (text - key));
      png_ptr->zstream.next_out = png_ptr->zbuf;
      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

      key_size = text - key;
      text_size = 0;
      text = NULL;
      ret = Z_STREAM_END;

      while (png_ptr->zstream.avail_in)
      {
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
         if (ret != Z_OK && ret != Z_STREAM_END)
         {
            inflateReset(&png_ptr->zstream);
            png_ptr->zstream.avail_in = 0;
            png_ptr->current_text = NULL;
            png_free(png_ptr, key);
            png_free(png_ptr, text);
            return;
         }
         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
         {
            if (text == NULL)
            {
               text = (png_charp)png_malloc(png_ptr,
                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
                     + key_size + 1));
               png_memcpy(text + key_size, png_ptr->zbuf,
                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
               png_memcpy(text, key, key_size);
               text_size = key_size + png_ptr->zbuf_size -
                  png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
            }
            else
            {
               png_charp tmp;

               tmp = text;
               text = (png_charp)png_malloc(png_ptr, text_size +
                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
                   + 1));
               png_memcpy(text, tmp, text_size);
               png_free(png_ptr, tmp);
               png_memcpy(text + text_size, png_ptr->zbuf,
                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
            }
            if (ret != Z_STREAM_END)
            {
               png_ptr->zstream.next_out = png_ptr->zbuf;
               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
            }
         }
         else
         {
            break;
         }

         if (ret == Z_STREAM_END)
            break;
      }

      inflateReset(&png_ptr->zstream);
      png_ptr->zstream.avail_in = 0;

      if (ret != Z_STREAM_END)
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         png_free(png_ptr, text);
         return;
      }

      png_ptr->current_text = NULL;
      png_free(png_ptr, key);
      key = text;
      text += key_size;

      text_ptr = (png_textp)png_malloc(png_ptr,
          (png_uint_32)png_sizeof(png_text));
      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
      text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
#endif
      text_ptr->text = text;

      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);

      png_free(png_ptr, key);
      png_free(png_ptr, text_ptr);

      if (ret)
        png_warning(png_ptr, "Insufficient memory to store text chunk.");
   }
}
コード例 #12
0
ファイル: pngpread.c プロジェクト: AGenews/GUI
void /* PRIVATE */
png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
{
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
      png_size_t text_size;

      if (png_ptr->buffer_size < png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
      else
         text_size = png_ptr->current_text_left;
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
      png_ptr->current_text_left -= text_size;
      png_ptr->current_text_ptr += text_size;
   }
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp text;
      png_charp key;
      int ret;

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

      png_push_crc_finish(png_ptr);

#if defined(PNG_MAX_MALLOC_64K)
      if (png_ptr->skip_length)
         return;
#endif

      key = png_ptr->current_text;

      for (text = key; *text; text++)
         /* empty loop */ ;

      if (text < key + png_ptr->current_text_size)
         text++;

      text_ptr = (png_textp)png_malloc(png_ptr,
         (png_uint_32)png_sizeof(png_text));
      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
      text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
#endif
      text_ptr->text = text;

      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);

      png_free(png_ptr, key);
      png_free(png_ptr, text_ptr);
      png_ptr->current_text = NULL;

      if (ret)
        png_warning(png_ptr, "Insufficient memory to store text chunk.");
   }
}
コード例 #13
0
ファイル: pngread.c プロジェクト: My-Source/root
void PNGAPI
png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
   png_size_t png_struct_size)
{
#ifdef PNG_SETJMP_SUPPORTED
   jmp_buf tmp_jmp;  /* to save current jump buffer */
#endif

   int i=0;

   png_structp png_ptr=*ptr_ptr;

   if(png_ptr == NULL) return;

   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
     {
#ifdef PNG_LEGACY_SUPPORTED
       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
#else
       png_ptr->warning_fn=NULL;
       png_warning(png_ptr,
        "Application uses deprecated png_read_init() and should be recompiled.");
       break;
#endif
     }
   } while (png_libpng_ver[i++]);

   png_debug(1, "in png_read_init_3\n");

#ifdef PNG_SETJMP_SUPPORTED
   /* save jump buffer and error functions */
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf));
#endif

   if(png_sizeof(png_struct) > png_struct_size)
     {
       png_destroy_struct(png_ptr);
       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
       png_ptr = *ptr_ptr;
     }

   /* reset all variables to 0 */
   png_memset(png_ptr, 0, png_sizeof (png_struct));

#ifdef PNG_SETJMP_SUPPORTED
   /* restore jump buffer */
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf));
#endif

   /* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;

   switch (inflateInit(&png_ptr->zstream))
   {
     case Z_OK: /* Do nothing */ break;
     case Z_MEM_ERROR:
     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
     default: png_error(png_ptr, "Unknown zlib error");
   }

   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
}
コード例 #14
0
ファイル: pngread.c プロジェクト: Brukwa/VisualBoyAdvance
/* Alternate create PNG structure for reading, and allocate any memory needed. */
png_structp PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */

   png_structp png_ptr;

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

   int i;

   png_debug(1, "in png_create_read_struct\n");
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
#else
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
#endif
   if (png_ptr == NULL)
      return (NULL);

#if !defined(PNG_1_0_X)
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
   png_init_mmx_flags(png_ptr);   /* 1.2.0 addition */
#endif
#endif /* PNG_1_0_X */

   /* added at libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
#endif

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_ptr->jmpbuf))
#endif
   {
      png_free(png_ptr, png_ptr->zbuf);
      png_ptr->zbuf=NULL;
#ifdef PNG_USER_MEM_SUPPORTED
      png_destroy_struct_2((png_voidp)png_ptr,
         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
      return (NULL);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#endif
#endif

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif

   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   i=0;
   do
   {
     if(user_png_ver[i] != png_libpng_ver[i])
        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
   } while (png_libpng_ver[i++]);

   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
   {
     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
      * we must recompile any applications that use any older library version.
      * For versions after libpng 1.0, we will be compatible, so we need
      * only check the first digit.
      */
     if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
         (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
         (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
     {
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
        char msg[80];
        if (user_png_ver)
        {
          sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
             user_png_ver);
          png_warning(png_ptr, msg);
        }
        sprintf(msg, "Application  is  running with png.c from libpng-%.20s",
           png_libpng_ver);
        png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
        png_ptr->flags=0;
#endif
        png_error(png_ptr,
           "Incompatible libpng version in application and library");
     }
   }

   /* initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
     (png_uint_32)png_ptr->zbuf_size);
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;

   switch (inflateInit(&png_ptr->zstream))
   {
     case Z_OK: /* Do nothing */ break;
     case Z_MEM_ERROR:
     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
     default: png_error(png_ptr, "Unknown zlib error");
   }

   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

   png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);

#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then encounter
   a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
   abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
      PNG_ABORT();
   png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf));
#else
   if (setjmp(png_ptr->jmpbuf))
      PNG_ABORT();
#endif
#endif
   return (png_ptr);
}
コード例 #15
0
ファイル: pngtest.c プロジェクト: 50p/multitheftauto
/* Test one file */
int
test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
   static png_FILE_p fpin;
   static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
   png_structp read_ptr;
   png_infop read_info_ptr, end_info_ptr;
#ifdef PNG_WRITE_SUPPORTED
   png_structp write_ptr;
   png_infop write_info_ptr;
   png_infop write_end_info_ptr;
#else
   png_structp write_ptr = NULL;
   png_infop write_info_ptr = NULL;
   png_infop write_end_info_ptr = NULL;
#endif
   png_bytep row_buf;
   png_uint_32 y;
   png_uint_32 width, height;
   int num_pass, pass;
   int bit_depth, color_type;
#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

#if defined(_WIN32_WCE)
   TCHAR path[MAX_PATH];
#endif
   char inbuf[256], outbuf[256];

   row_buf = NULL;

#if defined(_WIN32_WCE)
   MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
   if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
#else
   if ((fpin = fopen(inname, "rb")) == NULL)
#endif
   {
      fprintf(STDERR, "Could not find input file %s\n", inname);
      return (1);
   }

#if defined(_WIN32_WCE)
   MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
   if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
#else
   if ((fpout = fopen(outname, "wb")) == NULL)
#endif
   {
      fprintf(STDERR, "Could not open output file %s\n", outname);
      FCLOSE(fpin);
      return (1);
   }

   png_debug(0, "Allocating read and write structures\n");
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
   read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
#else
   read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL);
#endif
#if defined(PNG_NO_STDIO)
   png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
       pngtest_warning);
#endif
#ifdef PNG_WRITE_SUPPORTED
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
   write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
      (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
#else
   write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
      png_error_ptr_NULL, png_error_ptr_NULL);
#endif
#if defined(PNG_NO_STDIO)
   png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
       pngtest_warning);
#endif
#endif
   png_debug(0, "Allocating read_info, write_info and end_info structures\n");
   read_info_ptr = png_create_info_struct(read_ptr);
   end_info_ptr = png_create_info_struct(read_ptr);
#ifdef PNG_WRITE_SUPPORTED
   write_info_ptr = png_create_info_struct(write_ptr);
   write_end_info_ptr = png_create_info_struct(write_ptr);
#endif

#ifdef PNG_SETJMP_SUPPORTED
   png_debug(0, "Setting jmpbuf for read struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(read_ptr)))
#endif
   {
      fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
      if (row_buf)
         png_free(read_ptr, row_buf);
      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
      FCLOSE(fpin);
      FCLOSE(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf));
#endif

#ifdef PNG_WRITE_SUPPORTED
   png_debug(0, "Setting jmpbuf for write struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(write_ptr)))
#endif
   {
      fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
      png_destroy_info_struct(write_ptr, &write_end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
      FCLOSE(fpin);
      FCLOSE(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf));
#endif
#endif
#endif

   png_debug(0, "Initializing input and output streams\n");
#if !defined(PNG_NO_STDIO)
   png_init_io(read_ptr, fpin);
#  ifdef PNG_WRITE_SUPPORTED
   png_init_io(write_ptr, fpout);
#  endif
#else
   png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
#  ifdef PNG_WRITE_SUPPORTED
   png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
#    if defined(PNG_WRITE_FLUSH_SUPPORTED)
      pngtest_flush);
#    else
      NULL);
#    endif
#  endif
#endif
   if(status_dots_requested == 1)
   {
#ifdef PNG_WRITE_SUPPORTED
      png_set_write_status_fn(write_ptr, write_row_callback);
#endif
      png_set_read_status_fn(read_ptr, read_row_callback);
   }
   else
   {
#ifdef PNG_WRITE_SUPPORTED
      png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
#endif
      png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
   }

#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   {
     int i;
     for(i=0; i<256; i++)
        filters_used[i]=0;
     png_set_read_user_transform_fn(read_ptr, count_filters);
   }
#endif
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
   zero_samples=0;
   png_set_write_user_transform_fn(write_ptr, count_zero_samples);
#endif

#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
#  ifndef PNG_HANDLE_CHUNK_ALWAYS
#    define PNG_HANDLE_CHUNK_ALWAYS       3
#  endif
   png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
      png_bytep_NULL, 0);
#endif
#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
#  ifndef PNG_HANDLE_CHUNK_IF_SAFE
#    define PNG_HANDLE_CHUNK_IF_SAFE      2
#  endif
   png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
      png_bytep_NULL, 0);
#endif

   png_debug(0, "Reading info struct\n");
   png_read_info(read_ptr, read_info_ptr);

   png_debug(0, "Transferring info struct\n");
   {
      int interlace_type, compression_type, filter_type;

      if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
          &color_type, &interlace_type, &compression_type, &filter_type))
      {
         png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
            color_type, interlace_type, compression_type, filter_type);
#else
            color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
#endif
      }
   }
コード例 #16
0
void PNGAPI
png_read_png(png_structp png_ptr, png_infop info_ptr,
                           int transforms,
                           voidp params)
{
   int row;

   if (png_ptr == NULL)
      return;

   /* png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);
   if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
      png_error(png_ptr, "Image is too high to process with png_read_png()");

   /* -------------- image transformations start here ------------------- */

#ifdef PNG_READ_16_TO_8_SUPPORTED
   /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
    */
   if (transforms & PNG_TRANSFORM_STRIP_16)
      png_set_strip_16(png_ptr);
#endif

#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   /* Strip alpha bytes from the input data without combining with
    * the background (not recommended).
    */
   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
      png_set_strip_alpha(png_ptr);
#endif

#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   if (transforms & PNG_TRANSFORM_PACKING)
      png_set_packing(png_ptr);
#endif

#ifdef PNG_READ_PACKSWAP_SUPPORTED
   /* Change the order of packed pixels to least significant bit first
    * (not useful if you are using png_set_packing).
    */
   if (transforms & PNG_TRANSFORM_PACKSWAP)
      png_set_packswap(png_ptr);
#endif

#ifdef PNG_READ_EXPAND_SUPPORTED
   /* Expand paletted colors into true RGB triplets
    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
    * Expand paletted or RGB images with transparency to full alpha
    * channels so the data will be available as RGBA quartets.
    */
   if (transforms & PNG_TRANSFORM_EXPAND)
      if ((png_ptr->bit_depth < 8) ||
          (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
         png_set_expand(png_ptr);
#endif

   /* We don't handle background color or gamma transformation or quantizing.
    */

#ifdef PNG_READ_INVERT_SUPPORTED
   /* Invert monochrome files to have 0 as white and 1 as black
    */
   if (transforms & PNG_TRANSFORM_INVERT_MONO)
      png_set_invert_mono(png_ptr);
#endif

#ifdef PNG_READ_SHIFT_SUPPORTED
   /* If you want to shift the pixel values from the range [0,255] or
    * [0,65535] to the original [0,7] or [0,31], or whatever range the
    * colors were originally in:
    */
   if ((transforms & PNG_TRANSFORM_SHIFT)
       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
   {
      png_color_8p sig_bit;

      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
      png_set_shift(png_ptr, sig_bit);
   }
#endif

#ifdef PNG_READ_BGR_SUPPORTED
   /* Flip the RGB pixels to BGR (or RGBA to BGRA)
    */
   if (transforms & PNG_TRANSFORM_BGR)
      png_set_bgr(png_ptr);
#endif

#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
    */
   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
       png_set_swap_alpha(png_ptr);
#endif

#ifdef PNG_READ_SWAP_SUPPORTED
   /* Swap bytes of 16 bit files to least significant byte first
    */
   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
      png_set_swap(png_ptr);
#endif

/* Added at libpng-1.2.41 */
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   /* Invert the alpha channel from opacity to transparency
    */
   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
       png_set_invert_alpha(png_ptr);
#endif

/* Added at libpng-1.2.41 */
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   /* Expand grayscale image to RGB
    */
   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
       png_set_gray_to_rgb(png_ptr);
#endif

   /* We don't handle adding filler bytes */

   /* Optional call to gamma correct and add the background to the palette
    * and update info structure.  REQUIRED if you are expecting libpng to
    * update the palette for you (i.e., you selected such a transform above).
    */
   png_read_update_info(png_ptr, info_ptr);

   /* -------------- image transformations end here ------------------- */

   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
   if (info_ptr->row_pointers == NULL)
   {
    png_uint_32 iptr;

      info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
         info_ptr->height * png_sizeof(png_bytep));
      for (iptr=0; iptr<info_ptr->height; iptr++)
         info_ptr->row_pointers[iptr] = NULL;

      info_ptr->free_me |= PNG_FREE_ROWS;

      for (row = 0; row < (int)info_ptr->height; row++)
         info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
            png_get_rowbytes(png_ptr, info_ptr));
   }

   png_read_image(png_ptr, info_ptr->row_pointers);
   info_ptr->valid |= PNG_INFO_IDAT;

   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
   png_read_end(png_ptr, info_ptr);

   transforms = transforms; /* Quiet compiler warnings */
   params = params;

}
コード例 #17
0
ファイル: image_png.cpp プロジェクト: projedi/stabilization
// Write a png file; size of image: (width * nbytes) * height
bool write_png(char *file_name, int width, int height, int nbytes, UCHAR *image)
{
    int	bit_depth	= 8;

    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr;

    fp = fopen(file_name, "wb");
    if (fp == NULL) return false;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if (png_ptr == NULL) {
        fclose(fp);
        return false;
    }

    // Allocate/initialize the image information data
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        fclose(fp);
        png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
        return false;
    }

    // Set error handling.  REQUIRED if you aren't supplying your own
    // error handling functions in the png_create_write_struct() call.
    if (setjmp(png_jmpbuf(png_ptr))) {
        fclose(fp);		// If we get here, we had a problem writing the file
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }

    // I/O initialization method: using standard C streams
    png_init_io(png_ptr, fp);

    // Set the image information here.  Width and height are up to 2^31,
    // bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
    // the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
    // PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
    // or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
    // PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
    // currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED

    if (nbytes == 4)
        png_set_IHDR(png_ptr, info_ptr, (png_uint_32)width, (png_uint_32)height, bit_depth,
                     PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    else if (nbytes == 3)
        png_set_IHDR(png_ptr, info_ptr, (png_uint_32)width, (png_uint_32)height, bit_depth,
                     PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    else if (nbytes == 1)
        png_set_IHDR(png_ptr, info_ptr, (png_uint_32)width, (png_uint_32)height, bit_depth,
                     PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    png_write_info(png_ptr, info_ptr);	// Write the file header information.

    png_bytep *row_pointers = NULL;
    row_pointers = (png_bytep*)malloc( height * sizeof(png_bytep) );

    if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
        png_error (png_ptr, "Image is too tall to process in memory");

    for (int k = 0; k < height; k++)
        row_pointers[k] = (png_bytep)(image + k * width * nbytes);

    //for (int k = 0; k < height; k++)
    //	for (int i = 0; i < width; i++) {
    //		memset(row_pointers[k] + nbytes * i + 0, 55, 1);
    //		memset(row_pointers[k] + nbytes * i + 1, 55, 1);
    //	}

    // Write a few rows of image data
    // png_write_rows(png_ptr, row_pointers, height);

    // Write out the entire image data in one call
    png_write_image(png_ptr, row_pointers);

    // It is REQUIRED to call this to finish writing the rest of the file
    png_write_end(png_ptr, info_ptr);

    png_destroy_write_struct(&png_ptr, &info_ptr);

    free(row_pointers);
    row_pointers = NULL;
    fclose(fp);

    return true;
}
コード例 #18
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
void PNGAPI
png_set_sPLT(png_structp png_ptr,
             png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
/*
 *  entries        - array of png_sPLT_t structures
 *                   to be added to the list of palettes
 *                   in the info structure.
 *
 *  nentries       - number of palette structures to be
 *                   added.
 */
{
    png_sPLT_tp np;
    int i;

    if (png_ptr == NULL || info_ptr == NULL)
        return;

    if (nentries < 0 ||
            nentries > INT_MAX-info_ptr->splt_palettes_num ||
            (unsigned int)/*SAFE*/(nentries +/*SAFE*/
                                   info_ptr->splt_palettes_num) >=
            PNG_SIZE_MAX/png_sizeof(png_sPLT_t))
        np=NULL;

    else

        np = (png_sPLT_tp)png_malloc_warn(png_ptr,
                                          (info_ptr->splt_palettes_num + nentries) *
                                          (png_size_t)png_sizeof(png_sPLT_t));

    if (np == NULL)
    {
        png_warning(png_ptr, "No memory for sPLT palettes");
        return;
    }

    png_memcpy(np, info_ptr->splt_palettes,
               info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));

    png_free(png_ptr, info_ptr->splt_palettes);
    info_ptr->splt_palettes=NULL;

    for (i = 0; i < nentries; i++)
    {
        png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
        png_const_sPLT_tp from = entries + i;
        png_size_t length;

        length = png_strlen(from->name) + 1;
        to->name = (png_charp)png_malloc_warn(png_ptr, length);

        if (to->name == NULL)
        {
            png_warning(png_ptr,
                        "Out of memory while processing sPLT chunk");
            continue;
        }

        png_memcpy(to->name, from->name, length);
        to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
                      from->nentries * png_sizeof(png_sPLT_entry));

        if (to->entries == NULL)
        {
            png_warning(png_ptr,
                        "Out of memory while processing sPLT chunk");
            png_free(png_ptr, to->name);
            to->name = NULL;
            continue;
        }

        png_memcpy(to->entries, from->entries,
                   from->nentries * png_sizeof(png_sPLT_entry));

        to->nentries = from->nentries;
        to->depth = from->depth;
    }

    info_ptr->splt_palettes = np;
    info_ptr->splt_palettes_num += nentries;
    info_ptr->valid |= PNG_INFO_sPLT;
    info_ptr->free_me |= PNG_FREE_SPLT;
}
コード例 #19
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
int /* PRIVATE */
png_set_text_2(png_structp png_ptr, png_infop info_ptr,
               png_const_textp text_ptr, int num_text)
{
    int i;

    png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
               (unsigned long)png_ptr->chunk_name);

    if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
        return(0);

    /* Make sure we have enough space in the "text" array in info_struct
     * to hold all of the incoming text_ptr objects.
     */

    if (num_text < 0 ||
            num_text > INT_MAX - info_ptr->num_text - 8 ||
            (unsigned int)/*SAFE*/(num_text +/*SAFE*/
                                   info_ptr->num_text + 8) >=
            PNG_SIZE_MAX/png_sizeof(png_text))
    {
        png_warning(png_ptr, "too many text chunks");
        return(0);
    }

    if (info_ptr->num_text + num_text > info_ptr->max_text)
    {
        int old_max_text = info_ptr->max_text;
        int old_num_text = info_ptr->num_text;

        if (info_ptr->text != NULL)
        {
            png_textp old_text;

            info_ptr->max_text = info_ptr->num_text + num_text + 8;
            old_text = info_ptr->text;

            info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
                             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));

            if (info_ptr->text == NULL)
            {
                /* Restore to previous condition */
                info_ptr->max_text = old_max_text;
                info_ptr->text = old_text;
                return(1);
            }

            png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max_text *
                       png_sizeof(png_text)));
            png_free(png_ptr, old_text);
        }

        else
        {
            info_ptr->max_text = num_text + 8;
            info_ptr->num_text = 0;
            info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
                             (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
            if (info_ptr->text == NULL)
            {
                /* Restore to previous condition */
                info_ptr->num_text = old_num_text;
                info_ptr->max_text = old_max_text;
                return(1);
            }
            info_ptr->free_me |= PNG_FREE_TEXT;
        }

        png_debug1(3, "allocated %d entries for info_ptr->text",
                   info_ptr->max_text);
    }
    for (i = 0; i < num_text; i++)
    {
        png_size_t text_length, key_len;
        png_size_t lang_len, lang_key_len;
        png_textp textp = &(info_ptr->text[info_ptr->num_text]);

        if (text_ptr[i].key == NULL)
            continue;

        if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
                text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
        {
            png_warning(png_ptr, "text compression mode is out of range");
            continue;
        }

        key_len = png_strlen(text_ptr[i].key);

        if (text_ptr[i].compression <= 0)
        {
            lang_len = 0;
            lang_key_len = 0;
        }

        else
#  ifdef PNG_iTXt_SUPPORTED
        {
            /* Set iTXt data */

            if (text_ptr[i].lang != NULL)
                lang_len = png_strlen(text_ptr[i].lang);

            else
                lang_len = 0;

            if (text_ptr[i].lang_key != NULL)
                lang_key_len = png_strlen(text_ptr[i].lang_key);

            else
                lang_key_len = 0;
        }
#  else /* PNG_iTXt_SUPPORTED */
        {
            png_warning(png_ptr, "iTXt chunk not supported");
            continue;
        }
#  endif

        if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
        {
            text_length = 0;
#  ifdef PNG_iTXt_SUPPORTED
            if (text_ptr[i].compression > 0)
                textp->compression = PNG_ITXT_COMPRESSION_NONE;

            else
#  endif
                textp->compression = PNG_TEXT_COMPRESSION_NONE;
        }

        else
        {
            text_length = png_strlen(text_ptr[i].text);
            textp->compression = text_ptr[i].compression;
        }

        textp->key = (png_charp)png_malloc_warn(png_ptr,
                                                (png_size_t)
                                                (key_len + text_length + lang_len + lang_key_len + 4));

        if (textp->key == NULL)
            return(1);

        png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
                   (unsigned long)(png_uint_32)
                   (key_len + lang_len + lang_key_len + text_length + 4),
                   textp->key);

        png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
        *(textp->key + key_len) = '\0';

        if (text_ptr[i].compression > 0)
        {
            textp->lang = textp->key + key_len + 1;
            png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
            *(textp->lang + lang_len) = '\0';
            textp->lang_key = textp->lang + lang_len + 1;
            png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
            *(textp->lang_key + lang_key_len) = '\0';
            textp->text = textp->lang_key + lang_key_len + 1;
        }

        else
        {
            textp->lang=NULL;
            textp->lang_key=NULL;
            textp->text = textp->key + key_len + 1;
        }

        if (text_length)
            png_memcpy(textp->text, text_ptr[i].text,
                       (png_size_t)(text_length));

        *(textp->text + text_length) = '\0';

#  ifdef PNG_iTXt_SUPPORTED
        if (textp->compression > 0)
        {
            textp->text_length = 0;
            textp->itxt_length = text_length;
        }

        else
#  endif
        {
            textp->text_length = text_length;
            textp->itxt_length = 0;
        }

        info_ptr->num_text++;
        png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
    }
    return(0);
}
コード例 #20
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
void PNGAPI
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
             png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
             int nparams, png_const_charp units, png_charpp params)
{
    png_size_t length;
    int i;

    png_debug1(1, "in %s storage function", "pCAL");

    if (png_ptr == NULL || info_ptr == NULL)
        return;

    length = png_strlen(purpose) + 1;
    png_debug1(3, "allocating purpose for info (%lu bytes)",
               (unsigned long)length);

    /* TODO: validate format of calibration name and unit name */

    /* Check that the type matches the specification. */
    if (type < 0 || type > 3)
        png_error(png_ptr, "Invalid pCAL equation type");

    /* Validate params[nparams] */
    for (i=0; i<nparams; ++i)
        if (!png_check_fp_string(params[i], png_strlen(params[i])))
            png_error(png_ptr, "Invalid format for pCAL parameter");

    info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);

    if (info_ptr->pcal_purpose == NULL)
    {
        png_warning(png_ptr, "Insufficient memory for pCAL purpose");
        return;
    }

    png_memcpy(info_ptr->pcal_purpose, purpose, length);

    png_debug(3, "storing X0, X1, type, and nparams in info");
    info_ptr->pcal_X0 = X0;
    info_ptr->pcal_X1 = X1;
    info_ptr->pcal_type = (png_byte)type;
    info_ptr->pcal_nparams = (png_byte)nparams;

    length = png_strlen(units) + 1;
    png_debug1(3, "allocating units for info (%lu bytes)",
               (unsigned long)length);

    info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);

    if (info_ptr->pcal_units == NULL)
    {
        png_warning(png_ptr, "Insufficient memory for pCAL units");
        return;
    }

    png_memcpy(info_ptr->pcal_units, units, length);

    info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
                            (png_size_t)((nparams + 1) * png_sizeof(png_charp)));

    if (info_ptr->pcal_params == NULL)
    {
        png_warning(png_ptr, "Insufficient memory for pCAL params");
        return;
    }

    png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));

    for (i = 0; i < nparams; i++)
    {
        length = png_strlen(params[i]) + 1;
        png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
                   (unsigned long)length);

        info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);

        if (info_ptr->pcal_params[i] == NULL)
        {
            png_warning(png_ptr, "Insufficient memory for pCAL parameter");
            return;
        }

        png_memcpy(info_ptr->pcal_params[i], params[i], length);
    }

    info_ptr->valid |= PNG_INFO_pCAL;
    info_ptr->free_me |= PNG_FREE_PCAL;
}
コード例 #21
0
ファイル: pngset.c プロジェクト: robn/pioneer-thirdparty
void PNGAPI
png_set_unknown_chunks(png_structp png_ptr,
                       png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
{
    png_unknown_chunkp np;
    int i;

    if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
        return;

    if (num_unknowns < 0 ||
            num_unknowns > INT_MAX-info_ptr->unknown_chunks_num ||
            (unsigned int)/*SAFE*/(num_unknowns +/*SAFE*/
                                   info_ptr->unknown_chunks_num) >=
            PNG_SIZE_MAX/png_sizeof(png_unknown_chunk))
        np=NULL;

    else
        np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
                (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
                png_sizeof(png_unknown_chunk));

    if (np == NULL)
    {
        png_warning(png_ptr,
                    "Out of memory while processing unknown chunk");
        return;
    }

    png_memcpy(np, info_ptr->unknown_chunks,
               (png_size_t)info_ptr->unknown_chunks_num *
               png_sizeof(png_unknown_chunk));

    png_free(png_ptr, info_ptr->unknown_chunks);
    info_ptr->unknown_chunks = NULL;

    for (i = 0; i < num_unknowns; i++)
    {
        png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
        png_const_unknown_chunkp from = unknowns + i;

        png_memcpy(to->name, from->name, png_sizeof(from->name));
        to->name[png_sizeof(to->name)-1] = '\0';
        to->size = from->size;

        /* Note our location in the read or write sequence */
        to->location = (png_byte)(png_ptr->mode & 0xff);

        if (from->size == 0)
            to->data=NULL;

        else
        {
            to->data = (png_bytep)png_malloc_warn(png_ptr,
                                                  (png_size_t)from->size);

            if (to->data == NULL)
            {
                png_warning(png_ptr,
                            "Out of memory while processing unknown chunk");
                to->size = 0;
            }

            else
                png_memcpy(to->data, from->data, from->size);
        }
    }

    info_ptr->unknown_chunks = np;
    info_ptr->unknown_chunks_num += num_unknowns;
    info_ptr->free_me |= PNG_FREE_UNKN;
}
コード例 #22
0
ImageReaderPNG::ImageType ImageReaderPNG::readData(const std::string& filePath, PNGInfra& infra, bool wantAlpha)
{
	if (filePath.empty())
		return eInvalid;

	infra.pFile = fopen(filePath.c_str(), "rb");
	if (!infra.pFile)
	{
		fprintf(stderr, "Error opening file: %s\n", filePath.c_str());
		return eInvalid;
	}

	unsigned char sig[8];

	// check the signature
	fread(sig, 1, 8, infra.pFile);
	if (!png_check_sig(sig, 8))
	{
		fprintf(stderr, "Cannot open file: %s - not a valid PNG file.\n", filePath.c_str());
		fclose(infra.pFile);
		return eInvalid;
	}

	infra.pPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!infra.pPNG)
	{
		fclose(infra.pFile);
		return eInvalid;
	}

	infra.pInfo = png_create_info_struct(infra.pPNG);
	if (!infra.pInfo)
	{
		png_destroy_read_struct(&infra.pPNG, NULL, NULL);
		fclose(infra.pFile);
		return eInvalid;
	}

	if (setjmp(png_jmpbuf(infra.pPNG)))
	{
		png_destroy_read_struct(&infra.pPNG, &infra.pInfo, NULL);
		fclose(infra.pFile);
		return eInvalid;
	}

	png_init_io(infra.pPNG, infra.pFile);
	png_set_sig_bytes(infra.pPNG, 8);
	png_read_info(infra.pPNG, infra.pInfo);

	int colorType;
	int bitDepth, interlaceType, compressionType;

	png_get_IHDR(infra.pPNG, infra.pInfo, &infra.width, &infra.height, &bitDepth, &colorType, &interlaceType, &compressionType, NULL);

	if (colorType == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(infra.pPNG);

	if (png_get_valid(infra.pPNG, infra.pInfo, PNG_INFO_tRNS))
	{
		png_set_tRNS_to_alpha(infra.pPNG);
	}

	if (bitDepth == 16)
		png_set_strip_16(infra.pPNG);

	ImageType type = eInvalid;

	if (!wantAlpha)
	{
		// add black Alpha
		if ((colorType & PNG_COLOR_MASK_ALPHA) == 0)
			png_set_add_alpha(infra.pPNG, 0xFF, PNG_FILLER_AFTER);

		if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			png_set_gray_to_rgb(infra.pPNG);
		else if (colorType != PNG_COLOR_TYPE_RGB && colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			return eInvalid;

		type = eRGBA;
	}
	else
	{
		if (colorType == PNG_COLOR_TYPE_RGB_ALPHA)
			type = eRGBA;
		else if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			type = eA;
		else
			return eInvalid;
	}

	png_read_update_info(infra.pPNG, infra.pInfo);

	infra.pRows = new png_bytep[infra.height * png_sizeof(png_bytep)];

	png_set_rows(infra.pPNG, infra.pInfo, infra.pRows);

	for (unsigned int i = 0; i < infra.height; i++)
	{
		infra.pRows[i] = new png_byte[png_get_rowbytes(infra.pPNG, infra.pInfo)];
	}

	png_read_image(infra.pPNG, infra.pRows);
	png_read_end(infra.pPNG, infra.pInfo);

	return type;
}
コード例 #23
0
ファイル: pngpread.c プロジェクト: AGenews/GUI
void /* PRIVATE */
png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
{

   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
      png_size_t text_size;

      if (png_ptr->buffer_size < png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
      else
         text_size = png_ptr->current_text_left;
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
      png_ptr->current_text_left -= text_size;
      png_ptr->current_text_ptr += text_size;
   }
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp key;
      int comp_flag;
      png_charp lang;
      png_charp lang_key;
      png_charp text;
      int ret;

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

      png_push_crc_finish(png_ptr);

#if defined(PNG_MAX_MALLOC_64K)
      if (png_ptr->skip_length)
         return;
#endif

      key = png_ptr->current_text;

      for (lang = key; *lang; lang++)
         /* empty loop */ ;

      if (lang < key + png_ptr->current_text_size - 3)
         lang++;

      comp_flag = *lang++;
      lang++;     /* skip comp_type, always zero */

      for (lang_key = lang; *lang_key; lang_key++)
         /* empty loop */ ;
      lang_key++;        /* skip NUL separator */

      text=lang_key;
      if (lang_key < key + png_ptr->current_text_size - 1)
      {
        for (; *text; text++)
           /* empty loop */ ;
      }

      if (text < key + png_ptr->current_text_size)
         text++;

      text_ptr = (png_textp)png_malloc(png_ptr,
         (png_uint_32)png_sizeof(png_text));
      text_ptr->compression = comp_flag + 2;
      text_ptr->key = key;
      text_ptr->lang = lang;
      text_ptr->lang_key = lang_key;
      text_ptr->text = text;
      text_ptr->text_length = 0;
      text_ptr->itxt_length = png_strlen(text);

      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);

      png_ptr->current_text = NULL;

      png_free(png_ptr, text_ptr);
      if (ret)
        png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
   }
}
コード例 #24
0
ファイル: pngpread.c プロジェクト: 111111111/AROMA-Installer
/* This function is called when we haven't found a handler for this
 * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
 * name or a critical chunk), the chunk is (currently) silently ignored.
 */
void /* PRIVATE */
png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
   length)
{
   png_uint_32 skip = 0;

   if (!(png_ptr->chunk_name[0] & 0x20))
   {
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
         PNG_HANDLE_CHUNK_ALWAYS
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
         && png_ptr->read_user_chunk_fn == NULL
#endif
         )
#endif
         png_chunk_error(png_ptr, "unknown critical chunk");

      info_ptr = info_ptr; /* To quiet some compiler warnings */
   }

#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   {
#ifdef PNG_MAX_MALLOC_64K
      if (length > (png_uint_32)65535L)
      {
          png_warning(png_ptr, "unknown chunk too large to fit in memory");
          skip = length - (png_uint_32)65535L;
          length = (png_uint_32)65535L;
      }
#endif
      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
                 (png_charp)png_ptr->chunk_name, 
                 png_sizeof(png_ptr->unknown_chunk.name));
      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
        = '\0';

      png_ptr->unknown_chunk.size = (png_size_t)length;

      if (length == 0)
         png_ptr->unknown_chunk.data = NULL;

      else
      {
         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
            (png_uint_32)length);
         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
      }

#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
      if (png_ptr->read_user_chunk_fn != NULL)
      {
         /* Callback to user unknown chunk handler */
         int ret;
         ret = (*(png_ptr->read_user_chunk_fn))
           (png_ptr, &png_ptr->unknown_chunk);

         if (ret < 0)
            png_chunk_error(png_ptr, "error in user chunk");

         if (ret == 0)
         {
            if (!(png_ptr->chunk_name[0] & 0x20))
               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
                    PNG_HANDLE_CHUNK_ALWAYS)
                  png_chunk_error(png_ptr, "unknown critical chunk");
            png_set_unknown_chunks(png_ptr, info_ptr,
               &png_ptr->unknown_chunk, 1);
         }
      }

      else
#endif
        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
      png_free(png_ptr, png_ptr->unknown_chunk.data);
      png_ptr->unknown_chunk.data = NULL;
   }

   else
#endif
      skip=length;
   png_push_crc_skip(png_ptr, skip);
}
コード例 #25
0
ファイル: ImageIO.hpp プロジェクト: beiko-lab/gengis
		/**
		* @brief Write image data to file as PNG
		* @param filename Name of output file.
		* @param img Image data.
		* @param width Width of image.
		* @param height Height of image.
		*/
		static void WritePNG(const std::string &filename, const byte *img, const int width, const int height)
		{
			FILE *fp;
			png_structp png_ptr;
			png_infop info_ptr;

			/* open the file */
			fp = fopen(filename.c_str(), "wb");
			if (fp == NULL) {
				throw std::string("Cannot create file \"") + filename + std::string("\"");
			}

			/* Create and initialize the png_struct with the desired error handler
			* functions.  If you want to use the default stderr and longjump method,
			* you can supply NULL for the last three parameters.  We also check that
			* the library version is compatible with the one used at compile time,
			* in case we are using dynamically linked libraries.  REQUIRED.
			*/
			png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
				NULL, NULL, NULL);

			if (png_ptr == NULL) {
				fclose(fp);
				throw std::string("Cannot create PNG write structure for file \"") + filename + std::string("\"");
			}

			/* Allocate/initialize the image information data.  REQUIRED */
			info_ptr = png_create_info_struct(png_ptr);
			if (info_ptr == NULL) {
				fclose(fp);
				png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
				throw std::string("Out of memory in RGBA::PNG::Write()");
			}

			/* Set error handling.  REQUIRED if you aren't supplying your own
			* error handling functions in the png_create_write_struct() call.
			*/
			if (setjmp(png_jmpbuf(png_ptr)))
			{
				/* If we get here, we had a problem reading the file */
				fclose(fp);
				png_destroy_write_struct(&png_ptr, &info_ptr);
				throw std::string("Could not set up error handling for PNG");
			}

			/* set up the output control if you are using standard C streams */
			png_init_io(png_ptr, fp);

			/* This is the easy way.  Use it if you already have all the
			* image info living info in the structure.  You could "|" many
			* PNG_TRANSFORM flags into the png_transforms integer here.
			*/
			//   png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);


			/* This is the hard way */

			/* Set the image information here.  Width and height are up to 2^31,
			* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
			* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
			* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
			* or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
			* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
			* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
			*/
			png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
				PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

			/* Write the file header information.  REQUIRED */
			png_write_info(png_ptr, info_ptr);

			/* If you want, you can write the info in two steps, in case you need to
			* write your private chunk ahead of PLTE:
		    *
		    *   png_write_info_before_PLTE(write_ptr, write_info_ptr);
		    *   write_my_chunk();
		    *   png_write_info(png_ptr, info_ptr);
		    *
		    * However, given the level of known- and unknown-chunk support in 1.1.0
		    * and up, this should no longer be necessary.
		    */

			/* Once we write out the header, the compression type on the text
			* chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
			* PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
			* at the end.
			*/

			/* set up the transformations you want.  Note that these are
			* all optional.  Only call them if you want them.
			*/

			/* The easiest way to write the image (you may have a different memory
			* layout, however, so choose what fits your needs best).  You need to
			* use the first method if you aren't handling interlacing yourself.
			*/
			png_bytep *row_pointers = new png_bytep[height];

			if( (png_uint_32)height > (png_uint_32)(PNG_UINT_32_MAX/png_sizeof(png_bytep)) ) {
				fclose(fp);
				png_destroy_write_struct(&png_ptr, &info_ptr);
				throw std::string("Image is too tall to process in memory");
			}

			for(int k = 0; k < height; k++)
				row_pointers[k] = (byte*)img + k*width*4;

			/* write out the entire image data in one call */
			png_write_image(png_ptr, row_pointers);

			/* You can write optional chunks like tEXt, zTXt, and tIME at the end
			* as well.  Shouldn't be necessary in 1.1.0 and up as all the public
			* chunks are supported and you can use png_set_unknown_chunks() to
			* register unknown chunks into the info structure to be written out.
			*/

			/* It is REQUIRED to call this to finish writing the rest of the file */
			png_write_end(png_ptr, info_ptr);

			/* clean up after the write, and free any memory allocated */
			png_destroy_write_struct(&png_ptr, &info_ptr);

			delete[] row_pointers;
			row_pointers = NULL;

			/* close the file */
			fclose(fp);
		}
コード例 #26
0
ファイル: hmpng.c プロジェクト: AlbertVeli/heightmap
bool save_heightmap_png(long double lat, long double lon, long double span_h, long double span_w, const char *outfile)
{
   int x1, x2, y1, y2;
   bool ret = false;
   FILE *fp = NULL;
   png_structp png_ptr = NULL;
   png_infop info_ptr = NULL;
   size_t x, y, w, h, skip;
   png_bytepp row_pointers;
   png_bytep row;
   int16_t elevation, height;

   /* Pointer to humongous (7GB) S_MAPW x S_MAPH 16-bit map data (see map.c) */
   int16_t *mapp = (int16_t *)map[0];

   /* Map longitude/latidude to pixel coordinates in source image */
   x1 = ((lon + 180.0) / (long double)360) * S_MAPW;
   x2 = (((lon + span_w) + 180.0) / (long double)360) * S_MAPW - 1;
   y1 = ((90 - lat) / (long double)180) * S_MAPH;
   y2 = ((90 - (lat - span_h)) / (long double)180) * S_MAPH - 1;

   w = x2 - x1 + 1;
   h = y2 - y1 + 1;

   printf("%s: %dx%d ... ", outfile, (int)w, (int)h);
   fflush(stdout);

   /* Advance mapp to first pixel */
   mapp += (uint64_t)x1 + (uint64_t)S_MAPW * (uint64_t)y1;

   /* Skip this many int16_t:s to get to next line */
   skip = S_MAPW - w;

   /* libpng stuff below */

   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (png_ptr == NULL) {
      goto out;
   }

   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL) {
      png_destroy_write_struct(&png_ptr, NULL);
      goto out;
   }

   if (setjmp(png_jmpbuf(png_ptr))) {
      png_destroy_write_struct(&png_ptr, &info_ptr);
      goto out;
   }

   /* Specify 16-bit grayscale in png header */
   png_set_IHDR(png_ptr, info_ptr,
                w, h,
                16,
                PNG_COLOR_TYPE_GRAY,
                PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);


   /* Alloc mem for png image data */
   row_pointers = (png_bytepp)png_malloc(png_ptr, h * png_sizeof(png_bytep));
   for (y = 0; y < h; y++) {
      row_pointers[y] = png_malloc(png_ptr, w * 2);
   }

   /* Copy image data from mapp to row_pointers */
   for (y = 0; y < h; y++) {
      row = row_pointers[y];
      for (x = 0; x < w; x++) {

         /* Read 2 big endian source bytes */
         elevation = *mapp++;

         /* Clamp negative heights to 0 */
         height = ntohs(elevation); /* swap bytes if little endian */
         if (height < 0) {
            elevation = 0;
         }

         /* Write 2 bytes to destination */
         *row++ = (png_byte)(elevation & 0xff);
         *row++ = (png_byte)(elevation >> 8);
      }
      mapp += skip;
   }

   /* Write image data to fp */

   if (!(fp = fopen(outfile, "w"))) {
      perror(outfile);
      goto out2;
   }

   png_init_io(png_ptr, fp);
   png_set_rows(png_ptr, info_ptr, row_pointers);
   png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

   ret = true;

 out2:

   /* Cleanup. */
   for (y = 0; y < h; y++) {
      png_free(png_ptr, row_pointers[y]);
   }
   png_free(png_ptr, row_pointers);
   png_destroy_write_struct(&png_ptr, &info_ptr);

   if (fp) {
      fclose(fp);
   }

 out:

   if (ret) {
      puts("ok");
   } else {
      puts("fail");
   }

   return ret;
}
コード例 #27
0
/* Free all memory used by the read (old method) */
void /* PRIVATE */
png_read_destroy(png_structp png_ptr, png_infop info_ptr,
    png_infop end_info_ptr)
{
#ifdef PNG_SETJMP_SUPPORTED
   jmp_buf tmp_jmp;
#endif
   png_error_ptr error_fn;
   png_error_ptr warning_fn;
   png_voidp error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
   png_free_ptr free_fn;
#endif

   png_debug(1, "in png_read_destroy");

   if (info_ptr != NULL)
      png_info_destroy(png_ptr, info_ptr);

   if (end_info_ptr != NULL)
      png_info_destroy(png_ptr, end_info_ptr);

   png_free(png_ptr, png_ptr->zbuf);
   png_free(png_ptr, png_ptr->big_row_buf);
   png_free(png_ptr, png_ptr->prev_row);
   png_free(png_ptr, png_ptr->chunkdata);
#ifdef PNG_READ_QUANTIZE_SUPPORTED
   png_free(png_ptr, png_ptr->palette_lookup);
   png_free(png_ptr, png_ptr->quantize_index);
#endif
#ifdef PNG_READ_GAMMA_SUPPORTED
   png_free(png_ptr, png_ptr->gamma_table);
#endif
#ifdef PNG_READ_BACKGROUND_SUPPORTED
   png_free(png_ptr, png_ptr->gamma_from_1);
   png_free(png_ptr, png_ptr->gamma_to_1);
#endif
   if (png_ptr->free_me & PNG_FREE_PLTE)
      png_zfree(png_ptr, png_ptr->palette);
   png_ptr->free_me &= ~PNG_FREE_PLTE;
#if defined(PNG_tRNS_SUPPORTED) || \
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   if (png_ptr->free_me & PNG_FREE_TRNS)
      png_free(png_ptr, png_ptr->trans_alpha);
   png_ptr->free_me &= ~PNG_FREE_TRNS;
#endif
#ifdef PNG_READ_hIST_SUPPORTED
   if (png_ptr->free_me & PNG_FREE_HIST)
      png_free(png_ptr, png_ptr->hist);
   png_ptr->free_me &= ~PNG_FREE_HIST;
#endif
#ifdef PNG_READ_GAMMA_SUPPORTED
   if (png_ptr->gamma_16_table != NULL)
   {
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
      for (i = 0; i < istop; i++)
      {
         png_free(png_ptr, png_ptr->gamma_16_table[i]);
      }
   png_free(png_ptr, png_ptr->gamma_16_table);
   }
#ifdef PNG_READ_BACKGROUND_SUPPORTED
   if (png_ptr->gamma_16_from_1 != NULL)
   {
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
      for (i = 0; i < istop; i++)
      {
         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
      }
   png_free(png_ptr, png_ptr->gamma_16_from_1);
   }
   if (png_ptr->gamma_16_to_1 != NULL)
   {
      int i;
      int istop = (1 << (8 - png_ptr->gamma_shift));
      for (i = 0; i < istop; i++)
      {
         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
      }
   png_free(png_ptr, png_ptr->gamma_16_to_1);
   }
#endif
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
   png_free(png_ptr, png_ptr->time_buffer);
#endif

   inflateEnd(&png_ptr->zstream);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   png_free(png_ptr, png_ptr->save_buffer);
#endif

#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
#ifdef PNG_TEXT_SUPPORTED
   png_free(png_ptr, png_ptr->current_text);
#endif /* PNG_TEXT_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

   /* Save the important info out of the png_struct, in case it is
    * being used again.
    */
#ifdef PNG_SETJMP_SUPPORTED
   png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
#endif

   error_fn = png_ptr->error_fn;
   warning_fn = png_ptr->warning_fn;
   error_ptr = png_ptr->error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
   free_fn = png_ptr->free_fn;
#endif

   png_memset(png_ptr, 0, png_sizeof(png_struct));

   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
   png_ptr->error_ptr = error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr->free_fn = free_fn;
#endif

#ifdef PNG_SETJMP_SUPPORTED
   png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
#endif

}
コード例 #28
0
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)
   {
      png_warning(png_ptr, "Cannot Allocate > 64K");
      ret = NULL;
   }
   else
#endif

   if (size != (size_t)size)
      ret = NULL;
   else if (size == (png_uint_32)65536L)
   {
      if (png_ptr->offset_table == NULL)
      {
         /* Try to see if we need to do any of this fancy stuff */
         ret = farmalloc(size);
         if (ret == NULL || ((png_size_t)ret & 0xffff))
         {
            int num_blocks;
            png_uint_32 total_size;
            png_bytep table;
            int i;
            png_byte huge * hptr;

            if (ret != NULL)
            {
               farfree(ret);
               ret = NULL;
            }

            if (png_ptr->zlib_window_bits > 14)
               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
            else
               num_blocks = 1;
            if (png_ptr->zlib_mem_level >= 7)
               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
            else
               num_blocks++;

            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;

            table = farmalloc(total_size);

            if (table == NULL)
            {
#ifndef PNG_USER_MEM_SUPPORTED
               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
                  png_error(png_ptr, "Out Of Memory."); /* Note "O", "M" */
               else
                  png_warning(png_ptr, "Out Of Memory.");
#endif
               return (NULL);
            }

            if ((png_size_t)table & 0xfff0)
            {
#ifndef PNG_USER_MEM_SUPPORTED
               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
                  png_error(png_ptr,
                    "Farmalloc didn't return normalized pointer");
               else
                  png_warning(png_ptr,
                    "Farmalloc didn't return normalized pointer");
#endif
               return (NULL);
            }

            png_ptr->offset_table = table;
            png_ptr->offset_table_ptr = farmalloc(num_blocks *
               png_sizeof(png_bytep));

            if (png_ptr->offset_table_ptr == NULL)
            {
#ifndef PNG_USER_MEM_SUPPORTED
               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
                  png_error(png_ptr, "Out Of memory."); /* Note "O", "m" */
               else
                  png_warning(png_ptr, "Out Of memory.");
#endif
               return (NULL);
            }

            hptr = (png_byte huge *)table;
            if ((png_size_t)hptr & 0xf)
            {
               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
            }
            for (i = 0; i < num_blocks; i++)
            {
               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
            }

            png_ptr->offset_table_number = num_blocks;
            png_ptr->offset_table_count = 0;
            png_ptr->offset_table_count_free = 0;
         }
      }

      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
      {
#ifndef PNG_USER_MEM_SUPPORTED
         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
            png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
         else
            png_warning(png_ptr, "Out of Memory.");
#endif
         return (NULL);
      }

      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
   }
   else
      ret = farmalloc(size);

#ifndef PNG_USER_MEM_SUPPORTED
   if (ret == NULL)
   {
      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
         png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
      else
         png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
   }
#endif

   return (ret);
}
コード例 #29
0
/* Alternate create PNG structure for reading, and allocate any memory
 * needed.
 */
png_structp PNGAPI
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */

#ifdef PNG_SETJMP_SUPPORTED
   volatile
#endif
   png_structp png_ptr;
   volatile int png_cleanup_needed = 0;

#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
   jmp_buf jmpbuf;
#endif
#endif

   int i;

   png_debug(1, "in png_create_read_struct");

#ifdef PNG_USER_MEM_SUPPORTED
   png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
      malloc_fn, mem_ptr);
#else
   png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
#endif
   if (png_ptr == NULL)
      return (NULL);

   /* Added at libpng-1.2.6 */
#ifdef PNG_USER_LIMITS_SUPPORTED
   png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
   png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
#  ifdef PNG_USER_CHUNK_CACHE_MAX
   /* Added at libpng-1.2.43 and 1.4.0 */
   png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
#  endif
#  ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
   /* Added at libpng-1.2.43 and 1.4.1 */
   png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
#  endif
#endif

#ifdef PNG_SETJMP_SUPPORTED
/* Applications that neglect to set up their own setjmp() and then
   encounter a png_error() will longjmp here.  Since the jmpbuf is
   then meaningless we abort instead of returning. */
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmpbuf))
#else
   if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
#endif
      PNG_ABORT();
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf));
#endif
#endif /* PNG_SETJMP_SUPPORTED */

#ifdef PNG_USER_MEM_SUPPORTED
   png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif

   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);

   if (user_png_ver)
   {
      i = 0;
      do
      {
         if (user_png_ver[i] != png_libpng_ver[i])
            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
      } while (png_libpng_ver[i++]);
    }
    else
         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;


    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
    {
       /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
       * we must recompile any applications that use any older library version.
       * For versions after libpng 1.0, we will be compatible, so we need
       * only check the first digit.
       */
      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
      {
#ifdef PNG_STDIO_SUPPORTED
         char msg[80];
         if (user_png_ver)
         {
           png_snprintf(msg, 80,
              "Application was compiled with png.h from libpng-%.20s",
              user_png_ver);
           png_warning(png_ptr, msg);
         }
         png_snprintf(msg, 80,
             "Application  is  running with png.c from libpng-%.20s",
             png_libpng_ver);
         png_warning(png_ptr, msg);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
         png_ptr->flags = 0;
#endif
         png_warning(png_ptr,
            "Incompatible libpng version in application and library");

         png_cleanup_needed = 1;
      }
   }

   if (!png_cleanup_needed)
   {
   /* Initialize zbuf - compression buffer */
   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
   png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr,
     png_ptr->zbuf_size);
   if (png_ptr->zbuf == NULL)
        png_cleanup_needed = 1;
   }
   png_ptr->zstream.zalloc = png_zalloc;
   png_ptr->zstream.zfree = png_zfree;
   png_ptr->zstream.opaque = (voidpf)png_ptr;

   if (!png_cleanup_needed)
   {
      switch (inflateInit(&png_ptr->zstream))
      {
         case Z_OK: /* Do nothing */ break;
         case Z_MEM_ERROR:
         case Z_STREAM_ERROR: png_warning(png_ptr, "zlib memory error");
            png_cleanup_needed = 1; break;
         case Z_VERSION_ERROR: png_warning(png_ptr, "zlib version error");
            png_cleanup_needed = 1; break;
         default: png_warning(png_ptr, "Unknown zlib error");
            png_cleanup_needed = 1;
      }
   }

   if (png_cleanup_needed)
   {
      /* Clean up PNG structure and deallocate any memory. */
      png_free(png_ptr, png_ptr->zbuf);
      png_ptr->zbuf = NULL;
#ifdef PNG_USER_MEM_SUPPORTED
      png_destroy_struct_2((png_voidp)png_ptr,
         (png_free_ptr)free_fn, (png_voidp)mem_ptr);
#else
      png_destroy_struct((png_voidp)png_ptr);
#endif
      return (NULL);
   }

   png_ptr->zstream.next_out = png_ptr->zbuf;
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

   png_set_read_fn(png_ptr, NULL, NULL);


   return (png_ptr);
}
コード例 #30
0
ファイル: Png.c プロジェクト: alexey-lysiuk/doom64ex-osx
cache Png_Create(int width, int height, int numpal, dPalette_t* pal,
				 int bits, cache data, int lump, int* size)
{
	int i = 0;
	int x = 0;
	int j = 0;
	cache image;
	cache out;
	cache* row_pointers;
	png_structp png_ptr;
	png_infop info_ptr;
	png_colorp palette;

	// setup png pointer
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
	if(png_ptr == NULL)
	{
		WGen_Complain("Png_Create: Failed getting png_ptr");
		return NULL;
	}

	// setup info pointer
	info_ptr = png_create_info_struct(png_ptr);
	if(info_ptr == NULL)
	{
		png_destroy_write_struct(&png_ptr, NULL);
		WGen_Complain("Png_Create: Failed getting info_ptr");
		return NULL;
	}

	// what does this do again?
	if(setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_write_struct(&png_ptr, &info_ptr);
		WGen_Complain("Png_Create: Failed on setjmp");
		return NULL;
	}

	// setup custom data writing procedure
	png_set_write_fn(png_ptr, NULL, Png_WriteData, NULL);

	// setup image
	png_set_IHDR(
		png_ptr,
		info_ptr,
		width,
		height,
		bits,
		PNG_COLOR_TYPE_PALETTE,
		PNG_INTERLACE_NONE,
		PNG_COMPRESSION_TYPE_BASE,
		PNG_FILTER_TYPE_DEFAULT);

	// setup palette
	palette = (png_colorp)Mem_Alloc((16 * numpal) * png_sizeof(png_color));

	// copy dPalette_t data over to png_colorp
	for(x = 0, j = 0; x < numpal; x++)
	{
		for(i = 0; i < 16; i++)
		{
			palette[j].red = pal[j].r;
			palette[j].green = pal[j].g;
			palette[j].blue = pal[j].b;
			j++;
		}
	}

    i = 0;

	// add palette to png
	png_set_PLTE(png_ptr, info_ptr, palette, (16 * numpal));

    // set transparent index
    if(palette[0].red == 0 && palette[0].green == 0 && palette[0].blue == 0)
    {
        char tmp[9];

        strncpy(tmp, romWadFile.lump[lump].name, 8);
        tmp[0] -= (char)0x80;
        tmp[8] = 0;

        // Exempt these lumps
        if(strcmp(tmp, "FIRE") && /*strcmp(tmp, "USLEGAL") &&
            strcmp(tmp, "TITLE") &&*/ strcmp(tmp, "EVIL") &&
            /*strcmp(tmp, "IDCRED1") && strcmp(tmp, "WMSCRED1") &&*/
            strcmp(tmp, "SPACE") && strcmp(tmp, "CLOUD") &&
            strcmp(tmp, "FINAL"))
            png_set_tRNS(png_ptr, info_ptr, (png_bytep)&i, 1, NULL);
    }

	// add png info to data
	png_write_info(png_ptr, info_ptr);

	// add offset chunk if png is a sprite
	if(INSPRITELIST(lump))
	{
		for(i = 0; i < spriteExCount; i++)
		{
			if(exSpriteLump[i].lumpRef == lump)
			{
				int offs[2];

				offs[0] = WGen_Swap32(exSpriteLump[i].sprite.offsetx);
				offs[1] = WGen_Swap32(exSpriteLump[i].sprite.offsety);

				png_write_chunk(png_ptr, "grAb", (byte*)offs, 8);
				break;
			}
		}
	}

	// setup packing if needed
	png_set_packing(png_ptr);
	png_set_packswap(png_ptr);

	// copy data over
	image = data;
	row_pointers = (cache*)Mem_Alloc(sizeof(byte*) * height);

	for(i = 0; i < height; i++)
	{
		row_pointers[i] = (cache)Mem_Alloc(width);
		if(bits == 4)
		{
			for(j = 0; j < width; j += 2)
			{
				row_pointers[i][j] = *image & 0xf;
				row_pointers[i][j+1] = *image >> 4;
				image++;
			}
		}
		else
		{
			for(j = 0; j < width; j++)
			{
				row_pointers[i][j] = *image;
				image++;
			}
		}

		png_write_rows(png_ptr, &row_pointers[i], 1);
	}