Exemplo n.º 1
0
decoder::decoder(std::streambuf *sbuf, info &i)
  : input_(sbuf),
    png_(png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)),
    info_(png_create_info_struct(png_)),
    end_(png_create_info_struct(png_))
{
  png_byte header[magic_];
  input_->sgetn((char*)header, magic_);
  if (png_sig_cmp(header, 0, magic_)) throw std::runtime_error("Not a PNG file");

  png_set_sig_bytes(png_, magic_);
  png_set_read_fn(png_, input_, decoder_read);
  png_set_error_fn(png_, input_, decoder_error, decoder_warning);
  png_set_read_status_fn(png_, 0);
  png_read_info(png_, info_);
  png_uint_32 w, h;
  int d, c, in, co, f;
  png_get_IHDR(png_, info_, &w, &h, &d, &c, &in, &co, &f);  
  i.width = w;
  i.height = h;
  i.rowbytes = png_get_rowbytes(png_, info_);
  i.depth = d;
  i.colortype = static_cast<color_type>(c);
  i.compression = co;
  i.filter = f;
  i.interlace = static_cast<interlace_type>(in);
}
Exemplo n.º 2
0
char* readpng_image(char* filename, int* width, int* height, int *alpha)
{
  FILE* fp = fopen(filename, "rb");
  const int number = 8;
  png_structp png_ptr;
  png_infop info_ptr, end_info;
  png_bytepp row_pointers;
  unsigned char header[8];
  int is_png;
  int colour_type, bit_depth, image_width, image_height;
  char* pixels;
  int x, y;
  int nchannels;

  if (!fp)
  {
    fprintf(stderr, "Can't load file %s\n", filename);
    return 0;
  }
  
  fread(header, 1, number, fp);
  is_png = !png_sig_cmp(header, 0, number);
  if (!is_png)
  {
    fprintf(stderr, "File %s doesn't look like a PNG\n", filename);
    fclose(fp);
    return 0;
  }
  
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
    (png_voidp)NULL, NULL, NULL);

  if (!png_ptr)
  {
    fprintf(stderr, "Problem creating PNG read struct for %s\n", filename);
    fclose(fp);
    return 0;
  }
  
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    fprintf(stderr, "Problem creating PNG info struct for %s\n", filename);
    fclose(fp);
    return 0;
  }
  
  end_info = png_create_info_struct(png_ptr);
  if (!end_info)
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    fprintf(stderr, "Problem creating PNG end struct for %s\n", filename);
    fclose(fp);
    return 0;
  }
  
  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    fprintf(stderr, "Problem loading PNG %s\n", filename);
    fclose(fp);
    return 0;
  }
  
  png_init_io(png_ptr, fp);
  
  png_set_sig_bytes(png_ptr, number);
  
  png_set_read_status_fn(png_ptr, read_row_callback);
  
  png_read_info(png_ptr, info_ptr);
  
  colour_type = png_get_color_type(png_ptr, info_ptr);
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  image_width = png_get_image_width(png_ptr, info_ptr);
  image_height = png_get_image_height(png_ptr, info_ptr);
  
  if (colour_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
    png_set_expand(png_ptr);
  
  /* update stuff */
  png_read_update_info(png_ptr, info_ptr);
  
  /* now image data (width, height) etc is ready to be used */
  fprintf(stderr, "Reading image: %dx%dx%d\n",
    image_width, image_height, bit_depth);
  
  switch (colour_type)
    {
    case PNG_COLOR_TYPE_RGB:
      nchannels = 3;
      *alpha = 0;
      break;
    case PNG_COLOR_TYPE_RGBA:
      nchannels = 4;
      *alpha = 1;
      break;
    default:
      abort ();
    }
  
  row_pointers = calloc(image_height, sizeof(png_bytepp));
  for (y=0; y<image_height; y++)
  {
    /* FIXME number of channels */
    row_pointers[y] = malloc (nchannels * image_width);
  }
  
  png_read_image(png_ptr, row_pointers);
  
  png_read_end(png_ptr, end_info);
  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  
  pixels = malloc (nchannels * image_width * image_height);
  
  for (y = 0; y < image_height; y++)
  {
    char* destrow = &pixels[y * image_width * nchannels];
    unsigned char* srcrow = row_pointers[y];

    switch (colour_type)
      {
      case PNG_COLOR_TYPE_RGB:
	for (x = 0; x < image_width * 3; x++)
	  destrow[x] = srcrow[x];
	break;
      case PNG_COLOR_TYPE_RGBA:
	for (x = 0; x < image_width * 4; x++)
	  destrow[x] = srcrow[x];
	break;
      default:
        abort ();
      }
  }
  
  for (y = 0; y < image_height; y++)
  {
    free (row_pointers[y]);
  }
  free (row_pointers);

  if (width) *width = image_width;
  if (height) *height = image_height;
    
  return pixels;
}
Exemplo n.º 3
0
/* 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
      }
   }
Exemplo n.º 4
0
int main( int argc, char *argv[] ) {
	int f, rowbytes;
	char buf[256];
	static FILE *fpout;  /* "static" prevents setjmp corruption */
	png_structp write_ptr;
	png_infop write_info_ptr, end_info_ptr;
	png_bytep row_buf, here;
	png_uint_32 y;
	png_textp text_ptr, new_text_ptr;
	int num_text;

	int interlace_type, compression_type, filter_type, bit_depth, color_type;
	int it, ct, ft, bd, clrt;
	png_uint_32 width, height, w, h;

	int duration;

	if( argc < 4 ) {
		printf( "makeanim v0.2\nusage: makeanim <duration in milliseconds> <input files ...> <output file>\n" );
		printf( "example: makeanim 1500 a00.png a01.png a02.png a03.png a04.png a.anim\n" );
		return 1;
		}

	duration = atoi( argv[1] );
	if( duration < 1 ) {
		printf( "duration is incorrect\n" );
		return 1;
		}

	numfiles = argc - 3;
	input = (struct inputstruct *)malloc( sizeof( struct inputstruct ) * numfiles );
	if( !input ) return 1;

	for( f = 0; f < numfiles; f++ ) {
		input[f].name = argv[f + 2];
		printf( "opening file %d, \"%s\"\n", f, input[f].name );

		/* open the file handle */
		input[f].file = fopen( input[f].name, "rb" );
		if( input[f].file == NULL ) {
			printf( "fopen() failed\n" );
			return 1;
			}

		/* check if it's PNG */
		if( fread( buf, 1, 8, input[f].file ) != 8 ) {
			printf( "fread() failed for file \"%s\"\n", input[f].name );
			return 1;
			}
		if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) {
			printf( "not a PNG file\n" );
			return 1;
			}
		fseek( input[f].file, 0, SEEK_SET );

		/* allocate read structure */
		input[f].read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL );
		if( input[f].read_ptr == NULL ) {
			printf( "png_create_read_struct() failed\n" );
			return 1;
			}
		
		/* allocate read info structure */
		input[f].read_info_ptr = png_create_info_struct( input[f].read_ptr );
		if( input[f].read_info_ptr == NULL ) {
			printf( "png_create_info_struct() failed\n" );
			return 1;
			}


		/* set error handler code */
		if( setjmp( input[f].read_ptr->jmpbuf ) ) {
			printf( "libpng read error\n" );
			return 1;
			}

		/* initialize stream */
		png_init_io( input[f].read_ptr, input[f].file );
		png_set_read_status_fn( input[f].read_ptr, NULL );

		/* read png info struct */
		png_read_info( input[f].read_ptr, input[f].read_info_ptr );

		/* get the info */
		if( !png_get_IHDR( input[f].read_ptr, input[f].read_info_ptr, &w, &h, &bd, &clrt, &it, &ct, &ft ) ) {
			printf( "png_get_IHDR() failed\n" );
			return 1;
			}

		/* save the info of the first frame */
		if( f == 0 ) {
			width = w;
			height = h;
			bit_depth = bd;
			color_type = clrt;
			interlace_type = it;
			compression_type = ct;
			filter_type = ft;
			}
		/* compare all other frames to first frame */
		else if( (w != width) ||
				(h != height) ||
				(bd != bit_depth) ||
				(clrt != color_type) ||
				(it != interlace_type) ||
				(ct != compression_type) ||
				(ft != filter_type) ) {
			if( w != width ) printf( "width is different\n" );
			if( h != height ) printf( "height  is different\n" );
			if( bd != bit_depth ) printf( "bit depth is different\n" );
			if( clrt != color_type ) printf( "color type is different\n" );
			if( it != interlace_type ) printf( "interlace type is different\n" );
			if( ct != compression_type ) printf( "compression type is different\n" );
			if( ft != filter_type ) printf( "filter type is different\n" );
			return 1;
			}
		}
	
	row_buf = (png_bytep)NULL;
	
	/* open output file */
	printf( "opening file \"%s\"\n", argv[numfiles + 2] );
	fpout = fopen( argv[numfiles + 2], "wb" );
	if( fpout == NULL ) {
		printf( "fopen() failed\n" );
		return 1;
		}

	/* allocate write structure */
	write_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL );

	/* allocate info structures */
	write_info_ptr = png_create_info_struct( write_ptr );
	end_info_ptr = png_create_info_struct( write_ptr );

	/* error handling */
	if( setjmp( write_ptr->jmpbuf ) ) {
		printf( "libpng write error\n" );
		return 1;
		}

	/* initialize output stream */
	png_init_io( write_ptr, fpout );
	png_set_write_status_fn( write_ptr, NULL );

	/* set info */
	png_set_IHDR( write_ptr, write_info_ptr, width * numfiles, height, bit_depth, color_type, PNG_INTERLACE_NONE, compression_type, filter_type);

	/* image characteristics */
	{
		png_color_16p background;
		double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
		double gamma;
		int intent;
		png_uint_16p hist;
		png_uint_32 offset_x, offset_y;
		int unit_type;
		png_charp purpose, units;
		png_charpp params;
		png_int_32 X0, X1;
		int type, nparams;
		png_uint_32 res_x, res_y;
		png_colorp palette;
		int num_palette;
		png_color_8p sig_bit;
		png_bytep trans;
		int num_trans;
		png_color_16p trans_values;

		/* background color */
		if( png_get_bKGD( input[0].read_ptr, input[0].read_info_ptr, &background ) ) {
			png_set_bKGD( write_ptr, write_info_ptr, background );
			}

		if( png_get_cHRM( input[0].read_ptr, input[0].read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ) ) {
			png_set_cHRM( write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y );
			}

		/* gamma */
		if( png_get_gAMA( input[0].read_ptr, input[0].read_info_ptr, &gamma ) ) {
			png_set_gAMA( write_ptr, write_info_ptr, gamma );
			}

		/* rendering intent */
		if( png_get_sRGB( input[0].read_ptr, input[0].read_info_ptr, &intent ) ) {
			png_set_sRGB( write_ptr, write_info_ptr, intent );
			}

		/* Histogram */
		if( png_get_hIST( input[0].read_ptr, input[0].read_info_ptr, &hist ) ) {
			png_set_hIST( write_ptr, write_info_ptr, hist );
			}

		/* offsets */
		if( png_get_oFFs( input[0].read_ptr, input[0].read_info_ptr, &offset_x, &offset_y, &unit_type ) ) {
			png_set_oFFs( write_ptr, write_info_ptr, offset_x, offset_y, unit_type );
			}

		if( png_get_pCAL( input[0].read_ptr, input[0].read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, &params ) ) {
			png_set_pCAL( write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params );
			}

		/* pixel density */
		if( png_get_pHYs( input[0].read_ptr, input[0].read_info_ptr, &res_x, &res_y, &unit_type ) ) {
			png_set_pHYs( write_ptr, write_info_ptr, res_x, res_y, unit_type );
			}

		/* text chunks */
/*		if( png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) > 0 ) {
			printf( "Handling %d tEXt/zTXt chunks\n", num_text );
			png_set_text( write_ptr, write_info_ptr, text_ptr, num_text );
			}
*/
		/* palette */
		if( png_get_PLTE( input[0].read_ptr, input[0].read_info_ptr, &palette, &num_palette ) ) {
			png_set_PLTE( write_ptr, write_info_ptr, palette, num_palette );
			}

		/* significant bits */
		if( png_get_sBIT( input[0].read_ptr, input[0].read_info_ptr, &sig_bit ) ) {
			png_set_sBIT( write_ptr, write_info_ptr, sig_bit );
			}

		/* transparency */
		if( png_get_tRNS( input[0].read_ptr, input[0].read_info_ptr, &trans, &num_trans, &trans_values ) ) {
			png_set_tRNS( write_ptr, write_info_ptr, trans, num_trans, trans_values );
			}
		}

	/* text chunks */
	num_text = 0;
	if( !png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) ) num_text = 0;
	new_text_ptr = (struct png_text_struct *)malloc( sizeof( struct png_text_struct ) * num_text + 1 );
	if( !new_text_ptr ) {
		printf( "malloc() failed\n" );
		return 1;
		}
	
	memcpy( new_text_ptr, text_ptr, sizeof( struct png_text_struct ) * num_text );

	snprintf( buf, 255, "SDL_anim %d %d %d", duration, width, numfiles );
	buf[255] = 0;
	new_text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
	new_text_ptr[num_text].key = "format";
	new_text_ptr[num_text].text = buf;
	new_text_ptr[num_text].text_length = strlen( buf );
	num_text++;
	png_set_text( write_ptr, write_info_ptr, new_text_ptr, num_text );

	/* write info */
	png_write_info( write_ptr, write_info_ptr );

	/* allocate buffer */
	rowbytes = png_get_rowbytes( input[0].read_ptr, input[0].read_info_ptr );
	row_buf = (png_bytep)png_malloc( write_ptr, rowbytes * numfiles );
	if( row_buf == NULL ) {
		printf( "png_malloc() failed\n" );
		return 1;
		}

	/* copy raw data */
	for( y = 0; y < height; y++ ) {
		/* grab a scanline from each file */
		here = row_buf;
		for( f = 0; f < numfiles; f++ ) {
			png_read_rows( input[f].read_ptr, (png_bytepp)&here, (png_bytepp)NULL, 1 );
			here += rowbytes;
			}
		/* write the long scanline */
		png_write_rows( write_ptr, (png_bytepp)&row_buf, 1 );
		}

	/* end io */
	for( f = 0; f < numfiles; f++ ) png_read_end( input[f].read_ptr, end_info_ptr );
	png_write_end( write_ptr, end_info_ptr );

	/* cleanup */
	png_free( write_ptr, row_buf );
	for( f = 0; f < numfiles; f++ ) {
		png_destroy_read_struct( &input[f].read_ptr, &input[f].read_info_ptr, &end_info_ptr);
		fclose( input[f].file );
		}
	png_destroy_write_struct( &write_ptr, &write_info_ptr );
	fclose( fpout );

	return 0;
	}
Exemplo n.º 5
0
/* Test one file */
int
test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
   static FILE *fpin, *fpout;  /* "static" prevents setjmp corruption */
   png_structp read_ptr, write_ptr;
   png_infop read_info_ptr, write_info_ptr, end_info_ptr, write_end_info_ptr;
   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 jmp_env;
#endif
#endif

   char inbuf[256], outbuf[256];

   row_buf = (png_bytep)NULL;

   if ((fpin = fopen(inname, "rb")) == NULL)
   {
      fprintf(STDERR, "Could not find input file %s\n", inname);
      return (1);
   }

   if ((fpout = fopen(outname, "wb")) == NULL)
   {
      fprintf(STDERR, "Could not open output file %s\n", outname);
      fclose(fpin);
      return (1);
   }

   png_debug(0, "Allocating read and write structures\n");
#ifdef PNG_USER_MEM_SUPPORTED
   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, png_default_error,
       png_default_warning);
#endif
#ifdef PNG_USER_MEM_SUPPORTED
   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, png_default_error,
       png_default_warning);
#endif
   png_debug(0, "Allocating read_info, write_info and end_info structures\n");
   read_info_ptr = png_create_info_struct(read_ptr);
   write_info_ptr = png_create_info_struct(write_ptr);
   end_info_ptr = png_create_info_struct(read_ptr);
   write_end_info_ptr = png_create_info_struct(write_ptr);
#ifdef PNG_USER_MEM_SUPPORTED
#endif

#ifdef PNG_SETJMP_SUPPORTED
   png_debug(0, "Setting jmp_env for read struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmp_env))
#else
   if (setjmp(png_jmp_env(read_ptr)))
#endif
   {
      fprintf(STDERR, "%s -> %s: libpng read 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);
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
      fclose(fpin);
      fclose(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmp_env(read_ptr),jmp_env,sizeof(jmp_buf));
#endif

   png_debug(0, "Setting jmp_env for write struct\n");
#ifdef USE_FAR_KEYWORD
   if (setjmp(jmp_env))
#else
   if (setjmp(png_jmp_env(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);
      png_destroy_write_struct(&write_ptr, &write_info_ptr);
      fclose(fpin);
      fclose(fpout);
      return (1);
   }
#ifdef USE_FAR_KEYWORD
   png_memcpy(png_jmp_env(write_ptr),jmp_env,sizeof(jmp_buf));
#endif
#endif

   png_debug(0, "Initializing input and output streams\n");
#if !defined(PNG_NO_STDIO)
   png_init_io(read_ptr, fpin);
   png_init_io(write_ptr, fpout);
#else
   png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
   png_set_write_fn(write_ptr, (png_voidp)fpout,  png_default_write_data,
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
      png_default_flush);
#else
      NULL);
#endif
#endif
   if(status_dots_requested == 1)
   {
      png_set_write_status_fn(write_ptr, write_row_callback);
      png_set_read_status_fn(read_ptr, read_row_callback);
   }
   else
   {
      png_set_write_status_fn(write_ptr, NULL);
      png_set_read_status_fn(read_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

#define HANDLE_CHUNK_IF_SAFE      2
#define HANDLE_CHUNK_ALWAYS       3
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
   png_set_keep_unknown_chunks(read_ptr, HANDLE_CHUNK_ALWAYS, NULL, 0);
#endif
#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
   png_set_keep_unknown_chunks(write_ptr, HANDLE_CHUNK_IF_SAFE, 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
      }
   }
Exemplo n.º 6
0
Arquivo: pngload.c Projeto: A600/xbmc
int
loadpng (char *file_name, int *w, int *h, unsigned int ***buf)
{
	FILE   *fp;
	png_uint_32 width, height;
	int     bit_depth,

		color_type, interlace_type, compression_type, filter_type;
	int     rowbytes;

	png_structp png_ptr;
	png_infop info_ptr;
	png_infop end_info;

	int     x, y;
	unsigned int **row_pointers;

	/* OUVERTURE DU FICHIER */

	fp = fopen (file_name, "rb");

	if (!fp) {
		// fprintf (stderr, "Couldn't open file\n");
		return 1;
	}

	/* CREATION DES STRUCTURES */
	png_ptr = png_create_read_struct
		(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL);
	if (!png_ptr) {
		fprintf (stderr, "Memory error\n");
		return 1;
	}

	info_ptr = png_create_info_struct (png_ptr);
	if (!info_ptr) {
		png_destroy_read_struct (&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
		fprintf (stderr, "Read error 1\n");
		return 1;
	}

	end_info = png_create_info_struct (png_ptr);
	if (!end_info) {
		png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);
		fprintf (stderr, "Read error 2\n");
		return 1;
	}

	/* CHARGEMENT DE L'IMAGE */
	if (setjmp (png_ptr->jmpbuf)) {
		png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
		fclose (fp);
		fprintf (stderr, "Erreur de chargement\n");
		return 1;
	}

	png_init_io (png_ptr, fp);
	png_set_read_status_fn (png_ptr, NULL);

	png_read_info (png_ptr, info_ptr);

	png_get_IHDR (png_ptr, info_ptr, &width, &height,
								&bit_depth, &color_type, &interlace_type,
								&compression_type, &filter_type);
/*
	printf ("taille : %dx%d\n",width,height);
	printf ("depth  : %d\n",bit_depth);
	printf ("color type : ");
	switch (color_type) {
		case PNG_COLOR_TYPE_GRAY:
			printf ("PNG_COLOR_TYPE_GRAY (bit depths 1, 2, 4, 8, 16)\n");
			break;
		case PNG_COLOR_TYPE_GRAY_ALPHA:
			printf ("PNG_COLOR_TYPE_GRAY_ALPHA (bit depths 8, 16)\n");
			break;
		case PNG_COLOR_TYPE_PALETTE:
			printf ("PNG_COLOR_TYPE_PALETTE (bit depths 1, 2, 4, 8)\n");
			break;
		case PNG_COLOR_TYPE_RGB:
			printf ("PNG_COLOR_TYPE_RGB (bit_depths 8, 16)\n");
			break;
		case PNG_COLOR_TYPE_RGB_ALPHA:
			printf ("PNG_COLOR_TYPE_RGB_ALPHA (bit_depths 8, 16)\n");
			break;
	}
  */
	// printf ("PNG_COLOR_MASK_ALPHA   : %x\n", PNG_COLOR_MASK_ALPHA);
	// printf ("PNG_COLOR_MASK_COLOR   : %x\n", PNG_COLOR_MASK_COLOR);
	// printf ("PNG_COLOR_MASK_PALETTE : %x\n", PNG_COLOR_MASK_PALETTE);

	if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
		png_set_palette_to_rgb (png_ptr);

	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
		png_set_expand_gray_1_2_4_to_8 (png_ptr);
	else if (color_type == PNG_COLOR_TYPE_GRAY ||
					 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
			png_set_gray_to_rgb (png_ptr);

	if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha (png_ptr);

	png_read_update_info (png_ptr, info_ptr);

//      printf ("channels : %d\n", png_get_channels (png_ptr, info_ptr));
	rowbytes = png_get_rowbytes (png_ptr, info_ptr);
//      printf ("rowbytes : %d\n", rowbytes);

	row_pointers = (unsigned int **) malloc (height * sizeof (unsigned int *));

	for (y = 0; y < height; y++)
		row_pointers[y] = (unsigned int *) malloc (4 * width);
	png_read_image (png_ptr, (png_bytepp) row_pointers);

	// for (y=0;y<height;y++) {
//              for (x=0;x<width;x++) {
//                      if (row_pointers[y][x] & 0xf000)
	// printf ("%x ",(((unsigned int**)row_pointers)[y][x])&0xf);
	// else
//                              printf (" ");
	// }
	// printf ("\n");
	// }

	png_read_end (png_ptr, end_info);
	png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);

	(*buf) = (unsigned int **) malloc (height * sizeof (void *));

	for (y = 0; y < height; y++) {
		(*buf)[y] = (unsigned int *) malloc (width * 4);
		for (x = 0; x < width; x++)
			(*buf)[y][x] = row_pointers[y][x];
	}
	*w = width;
	*h = height;

	return 0;
}
Exemplo n.º 7
0
int ExtractBits(PNG_CONST TCHAR *inname, PNG_CONST TCHAR *outname)
{
	static HANDLE fpin;
	static HANDLE fpout;  /* "static" prevents setjmp corruption */
	png_structp read_ptr;
	png_infop read_info_ptr, end_info_ptr;
	png_structp write_ptr = NULL;
	png_infop write_info_ptr = NULL;
	png_infop write_end_info_ptr = NULL;
	png_bytep row_buf;
	png_uint_32 y;
	png_uint_32 width, height;
	int num_pass, pass;
	int bit_depth, color_type;
	char inbuf[256], outbuf[256];
	row_buf = NULL;

	if ((fpin = CreateFile(inname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
	{
		fprintf(STDERR, "Could not find input file %s\n", inname);
		return (1);
	}

	if ((fpout = CreateFile(outname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
	{
		fprintf(STDERR, "Could not open output file %s\n", outname);
		FCLOSE(fpin);
		return (1);
	}

	png_debug(0, "Allocating read and write structures");
	read_ptr =
	    png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
	                           png_error_ptr_NULL, png_error_ptr_NULL);
	png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
	                 pngtest_warning);
	png_debug(0, "Allocating read_info, write_info and end_info structures");
	read_info_ptr = png_create_info_struct(read_ptr);
	end_info_ptr = png_create_info_struct(read_ptr);
	png_debug(0, "Setting jmpbuf for read struct");

	if (setjmp(png_jmpbuf(read_ptr)))
	{
		fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
		png_free(read_ptr, row_buf);
		row_buf = NULL;
		png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
		FCLOSE(fpin);
		FCLOSE(fpout);
		return (1);
	}

	png_debug(0, "Initializing input and output streams");
	png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);

	if (status_dots_requested == 1)
	{
		png_set_read_status_fn(read_ptr, read_row_callback);
	}
	else
	{
		png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
	}

	png_debug(0, "Reading info struct");
	png_read_info(read_ptr, read_info_ptr);
	png_debug(0, "Transferring info struct");
	{
		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,
			             color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
		}
	}
	{
		int intent;

		if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
			png_set_sRGB(write_ptr, write_info_ptr, intent);
	}
	{
		png_colorp palette;
		int num_palette;

		if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
			png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
	}
	{
		png_color_8p sig_bit;

		if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
			png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
	}
	{
		png_bytep trans;
		int num_trans;
		png_color_16p trans_values;

		if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
		                &trans_values))
		{
			int sample_max = (1 << read_info_ptr->bit_depth);

			/* libpng doesn't reject a tRNS chunk with out-of-range samples */
			if (!((read_info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
			        (int)trans_values->gray > sample_max) ||
			        (read_info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
			         ((int)trans_values->red > sample_max ||
			          (int)trans_values->green > sample_max ||
			          (int)trans_values->blue > sample_max))))
				png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
				             trans_values);
		}
	}
	png_debug(0, "Writing row data");
	num_pass = png_set_interlace_handling(read_ptr);

	for(pass = 0; pass < num_pass; pass++)
	{
		png_debug1(0, "Writing row data for pass %d", pass);

		for(y = 0; y < height; y++)
		{
			png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y);
			row_buf = (png_bytep)png_malloc(read_ptr,
			                                png_get_rowbytes(read_ptr, read_info_ptr));
			png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf,
			           png_get_rowbytes(read_ptr, read_info_ptr));
			png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
			png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y);
			png_free(read_ptr, row_buf);
			row_buf = NULL;
		}
	}

	png_debug(0, "Reading and writing end_info data");
	png_read_end(read_ptr, end_info_ptr);
	{
		png_uint_32 iwidth, iheight;
		iwidth = png_get_image_width(write_ptr, write_info_ptr);
		iheight = png_get_image_height(write_ptr, write_info_ptr);
		fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
		        (unsigned long)iwidth, (unsigned long)iheight);
	}
	png_debug(0, "Destroying data structs");
	png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr");
	png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
	png_debug(0, "Destruction complete.");
	FCLOSE(fpin);
	FCLOSE(fpout);
	png_debug(0, "Opening files for comparison");

	if ((fpin = CreateFile(inname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
	{
		fprintf(STDERR, "Could not find file %s\n", inname);
		return (1);
	}

	if ((fpout = CreateFile(outname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
	{
		fprintf(STDERR, "Could not find file %s\n", outname);
		FCLOSE(fpin);
		return (1);
	}

	for(;;)
	{
		DWORD num_in, num_out;
		READFILE(fpin, inbuf, 1, num_in);
		READFILE(fpout, outbuf, 1, num_out);

		if (num_in != num_out)
		{
			fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
			        inname, outname);

			if (wrote_question == 0)
			{
				fprintf(STDERR,
				        "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
				        inname, PNG_ZBUF_SIZE);
				fprintf(STDERR,
				        "\n   filtering heuristic (libpng default), compression");
				fprintf(STDERR,
				        " level (zlib default),\n   and zlib version (%s)?\n\n",
				        ZLIB_VERSION);
				wrote_question = 1;
			}

			FCLOSE(fpin);
			FCLOSE(fpout);
			return (0);
		}

		if (!num_in)
			break;

		if (png_memcmp(inbuf, outbuf, num_in))
		{
			fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);

			if (wrote_question == 0)
			{
				fprintf(STDERR,
				        "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
				        inname, PNG_ZBUF_SIZE);
				fprintf(STDERR,
				        "\n   filtering heuristic (libpng default), compression");
				fprintf(STDERR,
				        " level (zlib default),\n   and zlib version (%s)?\n\n",
				        ZLIB_VERSION);
				wrote_question = 1;
			}

			FCLOSE(fpin);
			FCLOSE(fpout);
			return (0);
		}
	}

	FCLOSE(fpin);
	FCLOSE(fpout);
	return (0);
}
Exemplo n.º 8
0
//---------------------------------------------------------------------------
void __fastcall TDeePNG::LoadFromStream(Classes::TStream * Stream)
{
	// LoadFromStream

	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_infop end_info = NULL;

	png_bytep *row_pointers = NULL;
	BYTE *image = NULL;

	png_uint_32 i;

	try
	{
		// create png_struct
		png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
			(png_voidp)this, DeePNG_error, DeePNG_warning,
			(png_voidp)this, DeePNG_malloc, DeePNG_free);

		// set read_chunk_callback
		png_set_read_user_chunk_fn(png_ptr,
			reinterpret_cast<void*>(this),
			PNG_read_chunk_callback);
		png_set_keep_unknown_chunks(png_ptr, 2, NULL, 0);
			// keep only if safe-to-copy chunks, for all unknown chunks

		// create png_info
		info_ptr = png_create_info_struct(png_ptr);

		// create end_info
		end_info = png_create_info_struct(png_ptr);

		// set stream input functions
		png_set_read_fn(png_ptr, (voidp)Stream, DeePNG_read_data);

		// set read_row_callback
		png_set_read_status_fn(png_ptr, DeePNG_read_row_callback);

		// call png_read_info
		png_read_info(png_ptr, info_ptr);

		// retrieve IHDR
		png_uint_32 width, height;
		int bit_depth, color_type, interlace_type, compression_type, filter_type;
		png_get_IHDR(png_ptr,info_ptr, &width, &height, &bit_depth, &color_type,
			&interlace_type, &compression_type, &filter_type);

		// expand palletted image which has transparent color, to 32bpp
		if (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS))
		{
			png_set_expand(png_ptr);
			color_type=PNG_COLOR_TYPE_RGB_ALPHA;
		}

		// analyse IHDR ( color_type )
		switch(color_type)
		{
		case PNG_COLOR_TYPE_GRAY_ALPHA:
			PixelFormat=pf32bit;
			break;
		case PNG_COLOR_TYPE_GRAY:
			// w/b
			SetGrayscalePalette(this,bit_depth);
			break;
		case PNG_COLOR_TYPE_PALETTE:
			SetColorDepth(this,bit_depth);
			break;
		case PNG_COLOR_TYPE_RGB_ALPHA:
			PixelFormat=pf32bit;
			break;
		case PNG_COLOR_TYPE_RGB:
			PixelFormat=pf24bit;
			break;
		default:
			throw EDeePNG("EDeePNG : Non-supported color type.");
		}

		// retrieve offset information
		png_int_32 offset_x, offset_y;
		int offset_unit_type;
		if(png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &offset_unit_type))
		{
			ofs_x = offset_x;
			ofs_y = offset_y;
			ofs_unit = offset_unit_type;
			ofs_set = true;
		}
		else
		{
			ofs_set = false;
		}

		// check size
		if(width>=65536 || height>=65536)
		{
			throw EDeePNG("EDeePNG : Too large image size.");
		}


		// retrieve palette
		if(color_type == PNG_COLOR_TYPE_PALETTE)
		{
			int num_palette;
			png_color *palette = NULL;
			png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);

			int i;
		#pragma pack(push, 1)
			struct
			{
				WORD	palVersion;
				WORD	palNumEntries;
				PALETTEENTRY entry[256];
			} pal;
		#pragma pack(pop)
			pal.palVersion = 0x300;
			pal.palNumEntries = num_palette;
			for(i = 0; i < num_palette; i++)
			{
				pal.entry[i].peRed = palette[i].red;
				pal.entry[i].peGreen = palette[i].green;
				pal.entry[i].peBlue = palette[i].blue;
				pal.entry[i].peFlags = 0;
			}
			Palette = CreatePalette((const LOGPALETTE*)&pal);
		}

		// collapse 16bit precision data to 8bit
		if(bit_depth == 16) png_set_strip_16(png_ptr);

		// change color component order
		if (color_type == PNG_COLOR_TYPE_RGB ||
			color_type == PNG_COLOR_TYPE_RGB_ALPHA)
				png_set_bgr(png_ptr);

		// call png_read_update_info ...
		png_read_update_info(png_ptr, info_ptr);

		// set size
		Width=width, Height=height;

		// allocate memory for row_pointers
		row_pointers = new png_bytep[height];
		png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
		image = new BYTE[rowbytes*height];
		for(i = 0;i < height; i++)
		{
			row_pointers[i] = image + i*rowbytes;
		}

		// load image
		png_read_image(png_ptr, row_pointers);

		// finish loading image
		png_read_end(png_ptr, info_ptr);

		// set image to ScanLines

		BYTE *imageptr = image;
		if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		{
			// IA IA IA ....

			for(i = 0; i < height; i++)
			{
				BYTE *scanptr = (BYTE*)ScanLine[i];
				png_uint_32 j;
				for(j = 0; j < width; j++)
				{
					BYTE i = *(imageptr++);
					scanptr[0] = i;
					scanptr[1] = i;
					scanptr[2] = i;
					scanptr[3] = *(imageptr++);
					scanptr += 4;
				}
			}
		}
		else
		{
			// intact copy

			for(i = 0; i < height; i++)
			{
				BYTE *scanptr = (BYTE*)ScanLine[i];
				memcpy(scanptr, imageptr, rowbytes);
				imageptr += rowbytes;
			}


		}
	}
	catch(...)
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		if(row_pointers) delete [] row_pointers;
		if(image) delete [] image;
		throw;
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	if(row_pointers) delete [] row_pointers;
	if(image) delete [] image;
}