示例#1
0
    void set_filler(uint_32 filler, filler_type type) const
    {
        TRACE_IO_TRANSFORM("png_set_filler: filler=%08x, type=%d\n",
                           filler, type);

        png_set_filler(m_png, filler, type);
    }
/* Since libpng forces us to use longjmp, this function shouldn't create any C++
 * objects, and needs to watch out for memleaks. */
static bool RageSurface_Save_PNG( RageFile &f, char szErrorbuf[1024], RageSurface *pImgIn )
{
	bool bAlpha = pImgIn->format->Amask != 0;
	RageSurface *pImg;
	bool bDeleteImg = RageSurfaceUtils::ConvertSurface( pImgIn, pImg, pImgIn->w, pImgIn->h, 32,
			Swap32BE( 0xFF000000 ),
			Swap32BE( 0x00FF0000 ),
			Swap32BE( 0x0000FF00 ),
			Swap32BE( 0x000000FF ) );
	if( !bDeleteImg )
		pImg = pImgIn;

	error_info error;
	error.szErr = szErrorbuf;

	png_struct *pPng = png_create_write_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
	if( pPng == NULL )
	{
		sprintf( szErrorbuf, "creating png_create_write_struct failed");
		return false;
	}

	png_info *pInfo = png_create_info_struct(pPng);
	if( pInfo == NULL )
	{
		png_destroy_read_struct( &pPng, NULL, NULL );
		if( bDeleteImg )
			delete pImg;
		sprintf( szErrorbuf, "creating png_create_info_struct failed");
		return false;
	}

	if( setjmp(png_jmpbuf(pPng)) )
	{
		png_destroy_read_struct( &pPng, &pInfo, NULL );
		return false;
	}

	png_set_write_fn( pPng, &f, RageFile_png_write, RageFile_png_flush );
	png_set_compression_level( pPng, 1 );

	png_set_IHDR( pPng, pInfo, pImg->w, pImg->h, 8, bAlpha? PNG_COLOR_TYPE_RGBA:PNG_COLOR_TYPE_RGB,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );

	png_write_info( pPng, pInfo );
	png_set_filler( pPng, 0, PNG_FILLER_AFTER );

	png_byte *pixels = (png_byte *) pImg->pixels;
	for( int y = 0; y < pImg->h; y++ )
		png_write_row( pPng, pixels + pImg->pitch*y );

	png_write_end( pPng, pInfo );
	png_destroy_write_struct( &pPng, &pInfo );

	/* Free the converted image. */
	if( bDeleteImg )
		delete pImg;

	return true;
}
示例#3
0
文件: pngtrans.c 项目: kvakvs/hge
/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
   png_debug(1, "in png_set_add_alpha\n");
   png_set_filler(png_ptr, filler, filler_loc);
   png_ptr->transformations |= PNG_ADD_ALPHA;
}
示例#4
0
    void writePNG(const QImage& image)
    {
#ifndef QT_LSB
        // LSB disallows accessing the info_ptr directly. LSB's png_set_IHDR sets
        // the channels anyways, so just comment it out for LSB usage
        info_ptr->channels = 4;
#endif
        png_set_sig_bytes(png_ptr, 8); // Pretend we already wrote the sig
        png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
                     8, image.hasAlphaChannel()
                     ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
                     0, 0, 0);
        png_write_info(png_ptr, info_ptr);
        if (!image.hasAlphaChannel())
            png_set_filler(png_ptr, 0,
                           QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                           PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
        //if ( QImage::systemByteOrder() == QImage::BigEndian ) {
        //png_set_swap_alpha(png_ptr);
        //}
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
            png_set_bgr(png_ptr);
        }

        int height = image.height();
        png_bytep *row_pointers = new png_bytep[height];
        for (int i = 0; i < height; ++i)
            row_pointers[i] = (png_bytep)image.scanLine(i);
        png_write_image(png_ptr, row_pointers);
        delete [] row_pointers;
        png_write_end(png_ptr, info_ptr);
        end_png();
        begin_png();
    }
示例#5
0
/**
 * \brief encode an image to RGB(A) PNG format
 * \private \memberof mapcache_image_format_png
 * \sa mapcache_image_format::write()
 */
mapcache_buffer* _mapcache_imageio_png_encode(mapcache_context *ctx, mapcache_image *img, mapcache_image_format *format) {
   png_infop info_ptr;
   int color_type;
   size_t row;
   mapcache_buffer *buffer = NULL;
   int compression = ((mapcache_image_format_png*)format)->compression_level;
   png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
   if (!png_ptr) {
      ctx->set_error(ctx, 500, "failed to allocate png_struct structure");
      return NULL;
   }

   info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr)
   {
      png_destroy_write_struct(&png_ptr,
            (png_infopp)NULL);
      ctx->set_error(ctx, 500, "failed to allocate png_info structure");
      return NULL;
   }

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      ctx->set_error(ctx, 500, "failed to setjmp(png_jmpbuf(png_ptr))");
      png_destroy_write_struct(&png_ptr, &info_ptr);
      return NULL;
   }

   buffer = mapcache_buffer_create(5000,ctx->pool);

   png_set_write_fn(png_ptr, buffer, _mapcache_imageio_png_write_func, _mapcache_imageio_png_flush_func);

   if(mapcache_image_has_alpha(img))
      color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   else
      color_type = PNG_COLOR_TYPE_RGB;
      
   png_set_IHDR(png_ptr, info_ptr, img->w, img->h,
         8, color_type, PNG_INTERLACE_NONE,
         PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
   if(compression == MAPCACHE_COMPRESSION_BEST)
      png_set_compression_level (png_ptr, Z_BEST_COMPRESSION);
   else if(compression == MAPCACHE_COMPRESSION_FAST)
      png_set_compression_level (png_ptr, Z_BEST_SPEED);

   png_write_info(png_ptr, info_ptr);
   if(color_type == PNG_COLOR_TYPE_RGB)
       png_set_filler(png_ptr, 255, PNG_FILLER_AFTER);

   png_bytep rowptr = img->data;
   for(row=0;row<img->h;row++) {
      png_write_row(png_ptr,rowptr);
      rowptr += img->stride;
   }
   png_write_end(png_ptr, info_ptr);
   png_destroy_write_struct(&png_ptr, &info_ptr);
   return buffer;
}
示例#6
0
void read_png_file(char *filename) {
  FILE *fp = fopen(filename, "rb");

  png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if(!png) abort();

  png_infop info = png_create_info_struct(png);
  if(!info) abort();

  if(setjmp(png_jmpbuf(png))) abort();

  png_init_io(png, fp);

  png_read_info(png, info);

  width      = png_get_image_width(png, info);
  height     = png_get_image_height(png, info);
  color_type = png_get_color_type(png, info);
  bit_depth  = png_get_bit_depth(png, info);

  // Read any color_type into 8bit depth, RGBA format.
  // See http://www.libpng.org/pub/png/libpng-manual.txt

  if(bit_depth == 16)
    png_set_strip_16(png);

  if(color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png);

  // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
  if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    png_set_expand_gray_1_2_4_to_8(png);

  if(png_get_valid(png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png);

  // These color_type don't have an alpha channel then fill it with 0xff.
  if(color_type == PNG_COLOR_TYPE_RGB ||
     color_type == PNG_COLOR_TYPE_GRAY ||
     color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_filler(png, 0xFF, PNG_FILLER_AFTER);

  if(color_type == PNG_COLOR_TYPE_GRAY ||
     color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    png_set_gray_to_rgb(png);

  png_read_update_info(png, info);

  row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
  int y ;
  for( y = 0; y < height; y++) {
    row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
  }

  png_read_image(png, row_pointers);

  fclose(fp);
}
示例#7
0
文件: png.c 项目: bkeepers/cheribsd
static void nspng_setup_transforms(png_structp png_ptr, png_infop info_ptr)
{
	int bit_depth, color_type;
#if 0
	int intent;
	double gamma;
#endif

	bit_depth = png_get_bit_depth(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);

	/* Set up our transformations */
	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		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);
	}

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

	if (bit_depth == 16) {
		png_set_strip_16(png_ptr);
	}

	if (color_type == PNG_COLOR_TYPE_GRAY ||
	    color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
		png_set_gray_to_rgb(png_ptr);
	}

	if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
		png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
	}

#if 0
	/* gamma correction - we use 2.2 as our screen gamma
	 * this appears to be correct (at least in respect to !Browse)
	 * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case
	 */
	if (png_get_sRGB(png_ptr, info_ptr, &intent)) {
		png_set_gamma(png_ptr, 2.2, 0.45455);
	} else {
		if (png_get_gAMA(png_ptr, info_ptr, &gamma)) {
			png_set_gamma(png_ptr, 2.2, gamma);
		} else {
			png_set_gamma(png_ptr, 2.2, 0.45455);
		}
	}
#endif

	png_read_update_info(png_ptr, info_ptr);
}
示例#8
0
static CogFrame *
cog_frame_new_from_png (void *data, int size)
{
  struct png_data_struct s = { 0 };
  png_structp png_ptr;
  png_infop info_ptr;
  png_bytep *rows;
  CogFrame *frame;
  guchar *frame_data;
  int j;
  int width, height;
  int color_type;

  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  info_ptr = png_create_info_struct (png_ptr);

  s.data = data;
  s.size = size;
  png_set_read_fn (png_ptr, (void *) &s, read_data);

  png_read_info (png_ptr, info_ptr);

  width = png_get_image_width (png_ptr, info_ptr);
  height = png_get_image_height (png_ptr, info_ptr);
  color_type = png_get_color_type (png_ptr, info_ptr);
  GST_DEBUG ("PNG size %dx%d color_type %d", width, height, color_type);

  png_set_strip_16 (png_ptr);
  png_set_packing (png_ptr);
  if (color_type == PNG_COLOR_TYPE_RGB) {
    png_set_filler (png_ptr, 0xff, PNG_FILLER_BEFORE);
  }
  if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
    png_set_swap_alpha (png_ptr);
  }

  frame_data = g_malloc (width * height * 4);
  frame = cog_frame_new_from_data_ARGB (frame_data, width, height);
  frame->regions[0] = frame_data;

  rows = (png_bytep *) g_malloc (sizeof (png_bytep) * height);

  for (j = 0; j < height; j++) {
    rows[j] = COG_FRAME_DATA_GET_LINE (frame->components + 0, j);
  }
  png_read_image (png_ptr, rows);
  g_free (rows);

  png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);

  return frame;
}
示例#9
0
文件: npng.c 项目: Crockadavin/naev
/**
 * @brief Initializes the npng.
 */
static int npng_info( npng_t *npng )
{
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;
   /*double display_exponent, gamma;*/

   /* Read information. */
   png_read_info( npng->png_ptr, npng->info_ptr );

   /* Read header stuff. */
   png_get_IHDR( npng->png_ptr, npng->info_ptr, &width, &height,
         &bit_depth, &color_type, &interlace_type, NULL, NULL );

   /* Set Interlace handling if necessary. */
   if (interlace_type != PNG_INTERLACE_NONE)
      png_set_interlace_handling( npng->png_ptr );

   /* Strip down from 16 bit to 8 bit. */
   png_set_strip_16( npng->png_ptr );

   /* Extract small bits into separate bytes. */
   png_set_packing( npng->png_ptr );

   /* Expand palette to RGB. */
   if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_expand( npng->png_ptr );
   /* Expand low bit grayscale to 8 bit. */
   if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8))
      png_set_expand( npng->png_ptr );
   /* Expand tRNS data to alpha channel. */
   if (png_get_valid( npng->png_ptr, npng->info_ptr, PNG_INFO_tRNS) )
      png_set_expand( npng->png_ptr );

   /* Set grayscale to 8 bits. */
   if ((color_type == PNG_COLOR_TYPE_GRAY) ||
         (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
      png_set_gray_to_rgb( npng->png_ptr );

   /* Set gamma. */
   /*if (png_get_gAMA( npng->png_ptr, info_ptr, &gamma) )
      png_set_gamma( npng->png_ptr, display_exponent, gamma );*/

   /* Fill alpha. */
   png_set_filler( npng->png_ptr, 0xff, PNG_FILLER_AFTER );

   /* Update information. */
   png_read_update_info( npng->png_ptr, npng->info_ptr );

   /* Success. */
   return 0;
}
示例#10
0
/* Since libpng forces us to use longjmp, this function shouldn't create any C++
 * objects, and needs to watch out for memleaks. */
bool SavePNG( FILE *f, char szErrorbuf[1024], const Surface *pSurf )
{
/*	RageSurfaceUtils::ConvertSurface( pImgIn, pImg, pImgIn->w, pImgIn->h, 32,
			Swap32BE( 0xFF000000 ),
			Swap32BE( 0x00FF0000 ),
			Swap32BE( 0x0000FF00 ),
			Swap32BE( 0x000000FF ) );
*/
	error_info error;
	error.szErr = szErrorbuf;

	png_struct *pPng = png_create_write_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
	if( pPng == NULL )
	{
		sprintf( szErrorbuf, "creating png_create_write_struct failed");
		return false;
	}

	png_info *pInfo = png_create_info_struct(pPng);
	if( pInfo == NULL )
	{
		png_destroy_read_struct( &pPng, NULL, NULL );
		sprintf( szErrorbuf, "creating png_create_info_struct failed");
		return false;
	}

	if( setjmp(pPng->jmpbuf) )
	{
		png_destroy_read_struct( &pPng, &pInfo, png_infopp_NULL );
		return false;
	}

	png_set_write_fn( pPng, f, File_png_write, File_png_flush );
	png_set_compression_level( pPng, 1 );

	png_set_IHDR( pPng, pInfo, pSurf->iWidth, pSurf->iHeight, 8, PNG_COLOR_TYPE_RGBA,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );

	png_write_info( pPng, pInfo );
	png_set_filler( pPng, 0, PNG_FILLER_AFTER );

	png_byte *pixels = (png_byte *) pSurf->pRGBA;
	for( int y = 0; y < pSurf->iHeight; y++ )
		png_write_row( pPng, pixels + pSurf->iPitch*y );

	png_write_end( pPng, pInfo );
	png_destroy_write_struct( &pPng, &pInfo );

	return true;
}
示例#11
0
static void
info_callback(png_structp png, png_infop info)
{
	int bit_depth, color_type, interlace, intent;
	double gamma;
	png_uint_32 width, height;
	
	/* Read the PNG details */
	png_get_IHDR(png, info, &width, &height, &bit_depth,
			&color_type, &interlace, 0, 0);
        
        /* Set up our transformations */
	if (color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png);
	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
		png_set_expand_gray_1_2_4_to_8(png);
	if (png_get_valid(png, info, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha(png);
	if (bit_depth == 16)
		png_set_strip_16(png);
	if (color_type == PNG_COLOR_TYPE_GRAY ||
			color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png);
	if (!(color_type & PNG_COLOR_MASK_ALPHA))
		png_set_filler(png, 0xff, PNG_FILLER_AFTER);
	/* gamma correction - we use 2.2 as our screen gamma
	 * this appears to be correct (at least in respect to !Browse)
	 * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case
	 */
	if (png_get_sRGB(png, info, &intent))
	        png_set_gamma(png, 2.2, 0.45455);
	else {
	        if (png_get_gAMA(png, info, &gamma))
	                png_set_gamma(png, 2.2, gamma);
	        else
	                png_set_gamma(png, 2.2, 0.45455);
	}


	png_read_update_info(png, info);

	rowbytes = png_get_rowbytes(png, info);
	interlace = (interlace == PNG_INTERLACE_ADAM7);
	raw_width = width;
	raw_height = height;
        
        rowstride = raw_width * 4;
        bitmap_data = malloc(rowstride * raw_height);
}
示例#12
0
bool SkPngEncoderMgr::writeInfo(const SkImageInfo& srcInfo) {
    if (setjmp(png_jmpbuf(fPngPtr))) {
        return false;
    }

    png_write_info(fPngPtr, fInfoPtr);
    if (kRGBA_F16_SkColorType == srcInfo.colorType() &&
        kOpaque_SkAlphaType == srcInfo.alphaType())
    {
        // For kOpaque, kRGBA_F16, we will keep the row as RGBA and tell libpng
        // to skip the alpha channel.
        png_set_filler(fPngPtr, 0, PNG_FILLER_AFTER);
    }

    return true;
}
示例#13
0
文件: glib2d.c 项目: libcg/PSP_Bot
void _gTexLoadPNG(FILE* fp, gImage* tex)
{
  png_structp png_ptr;
  png_infop info_ptr;
  unsigned int sig_read = 0;
  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type, x, y;
  u32* line;
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  png_set_error_fn(png_ptr,NULL,NULL,NULL);
  info_ptr = png_create_info_struct(png_ptr);
  png_init_io(png_ptr,fp);
  png_set_sig_bytes(png_ptr,sig_read);
  png_read_info(png_ptr,info_ptr);
  png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
                                &interlace_type,NULL,NULL);
  png_set_strip_16(png_ptr);
  png_set_packing(png_ptr);
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png_ptr);
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    png_set_gray_1_2_4_to_8(png_ptr);
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png_ptr);
  png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
  tex->w = width;
  tex->h = height;
  tex->tw = _getNextPower2(width);
  tex->th = _getNextPower2(height);
  tex->ratio = (float)width / height;
  tex->data = memalign(16, tex->tw * tex->th * sizeof(gColor));
  line = malloc(width * 4);
  for (y = 0; y < height; y++) {
    png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
    for (x = 0; x < width; x++) {
      u32 color = line[x];
      tex->data[x + y * tex->tw] =  color;
    }
  }
  free(line);
  png_read_end(png_ptr, info_ptr);
  png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
}
示例#14
0
static void readRgb( PngInfo& info, unsigned width, unsigned height, bool update ){
	//Apply transparency information
	bool alpha = info.isGrayAlpha() || info.isRgbAlpha();
	if( png_get_valid( info.png, info.info, PNG_INFO_tRNS ) ){
		png_set_tRNS_to_alpha( info.png );
		alpha = true;
	}
	
	//Convert Grayscale
	if( info.isGray() || info.isGrayAlpha() )
		png_set_gray_to_rgb( info.png );
	
	//Use the format BGRA
	info.force8bit();
	png_set_filler( info.png, 255, PNG_FILLER_AFTER );
	png_set_bgr( info.png );
	
	//Initialize image
	auto format = alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32;
	info.read( width, height, format, update );
}
示例#15
0
文件: inlinedata.c 项目: new299/wflow
/* This function is called (as set by png_set_progressive_read_fn() above) when enough data has been supplied so all of the header has been read.  */
void info_callback(png_structp png_ptr, png_infop info) {

  file_end=0;
  width = png_get_image_width(png_ptr,info);
  height = png_get_image_height(png_ptr,info);
  pixel_depth = png_get_bit_depth(png_ptr,info);
  
  channels = png_get_channels(png_ptr,info);
  
  color_type = png_get_color_type(png_ptr,info);
  if(color_type == PNG_COLOR_TYPE_GRAY)      {}
  if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA){}
  if(color_type == PNG_COLOR_TYPE_RGB)       {}
  if(color_type == PNG_COLOR_TYPE_RGB_ALPHA) {}
  if(color_type == PNG_COLOR_TYPE_PALETTE )  {

    int r = png_get_PLTE(png_ptr,info,&palette,&num_palette);
    if(r == 0) {
    }
    
    png_uint_16p histogram = NULL;

    png_get_hIST(png_ptr, info, &histogram);
    png_set_expand(png_ptr);
    png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
    png_read_update_info(png_ptr, info);
    pixel_depth = 8;
  }

  int row_bytes = png_get_rowbytes(png_ptr,info);

  row_pointers = malloc(sizeof(png_bytep *) * height);
  for(size_t n=0;n<height;n++) {
    row_pointers[n] = malloc(row_bytes);
  }

  png_start_read_image(png_ptr);
}
示例#16
0
void LoadPNGBuffer(byte * data, byte ** pic, int *width, int *height)
{
	int             bit_depth;
	int             color_type;
	png_uint_32     w;
	png_uint_32     h;
	unsigned int    row;
	size_t          rowbytes;
	png_infop       info;
	png_structp     png;
	png_bytep      *row_pointers;
	byte           *out;
	int             size;
	byte            alphaByte = 255;

	// load png
//  size = ri.FS_ReadFile(name, (void **)&data);

	if(!data)
		return;

	//png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_user_error_fn, png_user_warning_fn);

	if(!png)
	{
		Sys_FPrintf(SYS_WRN, "LoadPNGBuffer: png_create_write_struct() failed\n");
		//free(data);
		return;
	}

	// allocate/initialize the memory for image information.  REQUIRED
	info = png_create_info_struct(png);
	if(!info)
	{
		Sys_FPrintf(SYS_WRN, "LoadPNGBuffer: png_create_info_struct() failed\n");
		//free(data);
		png_destroy_read_struct(&png, (png_infopp) NULL, (png_infopp) NULL);
		return;
	}

	//
	// Set error handling if you are using the setjmp/longjmp method (this is
	// the normal method of doing things with libpng).  REQUIRED unless you
	// set up your own error handlers in the png_create_read_struct() earlier.
	//
	if(setjmp(png_jmpbuf(png)))
	{
		// if we get here, we had a problem reading the file
		Sys_FPrintf(SYS_WRN, "LoadPNGBuffer: first exception handler called\n");
		//free(data);
		png_destroy_read_struct(&png, (png_infopp) & info, (png_infopp) NULL);
		return;
	}

	//png_set_write_fn(png, buffer, png_write_data, png_flush_data);
	png_set_read_fn(png, data, png_read_data);

	png_set_sig_bytes(png, 0);

	// The call to png_read_info() gives us all of the information from the
	// PNG file before the first IDAT (image data chunk).  REQUIRED
	png_read_info(png, info);

	// get picture info
	png_get_IHDR(png, info, (png_uint_32 *) & w, (png_uint_32 *) & h, &bit_depth, &color_type, NULL, NULL, NULL);

	// tell libpng to strip 16 bit/color files down to 8 bits/color
	png_set_strip_16(png);

	// expand paletted images to RGB triplets
	if(color_type & PNG_COLOR_MASK_PALETTE)
		png_set_expand(png);

	// expand gray-scaled images to RGB triplets
	if(!(color_type & PNG_COLOR_MASK_COLOR))
		png_set_gray_to_rgb(png);

	// expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
	//if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
	//  png_set_gray_1_2_4_to_8(png);

	// expand paletted or RGB images with transparency to full alpha channels
	// so the data will be available as RGBA quartets
	if(png_get_valid(png, info, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha(png);

	// if there is no alpha information, fill with alphaByte
	if(!(color_type & PNG_COLOR_MASK_ALPHA))
		png_set_filler(png, alphaByte, PNG_FILLER_AFTER);

	// expand pictures with less than 8bpp to 8bpp
	if(bit_depth < 8)
		png_set_packing(png);

	// update structure with the above settings
	png_read_update_info(png, info);

	// allocate the memory to hold the image
	*width = w;
	*height = h;
	*pic = out = (byte *) safe_malloc(w * h * 4);

	row_pointers = (png_bytep *) safe_malloc(sizeof(png_bytep) * h);

	// set a new exception handler
	if(setjmp(png_jmpbuf(png)))
	{
		Sys_FPrintf(SYS_WRN, "LoadPNGBuffer: second exception handler called\n");
		free(row_pointers);
		//free(data);
		png_destroy_read_struct(&png, (png_infopp) & info, (png_infopp) NULL);
		return;
	}

	rowbytes = png_get_rowbytes(png, info);

	for(row = 0; row < h; row++)
		row_pointers[row] = (png_bytep) (out + (row * 4 * w));

	// read image data
	png_read_image(png, row_pointers);

	// read rest of file, and get additional chunks in info
	png_read_end(png, info);

	// clean up after the read, and free any memory allocated
	png_destroy_read_struct(&png, &info, (png_infopp) NULL);

	free(row_pointers);
	//free(data);
}
示例#17
0
bool MCImageEncodePNG(MCImageBitmap *p_bitmap, IO_handle p_stream, uindex_t &r_bytes_written)
{
	bool t_success = true;

	MCPNGWriteContext t_context;
	t_context.stream = p_stream;
	t_context.byte_count = 0;

	png_structp t_png_ptr = nil;
	png_infop t_info_ptr = nil;
	png_color *t_png_palette = nil;
	png_byte *t_png_transparency = nil;

	png_bytep t_data_ptr = nil;
	uindex_t t_stride = 0;

	MCImageIndexedBitmap *t_indexed = nil;
	if (MCImageConvertBitmapToIndexed(p_bitmap, false, t_indexed))
	{
		t_success = MCImageEncodePNG(t_indexed, p_stream, r_bytes_written);
		MCImageFreeIndexedBitmap(t_indexed);
		return t_success;
	}

	/*init png stuff*/
	if (t_success)
	{
		t_success = nil != (t_png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
			(png_voidp)NULL, (png_error_ptr)NULL,
			(png_error_ptr)NULL));
	}

	if (t_success)
		t_success = nil != (t_info_ptr = png_create_info_struct(t_png_ptr));

	/*in case of png error*/
	if (setjmp(png_jmpbuf(t_png_ptr)))
		t_success = false;

	if (t_success)
		png_set_write_fn(t_png_ptr,(png_voidp)&t_context,fakewrite,fakeflush);

	bool t_fully_opaque = true;
	if (t_success)
	{
		t_fully_opaque = !MCImageBitmapHasTransparency(p_bitmap);

		png_set_IHDR(t_png_ptr, t_info_ptr, p_bitmap->width, p_bitmap->height, 8,
			t_fully_opaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
		png_set_gAMA(t_png_ptr, t_info_ptr, 1/MCgamma);
	}

	if (t_success)
	{
		png_write_info(t_png_ptr, t_info_ptr);

		//32 bit compensate for byte swapped systems
		if (t_fully_opaque)
			png_set_filler(t_png_ptr, 0, MCswapbytes ? PNG_FILLER_AFTER : PNG_FILLER_BEFORE);
		if (MCswapbytes)
			png_set_bgr(t_png_ptr);
		else
			png_set_swap_alpha(t_png_ptr);
	}

	if (t_success)
	{
		t_data_ptr = (png_bytep)p_bitmap->data;
		t_stride = p_bitmap->stride;
	}

	if (t_success)
	{
		for (uindex_t i = 0; i < p_bitmap->height; i++)
		{
			png_write_row(t_png_ptr, t_data_ptr);
			t_data_ptr += t_stride;
		}
	}

	if (t_success)
		png_write_end(t_png_ptr, t_info_ptr);

	if (t_png_ptr != nil)
		png_destroy_write_struct(&t_png_ptr, &t_info_ptr);
	if (t_png_palette != nil)
		MCMemoryDeleteArray(t_png_palette);
	if (t_png_transparency != nil)
		MCMemoryDeallocate(t_png_transparency);

	if (t_success)
		r_bytes_written = t_context.byte_count;

	return t_success;
}
示例#18
0
FloatPixMapRef FPMCreateWithPNGCustom(png_voidp ioPtr, png_rw_ptr readDataFn, FPMGammaFactor desiredGamma, FPMPNGErrorHandler errorHandler)
{
    png_structp			png = NULL;
    png_infop			pngInfo = NULL;
    png_infop			pngEndInfo = NULL;
    FloatPixMapRef		result = NULL;
    png_uint_32			i, width, height, rowBytes;
    int					depth, colorType;
    png_bytepp			rows = NULL;
    void				*data = NULL;

    png = png_create_read_struct(PNG_LIBPNG_VER_STRING, errorHandler, PNGError, PNGWarning);
    if (png == NULL)  goto FAIL;

    pngInfo = png_create_info_struct(png);
    if (pngInfo == NULL)  goto FAIL;

    pngEndInfo = png_create_info_struct(png);
    if (pngEndInfo == NULL)  goto FAIL;

    if (setjmp(png_jmpbuf(png)))
    {
        // libpng will jump here on error.
        goto FAIL;
    }

    png_set_read_fn(png, ioPtr, readDataFn);

    png_read_info(png, pngInfo);
    if (!png_get_IHDR(png, pngInfo, &width, &height, &depth, &colorType, NULL, NULL, NULL))  goto FAIL;

#if __LITTLE_ENDIAN__
    if (depth == 16)  png_set_swap(png);
#endif
    if (depth <= 8 && !(colorType & PNG_COLOR_MASK_ALPHA))
    {
        png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
    }
    png_set_gray_to_rgb(png);
    if (depth < 8)
    {
        png_set_packing(png);
        png_set_expand(png);
    }

    png_read_update_info(png, pngInfo);
    rowBytes = png_get_rowbytes(png, pngInfo);

    rows = malloc(sizeof *rows * height);
    data = malloc(rowBytes * height);
    if (rows == NULL || data == NULL)  goto FAIL;

    // Set up row pointers.
    for (i = 0; i < height; i++)
    {
        rows[i] = (png_bytep)data + i * rowBytes;
    }

    png_read_image(png, rows);
    png_read_end(png, pngEndInfo);

    free(rows);

    result = ConvertPNGData(data, width, height, rowBytes, png_get_bit_depth(png, pngInfo), png_get_color_type(png, pngInfo));

    if (result != NULL)
    {
        double invGamma = 1.0/kFPMGammaSRGB;
        png_get_gAMA(png, pngInfo, &invGamma);
        FPMApplyGamma(result, 1.0/invGamma, desiredGamma, png_get_bit_depth(png, pngInfo) == 16 ? 65536 : 256);
    }

    png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
    free(data);

    return result;

FAIL:
    FPMRelease(&result);
    if (png != NULL)  png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
    free(rows);
    free(data);

    return NULL;
}
示例#19
0
pngquant_error rwpng_read_image24(FILE *infile, png24_image *mainprog_ptr)
{
    png_structp  png_ptr = NULL;
    png_infop    info_ptr = NULL;
    png_uint_32  i;
    png_size_t   rowbytes;
    int          color_type, bit_depth;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
      rwpng_error_handler, NULL);
    if (!png_ptr) {
        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
    }

    /* setjmp() must be called in every function that calls a non-trivial
     * libpng function */

    if (setjmp(mainprog_ptr->jmpbuf)) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return LIBPNG_FATAL_ERROR;   /* fatal libpng error (via longjmp()) */
    }

    struct rwpng_read_data read_data = {infile, 0};
    png_set_read_fn(png_ptr, &read_data, user_read_data);

    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */


    /* alternatively, could make separate calls to png_get_image_width(),
     * etc., but want bit_depth and color_type for later [don't care about
     * compression_type and filter_type => NULLs] */

    png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, &mainprog_ptr->height,
      &bit_depth, &color_type, NULL, NULL, NULL);


    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
     * transparency chunks to full alpha channel; strip 16-bit-per-sample
     * images to 8 bits per sample; and convert grayscale to RGB[A] */

    /* GRR TO DO:  preserve all safe-to-copy ancillary PNG chunks */

    if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
#ifdef PNG_READ_FILLER_SUPPORTED
        /* GRP:  expand palette to RGB, and grayscale or RGB to GA or RGBA */
        if (color_type == PNG_COLOR_TYPE_PALETTE)
            png_set_expand(png_ptr);
        png_set_filler(png_ptr, 65535L, PNG_FILLER_AFTER);
#else
        fprintf(stderr, "pngquant readpng:  image is neither RGBA nor GA\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        mainprog_ptr->retval = 26;
        return mainprog_ptr->retval;
#endif
    }
/*
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
 */
    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);


    /* get and save the gamma info (if any) for writing */

    double gamma;
    mainprog_ptr->gamma = png_get_gAMA(png_ptr, info_ptr, &gamma) ? gamma : 0.45455f;

    png_set_interlace_handling(png_ptr);

    /* all transformations have been registered; now update info_ptr data,
     * get rowbytes and channels, and allocate image memory */

    png_read_update_info(png_ptr, info_ptr);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    if ((mainprog_ptr->rgba_data = malloc(rowbytes*mainprog_ptr->height)) == NULL) {
        fprintf(stderr, "pngquant readpng:  unable to allocate image data\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;
    }
    if ((mainprog_ptr->row_pointers = (png_bytepp)malloc(mainprog_ptr->height*sizeof(png_bytep))) == NULL) {
        fprintf(stderr, "pngquant readpng:  unable to allocate row pointers\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        free(mainprog_ptr->rgba_data);
        mainprog_ptr->rgba_data = NULL;
        return PNG_OUT_OF_MEMORY_ERROR;
    }

    /* set the individual row_pointers to point at the correct offsets */

    for (i = 0;  i < mainprog_ptr->height;  ++i)
        mainprog_ptr->row_pointers[i] = mainprog_ptr->rgba_data + i*rowbytes;


    /* now we can go ahead and just read the whole image */

    png_read_image(png_ptr, (png_bytepp)mainprog_ptr->row_pointers);


    /* and we're done!  (png_read_end() can be omitted if no processing of
     * post-IDAT text/time/etc. is desired) */

    png_read_end(png_ptr, NULL);

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    mainprog_ptr->file_size = read_data.bytes_read;

    return SUCCESS;
}
示例#20
0
文件: pngshim.c 项目: ONLYOFFICE/core
  Load_SBit_Png( FT_GlyphSlot     slot,
                 FT_Int           x_offset,
                 FT_Int           y_offset,
                 FT_Int           pix_bits,
                 TT_SBit_Metrics  metrics,
                 FT_Memory        memory,
                 FT_Byte*         data,
                 FT_UInt          png_len,
                 FT_Bool          populate_map_and_metrics )
  {
    FT_Bitmap    *map   = &slot->bitmap;
    FT_Error      error = FT_Err_Ok;
    FT_StreamRec  stream;

    png_structp  png;
    png_infop    info;
    png_uint_32  imgWidth, imgHeight;

    int         bitdepth, color_type, interlace;
    FT_Int      i;
    png_byte*  *rows = NULL; /* pacify compiler */


    if ( x_offset < 0 ||
         y_offset < 0 )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    if ( !populate_map_and_metrics                   &&
         ( x_offset + metrics->width  > map->width ||
           y_offset + metrics->height > map->rows  ||
           pix_bits != 32                          ||
           map->pixel_mode != FT_PIXEL_MODE_BGRA   ) )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    FT_Stream_OpenMemory( &stream, data, png_len );

    png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
                                  &error,
                                  error_callback,
                                  warning_callback );
    if ( !png )
    {
      error = FT_THROW( Out_Of_Memory );
      goto Exit;
    }

    info = png_create_info_struct( png );
    if ( !info )
    {
      error = FT_THROW( Out_Of_Memory );
      png_destroy_read_struct( &png, NULL, NULL );
      goto Exit;
    }

    if ( ft_setjmp( png_jmpbuf( png ) ) )
    {
      error = FT_THROW( Invalid_File_Format );
      goto DestroyExit;
    }

    png_set_read_fn( png, &stream, read_data_from_FT_Stream );

    png_read_info( png, info );
    png_get_IHDR( png, info,
                  &imgWidth, &imgHeight,
                  &bitdepth, &color_type, &interlace,
                  NULL, NULL );

    if ( error                                        ||
         ( !populate_map_and_metrics                &&
           ( (FT_Int)imgWidth  != metrics->width  ||
             (FT_Int)imgHeight != metrics->height ) ) )
      goto DestroyExit;

    if ( populate_map_and_metrics )
    {
      FT_Long  size;


      metrics->width  = (FT_Int)imgWidth;
      metrics->height = (FT_Int)imgHeight;

      map->width      = metrics->width;
      map->rows       = metrics->height;
      map->pixel_mode = FT_PIXEL_MODE_BGRA;
      map->pitch      = map->width * 4;
      map->num_grays  = 256;

      size = map->rows * map->pitch;

      error = ft_glyphslot_alloc_bitmap( slot, size );
      if ( error )
        goto DestroyExit;
    }

    /* convert palette/gray image to rgb */
    if ( color_type == PNG_COLOR_TYPE_PALETTE )
      png_set_palette_to_rgb( png );

    /* expand gray bit depth if needed */
    if ( color_type == PNG_COLOR_TYPE_GRAY )
    {
#if PNG_LIBPNG_VER >= 10209
      png_set_expand_gray_1_2_4_to_8( png );
#else
      png_set_gray_1_2_4_to_8( png );
#endif
    }

    /* transform transparency to alpha */
    if ( png_get_valid(png, info, PNG_INFO_tRNS ) )
      png_set_tRNS_to_alpha( png );

    if ( bitdepth == 16 )
      png_set_strip_16( png );

    if ( bitdepth < 8 )
      png_set_packing( png );

    /* convert grayscale to RGB */
    if ( color_type == PNG_COLOR_TYPE_GRAY       ||
         color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
      png_set_gray_to_rgb( png );

    if ( interlace != PNG_INTERLACE_NONE )
      png_set_interlace_handling( png );

    png_set_filler( png, 0xFF, PNG_FILLER_AFTER );

    /* recheck header after setting EXPAND options */
    png_read_update_info(png, info );
    png_get_IHDR( png, info,
                  &imgWidth, &imgHeight,
                  &bitdepth, &color_type, &interlace,
                  NULL, NULL );

    if ( bitdepth != 8                              ||
        !( color_type == PNG_COLOR_TYPE_RGB       ||
           color_type == PNG_COLOR_TYPE_RGB_ALPHA ) )
    {
      error = FT_THROW( Invalid_File_Format );
      goto DestroyExit;
    }

    switch ( color_type )
    {
    default:
      /* Shouldn't happen, but fall through. */

    case PNG_COLOR_TYPE_RGB_ALPHA:
      png_set_read_user_transform_fn( png, premultiply_data );
      break;

    case PNG_COLOR_TYPE_RGB:
      /* Humm, this smells.  Carry on though. */
      png_set_read_user_transform_fn( png, convert_bytes_to_data );
      break;
    }

    if ( FT_NEW_ARRAY( rows, imgHeight ) )
    {
      error = FT_THROW( Out_Of_Memory );
      goto DestroyExit;
    }

    for ( i = 0; i < (FT_Int)imgHeight; i++ )
      rows[i] = map->buffer + ( y_offset + i ) * map->pitch + x_offset * 4;

    png_read_image( png, rows );

    FT_FREE( rows );

    png_read_end( png, info );

  DestroyExit:
    png_destroy_read_struct( &png, &info, NULL );
    FT_Stream_Close( &stream );

  Exit:
    return error;
  }
示例#21
0
bool PNGLoader::doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) {
#ifndef USE_INTERNAL_PNG_DECODER
	png_structp png_ptr = NULL;
	png_infop   info_ptr = NULL;

	int         bitDepth;
	int         colorType;
	int         interlaceType;
	int         i;

	// Check for valid PNG signature
	if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) {
		error("png_check_sig failed");
	}

	// Create both PNG structures
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png_ptr) {
		error("Could not create libpng read struct.");
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		error("Could not create libpng info struct.");
	}

	// Use alternative reading function
	const byte **ref = &fileDataPtr;
	png_set_read_fn(png_ptr, (void *)ref, png_user_read_data);

	// Read PNG header
	png_read_info(png_ptr, info_ptr);

	// Read out PNG informations

	png_uint_32 w, h;
	png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL);
	width = w;
	height = h;

	// Calculate pitch of output image
	pitch = GraphicEngine::calcPitch(GraphicEngine::CF_ARGB32, width);

	// Allocate memory for the final image data.
	// To keep memory framentation low this happens before allocating memory for temporary image data.
	uncompressedDataPtr = new byte[pitch * height];
	if (!uncompressedDataPtr) {
		error("Could not allocate memory for output image.");
	}

	// Images of all color formates will be transformed into ARGB images
	if (bitDepth == 16)
		png_set_strip_16(png_ptr);
	if (colorType == PNG_COLOR_TYPE_PALETTE)
		png_set_expand(png_ptr);
	if (bitDepth < 8)
		png_set_expand(png_ptr);
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_expand(png_ptr);
	if (colorType == PNG_COLOR_TYPE_GRAY ||
	        colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png_ptr);

	png_set_bgr(png_ptr);

	if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
		png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);

	// After the transformations have been registered, the image data is read again.
	png_read_update_info(png_ptr, info_ptr);
	png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);
	width = w;
	height = h;

	if (interlaceType == PNG_INTERLACE_NONE) {
		// PNGs without interlacing can simply be read row by row.
		for (i = 0; i < height; i++) {
			png_read_row(png_ptr, uncompressedDataPtr + i * pitch, NULL);
		}
	} else {
		// PNGs with interlacing require us to allocate an auxillary
		// buffer with pointers to all row starts.

		// Allocate row pointer buffer
		png_bytep *pRowPtr = new png_bytep[height];
		if (!pRowPtr) {
			error("Could not allocate memory for row pointers.");
		}

		// Initialize row pointers
		for (i = 0; i < height; i++)
			pRowPtr[i] = uncompressedDataPtr + i * pitch;

		// Read image data
		png_read_image(png_ptr, pRowPtr);

		// Free row pointer buffer
		delete[] pRowPtr;
	}

	// Read additional data at the end.
	png_read_end(png_ptr, NULL);

	// Destroy libpng structures
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
#else
	Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO);
	Graphics::PNG *png = new Graphics::PNG();
	if (!png->read(fileStr))	// the fileStr pointer, and thus pFileData will be deleted after this is done
		error("Error while reading PNG image");

	Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
	Graphics::Surface *pngSurface = png->getSurface(format);

	width = pngSurface->w;
	height = pngSurface->h;
	uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h];
	memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h);
	pngSurface->free();

	delete pngSurface;
	delete png;

#endif
	// Signal success
	return true;
}
示例#22
0
static
void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0)
{
    if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
        double file_gamma;
        png_get_gAMA(png_ptr, info_ptr, &file_gamma);
        png_set_gamma(png_ptr, screen_gamma, file_gamma);
    }

    png_uint_32 width;
    png_uint_32 height;
    int bit_depth;
    int color_type;
    png_bytep trans_alpha = 0;
    png_color_16p trans_color_p = 0;
    int num_trans;
    png_colorp palette = 0;
    int num_palette;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
    png_set_interlace_handling(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY) {
        // Black & White or 8-bit grayscale
        if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
            png_set_invert_mono(png_ptr);
            png_read_update_info(png_ptr, info_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
                image = QImage(width, height, QImage::Format_Mono);
                if (image.isNull())
                    return;
            }
            image.setColorCount(2);
            image.setColor(1, qRgb(0,0,0));
            image.setColor(0, qRgb(255,255,255));
        } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            png_set_expand(png_ptr);
            png_set_strip_16(png_ptr);
            png_set_gray_to_rgb(png_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) {
                image = QImage(width, height, QImage::Format_ARGB32);
                if (image.isNull())
                    return;
            }
            if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
                png_set_swap_alpha(png_ptr);

            png_read_update_info(png_ptr, info_ptr);
        } else {
            if (bit_depth == 16)
                png_set_strip_16(png_ptr);
            else if (bit_depth < 8)
                png_set_packing(png_ptr);
            int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
            png_read_update_info(png_ptr, info_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) {
                image = QImage(width, height, QImage::Format_Indexed8);
                if (image.isNull())
                    return;
            }
            image.setColorCount(ncols);
            for (int i=0; i<ncols; i++) {
                int c = i*255/(ncols-1);
                image.setColor(i, qRgba(c,c,c,0xff));
            }
            if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
                const int g = trans_color_p->gray;
                if (g < ncols) {
                    image.setColor(g, 0);
                }
            }
        }
    } else if (color_type == PNG_COLOR_TYPE_PALETTE
               && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
               && num_palette <= 256)
    {
        // 1-bit and 8-bit color
        if (bit_depth != 1)
            png_set_packing(png_ptr);
        png_read_update_info(png_ptr, info_ptr);
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
        QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
        if (image.size() != QSize(width, height) || image.format() != format) {
            image = QImage(width, height, format);
            if (image.isNull())
                return;
        }
        png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
        image.setColorCount(num_palette);
        int i = 0;
        if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) {
            while (i < num_trans) {
                image.setColor(i, qRgba(
                    palette[i].red,
                    palette[i].green,
                    palette[i].blue,
                    trans_alpha[i]
                   )
               );
                i++;
            }
        }
        while (i < num_palette) {
            image.setColor(i, qRgba(
                palette[i].red,
                palette[i].green,
                palette[i].blue,
                0xff
               )
           );
            i++;
        }
    } else {
        // 32-bit
        if (bit_depth == 16)
            png_set_strip_16(png_ptr);

        png_set_expand(png_ptr);

        if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
            png_set_gray_to_rgb(png_ptr);

        QImage::Format format = QImage::Format_ARGB32;
        // Only add filler if no alpha, or we can get 5 channel data.
        if (!(color_type & PNG_COLOR_MASK_ALPHA)
            && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                           PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
            // We want 4 bytes, but it isn't an alpha channel
            format = QImage::Format_RGB32;
        }
        if (image.size() != QSize(width, height) || image.format() != format) {
            image = QImage(width, height, format);
            if (image.isNull())
                return;
        }

        if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
            png_set_swap_alpha(png_ptr);

        png_read_update_info(png_ptr, info_ptr);
    }

    // Qt==ARGB==Big(ARGB)==Little(BGRA)
    if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
        png_set_bgr(png_ptr);
    }
}
示例#23
0
文件: pngdec.c 项目: DCurrent/openbor
s_screen *pngToScreen(const void *data)
{
    png_structp png_ptr;
    png_infop info_ptr;
    unsigned int sig_read = 0;
    png_uint_32 width, height;
    int bit_depth, color_type, interlace_type, y;
    u32 *line;
    s_screen *image;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(png_ptr == NULL)
    {
        goto error;
    }
    png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, png_warning_fn);
    info_ptr = png_create_info_struct(png_ptr);
    if(info_ptr == NULL)
    {
        goto error2;
    }
    if(setjmp(png_jmpbuf(png_ptr)))
    {
        goto error2;
    }

    png_set_read_fn(png_ptr, &data, png_read_fn);
    png_set_sig_bytes(png_ptr, sig_read);
    png_read_info(png_ptr, info_ptr);
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);

    png_set_strip_16(png_ptr);
    png_set_packing(png_ptr);
    if(color_type == PNG_COLOR_TYPE_PALETTE)
    {
        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);
    }
    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(png_ptr);
    }
#if WII
    png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
#else
    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
#endif

    image = allocscreen(width, height, PIXEL_32);
    if(image == NULL)
    {
        goto error2;
    }

    line = (u32 *)image->data;
    for(y = 0; y < height; y++)
    {
        png_read_row(png_ptr, (u8 *) line, NULL);
        line += width;
    }
    png_read_end(png_ptr, info_ptr);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return image;

error2:
    png_destroy_read_struct(&png_ptr, NULL, NULL);
error:
    return NULL;
}
void LinuxAppPlatform::loadPNG(ImageData& imgData, const std::string& path, bool b) {
    std::cout << "loadPNG: " << path << "(from assets: " << b << ")" << "\n";

    FILE* file = fopen(getImagePath(path, b).c_str(), "rb");
    if (file == NULL) {
        std::cout << "failed to open file\n";
        return;
    }

    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png) {
        std::cout << "png_create_read_struct failed\n";
        abort();
        return;
    }

    png_infop info = png_create_info_struct(png);
    if (!info) {
        std::cout << "png_create_info_struct failed\n";
        abort();
        return;
    }

    unsigned char header[8];
    if(fread(header, 8, 1, file) != 1) {
        std::cout << "failed to read png header\n";
        return;
    }

    if(png_sig_cmp(header, 0, 8)) {
        std::cout << "header is invalid\n";
        return;
    }

    if (setjmp(png_jmpbuf(png))) {
        std::cout << "failed to load png\n";
        abort();
        return;
    }

    png_init_io(png, file);
    png_set_sig_bytes(png, 8);

    png_read_info(png, info);

    imgData.w = (int) png_get_image_width(png, info);
    imgData.h = (int) png_get_image_height(png, info);
    imgData.format = TextureFormat::U8888;
    imgData.mipLevel = 0;

    png_byte bitDepth = png_get_bit_depth(png, info);
    png_byte colorType = png_get_color_type(png, info);
    switch(colorType){
        case PNG_COLOR_TYPE_PALETTE:
            png_set_palette_to_rgb(png);
            break;
        case PNG_COLOR_TYPE_RGB:
            if(png_get_valid(png, info, PNG_INFO_tRNS)) {
                png_set_tRNS_to_alpha(png);
            } else {
                png_set_filler(png, 0xff, PNG_FILLER_AFTER);
            }
            break;

        case PNG_COLOR_TYPE_RGB_ALPHA:
            break;
        case PNG_COLOR_TYPE_GRAY:
            if(bitDepth < 8) {
                png_set_expand_gray_1_2_4_to_8(png);
            }

        default:
            std::cout << "png: unsupported color type\n";
    }
    if(bitDepth == 16) {
        png_set_strip_16(png);
    }
    png_read_update_info(png, info);

    png_size_t rowBytes = png_get_rowbytes(png, info);

    std::vector<char> data(rowBytes * imgData.h);

    png_byte* rows[imgData.h];
    for (int i = 0; i < imgData.h; i++) {
        rows[i] = (png_byte*) &data[i * rowBytes];
    }
    png_read_image(png, rows);

    fclose(file);

    {
        std::string empty;
        ((void **) &imgData.data)[0] = ((void **) &empty)[0];
        imgData.data = " ";
    }
    imgData.data = std::string(&data[0], rowBytes * imgData.h);
}
示例#25
0
文件: png.cpp 项目: AReim1982/scummvm
bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
#ifdef USE_PNG
	destroy();

	// First, check the PNG signature (if not set to skip it)
	if (!_skipSignature) {
		if (stream.readUint32BE() != MKTAG(0x89, 'P', 'N', 'G')) {
			return false;
		}
		if (stream.readUint32BE() != MKTAG(0x0d, 0x0a, 0x1a, 0x0a)) {
			return false;
		}
	}

	// The following is based on the guide provided in:
	//http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3
	//http://www.libpng.org/pub/png/libpng-1.4.0-manual.pdf
	// along with the png-loading code used in the sword25-engine.
	png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!pngPtr) {
		return false;
	}
	png_infop infoPtr = png_create_info_struct(pngPtr);
	if (!infoPtr) {
		png_destroy_read_struct(&pngPtr, NULL, NULL);
		return false;
	}

	png_set_error_fn(pngPtr, NULL, pngError, pngWarning);
	// TODO: The manual says errors should be handled via setjmp

	png_set_read_fn(pngPtr, &stream, pngReadFromStream);
	png_set_crc_action(pngPtr, PNG_CRC_DEFAULT, PNG_CRC_WARN_USE);
	// We already verified the PNG-header
	png_set_sig_bytes(pngPtr, 8);

	// Read PNG header
	png_read_info(pngPtr, infoPtr);

	// No handling for unknown chunks yet.
	int bitDepth, colorType, width, height, interlaceType;
	png_uint_32 w, h;
	png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL);
	width = w;
	height = h;

	// Allocate memory for the final image data.
	// To keep memory framentation low this happens before allocating memory for temporary image data.
	_outputSurface = new Graphics::Surface();

	// Images of all color formats except PNG_COLOR_TYPE_PALETTE
	// will be transformed into ARGB images
	if (colorType == PNG_COLOR_TYPE_PALETTE && !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
		int numPalette = 0;
		png_colorp palette = NULL;
		uint32 success = png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette);
		if (success != PNG_INFO_PLTE) {
			png_destroy_read_struct(&pngPtr, &infoPtr, NULL);
			return false;
		}
		_paletteColorCount = numPalette;
		_palette = new byte[_paletteColorCount * 3];
		for (int i = 0; i < _paletteColorCount; i++) {
			_palette[(i * 3)] = palette[i].red;
			_palette[(i * 3) + 1] = palette[i].green;
			_palette[(i * 3) + 2] = palette[i].blue;

		}
		_outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		png_set_packing(pngPtr);
	} else {
		bool isAlpha = (colorType & PNG_COLOR_MASK_ALPHA);
		if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
			isAlpha = true;
			png_set_expand(pngPtr);
		}
		_outputSurface->create(width, height, Graphics::PixelFormat(4,
		                       8, 8, 8, isAlpha ? 8 : 0, 24, 16, 8, 0));
		if (!_outputSurface->getPixels()) {
			error("Could not allocate memory for output image.");
		}
		if (bitDepth == 16)
			png_set_strip_16(pngPtr);
		if (bitDepth < 8)
			png_set_expand(pngPtr);
		if (colorType == PNG_COLOR_TYPE_GRAY ||
			colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
			png_set_gray_to_rgb(pngPtr);

		// PNGs are Big-Endian:
#ifdef SCUMM_LITTLE_ENDIAN
		png_set_bgr(pngPtr);
		png_set_swap_alpha(pngPtr);
		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			png_set_filler(pngPtr, 0xff, PNG_FILLER_BEFORE);
#else
		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
			png_set_filler(pngPtr, 0xff, PNG_FILLER_AFTER);
#endif

	}

	// After the transformations have been registered, the image data is read again.
	png_set_interlace_handling(pngPtr);
	png_read_update_info(pngPtr, infoPtr);
	png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);
	width = w;
	height = h;

	if (interlaceType == PNG_INTERLACE_NONE) {
		// PNGs without interlacing can simply be read row by row.
		for (int i = 0; i < height; i++) {
			png_read_row(pngPtr, (png_bytep)_outputSurface->getBasePtr(0, i), NULL);
		}
	} else {
		// PNGs with interlacing require us to allocate an auxillary
		// buffer with pointers to all row starts.

		// Allocate row pointer buffer
		png_bytep *rowPtr = new png_bytep[height];
		if (!rowPtr) {
			error("Could not allocate memory for row pointers.");
		}

		// Initialize row pointers
		for (int i = 0; i < height; i++)
			rowPtr[i] = (png_bytep)_outputSurface->getBasePtr(0, i);

		// Read image data
		png_read_image(pngPtr, rowPtr);

		// Free row pointer buffer
		delete[] rowPtr;
	}

	// Read additional data at the end.
	png_read_end(pngPtr, NULL);

	// Destroy libpng structures
	png_destroy_read_struct(&pngPtr, &infoPtr, NULL);

	return true;
#else
	return false;
#endif
}
示例#26
0
static void
init_output(void)
{
  int bit_depth ;
  int color_type ;
  int invert_mono = 0 ;
  png_colorp pngpalette = NULL ;
  png_bytep ptrans = NULL ;
  
  outfile = openout(flatspec.output_filename);
  libpng = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                   png_voidp_NULL,
                                   my_error_callback,
                                   png_error_ptr_NULL);
  if( !libpng )
    FatalUnexpected(_("Couldn't initialize libpng library"));
  
  libpng2 = png_create_info_struct(libpng);
  if( !libpng2 )
    FatalUnexpected("Couldn't create PNG info structure");

  png_init_io(libpng,outfile);
  
  bit_depth = 8;
  switch( flatspec.out_color_mode ) {
  case COLOR_GRAY:
    if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL ||
        flatspec.default_pixel == FORCE_ALPHA_CHANNEL )
      color_type = PNG_COLOR_TYPE_GRAY_ALPHA ;
    else
      color_type = PNG_COLOR_TYPE_GRAY ;
    break ;
  case COLOR_RGB:
    if( flatspec.default_pixel == PERHAPS_ALPHA_CHANNEL ||
        flatspec.default_pixel == FORCE_ALPHA_CHANNEL )
      color_type = PNG_COLOR_TYPE_RGB_ALPHA ;
    else
      color_type = PNG_COLOR_TYPE_RGB ;
    break ;
  case COLOR_INDEXED:
    if( paletteSize == 2 &&
        palette[0] == NEWALPHA(0,255) &&
        palette[1] == NEWALPHA(-1,255) ) {
      color_type = PNG_COLOR_TYPE_GRAY ;
      bit_depth = 1 ;
    } else if( paletteSize == 2 &&
               palette[0] == NEWALPHA(-1,255) &&
               palette[1] == NEWALPHA(0,255) ) {
      color_type = PNG_COLOR_TYPE_GRAY ;
      bit_depth = 1 ;
      invert_mono = 1 ;
    } else {
      unsigned i ;
      int need_trans = flatspec.default_pixel == FORCE_ALPHA_CHANNEL ;
      color_type = PNG_COLOR_TYPE_PALETTE ;
      pngpalette = xcfmalloc(paletteSize*sizeof(png_color)) ;
      ptrans = xcfmalloc(paletteSize);
      for(i = 0; i<paletteSize; i++ ) {
        pngpalette[i].red = 255 & (palette[i] >> RED_SHIFT);
        pngpalette[i].green = 255 & (palette[i] >> GREEN_SHIFT);
        pngpalette[i].blue = 255 & (palette[i] >> BLUE_SHIFT);
        if( (ptrans[i] = ALPHA(palette[i])) != 255 )
          need_trans = 1 ;
      }
      if( !need_trans ) {
        xcffree(ptrans);
        ptrans = NULL ;
      }
      if( paletteSize <= 2 )
        bit_depth = 1 ;
      else if( paletteSize <= 4 )
        bit_depth = 2 ;
      else if( paletteSize <= 16 )
        bit_depth = 4 ;
      else
        bit_depth = 8;
    }
    break ;
  default:
    FatalUnexpected("This can't happen (unknown out_color_mode)");
  }

  if( verboseFlag ) {
    fprintf(stderr,"Writing PNG: %s%s%s%s, %d bits",
            color_type & PNG_COLOR_MASK_COLOR ? _("color") : _("grayscale"),
            color_type & PNG_COLOR_MASK_PALETTE ? _("+palette") : "",
            color_type & PNG_COLOR_MASK_ALPHA ? _("+alpha") : "",
            ptrans || NULLALPHA(flatspec.default_pixel)
            ? _("+transparency") : "",
            bit_depth);
    if( pngpalette )
      fprintf(stderr,_(" (%d colors)"),paletteSize);
    fprintf(stderr,"\n");
  }
  
  png_set_IHDR(libpng,libpng2,flatspec.dim.width,flatspec.dim.height,
               bit_depth, color_type,
               PNG_INTERLACE_NONE,
               PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);

  if( invert_mono )
    png_set_invert_mono(libpng);
  
  if( pngpalette )
    png_set_PLTE(libpng,libpng2,pngpalette,paletteSize);
  if( ptrans )
    png_set_tRNS(libpng,libpng2,ptrans,paletteSize,NULL);
  else if ( !pngpalette &&
            NULLALPHA(flatspec.default_pixel) ) {
    static png_color_16 trans ;
    trans.gray =
      trans.red = 255 & (flatspec.default_pixel >> RED_SHIFT) ;
    trans.green = 255 & (flatspec.default_pixel >> GREEN_SHIFT) ;
    trans.blue = 255 & (flatspec.default_pixel >> BLUE_SHIFT) ;
    png_set_tRNS(libpng,libpng2,NULL,0,&trans);
  }

  /* png_set_text here */

  png_write_info(libpng,libpng2);

  if( bit_depth < 8 )
    png_set_packing(libpng);

  switch( color_type ) {
  case PNG_COLOR_TYPE_RGB:
  case PNG_COLOR_TYPE_RGBA:
#if (BLUE_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN)
    png_set_bgr(libpng);
#endif
    if( color_type == PNG_COLOR_TYPE_RGB )
#if (ALPHA_SHIFT < RED_SHIFT) == !defined(WORDS_BIGENDIAN)
      png_set_filler(libpng,0,PNG_FILLER_BEFORE);
    else
      png_set_swap_alpha(libpng);
#else
    png_set_filler(libpng,0,PNG_FILLER_AFTER);
#endif
    break ;
  case PNG_COLOR_TYPE_GRAY:
    png_set_filler(libpng,0,PNG_FILLER_AFTER);
    break ;
  case PNG_COLOR_TYPE_GRAY_ALPHA:
  case PNG_COLOR_TYPE_PALETTE:
    break ;
  default:
    FatalUnexpected("This can't happen (unexpected png color_type)");
  }
}
示例#27
0
PNGImage LoadImagePNG(const char *path)
{
	PNGImage loadedImage;
	loadedImage.loadedSuccessfully = GL_FALSE;
	
	FILE *PNG_file = fopen(path, "rb");
    if (PNG_file == NULL)
    {
        printf("Can't open PNG file %s\n", path);
        return loadedImage;
    }
    
    GLubyte PNG_header[PNG_HEADER_SIZE];
    
    fread(PNG_header, 1, PNG_HEADER_SIZE, PNG_file);
    if (png_sig_cmp(PNG_header, 0, PNG_HEADER_SIZE) != 0)
    {
        printf("%s is not a PNG file\n", path);
        return loadedImage;
    }
    
    png_structp PNG_reader
	= png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (PNG_reader == NULL)
    {
        printf("Can't start reading PNG file %s\n", path);
        fclose(PNG_file);
        return loadedImage;
    }
	
    png_infop PNG_info = png_create_info_struct(PNG_reader);
    if (PNG_info == NULL)
    {
        printf("Can't get info for PNG file %s\n", path);
		
        png_destroy_read_struct(&PNG_reader, NULL, NULL);
        fclose(PNG_file);
        return loadedImage;
    }
	
    png_infop PNG_end_info = png_create_info_struct(PNG_reader);
    if (PNG_end_info == NULL)
    {
        printf("Can't get end info for PNG file %s\n", path);
		
        png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
        fclose(PNG_file);
        return loadedImage;
    }
    
    if (setjmp(png_jmpbuf(PNG_reader)))
    {
        printf("Can't load PNG file %s\n", path);
		
        png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
        fclose(PNG_file);
        return loadedImage;
    }
    
    png_init_io(PNG_reader, PNG_file);
    png_set_sig_bytes(PNG_reader, PNG_HEADER_SIZE);
    
    png_read_info(PNG_reader, PNG_info);
	
	// we have to do a custom transformation to premultiply the alpha of the image
    png_set_read_user_transform_fn(PNG_reader, png_read_premultiply_alpha);
    
	png_uint_32 width, height;
    int bit_depth, color_type;
    
	png_get_IHDR(PNG_reader, PNG_info, &width, &height, &bit_depth, &color_type,NULL, NULL, NULL);
	
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
        png_set_palette_to_rgb(PNG_reader);
    }
	
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) 
    {
        png_set_expand_gray_1_2_4_to_8(PNG_reader);
    }
    
    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    {
        png_set_gray_to_rgb(PNG_reader);
    }
	
    if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
    {
        png_set_tRNS_to_alpha(PNG_reader);
    }
    else
    {
        png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
    }
    

    if (bit_depth == 16)
    {
        png_set_strip_16(PNG_reader);
    }
	
    png_read_update_info(PNG_reader, PNG_info);
    
	png_uint_32 widthPow2, heightPow2;
	widthPow2 = pow2(width);
	heightPow2 = pow2(height);
	
    png_byte* PNG_image_buffer = (png_byte*)malloc(4 * widthPow2 * heightPow2);
	memset(PNG_image_buffer,0,4*widthPow2*heightPow2); // clear image buffer
    png_byte** PNG_rows = (png_byte**)malloc(height * sizeof(png_byte*));


	png_uint_32 rowBytes = widthPow2*4;

	// load the image from the bottom up
	/*
	 image texture in mem looks like:
	 --------
	 |       |
	 |xxxx	 |
	 |xxxx	 |
	 --------
	 where 'x's represent actual image data and the lines are the image buffer.
	 so the image is aligned at the (0,0) texel coordinate of the image buffer.
	 */
	unsigned int row;
    for (row = 0; row < height; ++row)
    {
        PNG_rows[height-1-row] = PNG_image_buffer + (row * rowBytes);
    }
    png_read_image(PNG_reader, PNG_rows);
	
    free(PNG_rows);
   
    png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
    fclose(PNG_file);
    
	
	GLuint textureID = 0;
	glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	
	glTexImage2D(
				 GL_TEXTURE_2D,
				 0,
				 GL_RGBA,
				 widthPow2,
				 heightPow2,
				 0,
				 GL_RGBA,
				 GL_UNSIGNED_BYTE,
				 PNG_image_buffer);
    
     free(PNG_image_buffer);
	
	loadedImage.width = width;
	loadedImage.height = height;
	loadedImage.widthPow2 = widthPow2;
	loadedImage.heightPow2 = heightPow2;
	loadedImage.textureId = textureID;
	loadedImage.loadedSuccessfully = GL_TRUE;
	
    return loadedImage;
}
示例#28
0
bool CGLImageData::LoadPNG(const char * filename)
{
	FILE *png_file = fopen(filename, "rb");
	if (png_file == NULL)
	{
		sLog(DEFAULT_LOG_NAME, LOG_WARNING_EV, 
			"Can't Load PNG file: \"%s\" can't open or doesn't exist", filename);
		return false;
	}

	BYTE header[PNG_SIG_BYTES];

	fread(header, 1, PNG_SIG_BYTES, png_file);
	if (png_sig_cmp(header, 0, PNG_SIG_BYTES))
	{
		sLog(DEFAULT_LOG_NAME, LOG_WARNING_EV, 
			"Can't load PNG file: \"%s\" is not a PNG file.", filename);
		return false;
	}

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	png_infop info_ptr = png_create_info_struct(png_ptr);
	png_infop end_info = png_create_info_struct(png_ptr);

	if(setjmp(png_jmpbuf(png_ptr)))
	{
		sLog(DEFAULT_LOG_NAME, LOG_WARNING_EV, 
			"Can't load PNG file: \"%s\". Some error occured.", filename);
		return false;
	}
	png_init_io(png_ptr, png_file);
	png_set_sig_bytes(png_ptr, PNG_SIG_BYTES);
	png_read_info(png_ptr, info_ptr);

	width = png_get_image_width(png_ptr, info_ptr);
	height = png_get_image_height(png_ptr, info_ptr);

	png_uint_32 bit_depth, color_type;
	bit_depth = png_get_bit_depth(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);

	if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
		png_set_gray_1_2_4_to_8(png_ptr);

	if (bit_depth == 16)
		png_set_strip_16(png_ptr);

	if(color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(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);
	else
		png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);

	png_read_update_info(png_ptr, info_ptr);

	png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
	png_uint_32 numbytes = rowbytes*(height);
	png_byte* pixels = (png_byte *)malloc(numbytes);
	png_byte** row_ptrs = (png_byte **)malloc((height) * sizeof(png_byte*));

	
	for (UINT i=0; i<(height); i++)
		row_ptrs[i] = pixels + ((height) - 1 - i)*rowbytes;

	png_read_image(png_ptr, row_ptrs);

	free(row_ptrs);
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(png_file);

	data = pixels;


	sLog(DEFAULT_LOG_NAME, LOG_INFO_EV, "PNG image \"%s\" loaded", filename); 
	return true;
}
示例#29
0
bool
ply_image_load (ply_image_t *image)
{
  png_struct *png;
  png_info *info;
  png_uint_32 width, height, row;
  int bits_per_pixel, color_type, interlace_method;
  png_byte **rows;
  uint32_t *bytes;
  FILE *fp;
  
  assert (image != NULL);
  
  fp = fopen (image->filename, "r");
  if (fp == NULL)
    return false;
  
  png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  assert (png != NULL);

  info = png_create_info_struct (png);
  assert (info != NULL);

  png_init_io (png, fp);

  if (setjmp (png_jmpbuf (png)) != 0)
    {
      fclose (fp);
      return false;
    }

  png_read_info (png, info);
  png_get_IHDR (png, info,
                &width, &height, &bits_per_pixel,
                &color_type, &interlace_method, NULL, NULL);

  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb (png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
    png_set_expand_gray_1_2_4_to_8 (png);

  if (png_get_valid (png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha (png);

  if (bits_per_pixel == 16)
    png_set_strip_16 (png);

  if (bits_per_pixel < 8)
    png_set_packing (png);

  if ((color_type == PNG_COLOR_TYPE_GRAY)
      || (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
    png_set_gray_to_rgb (png);

  if (interlace_method != PNG_INTERLACE_NONE)
    png_set_interlace_handling (png);

  png_set_filler (png, 0xff, PNG_FILLER_AFTER);

  png_set_read_user_transform_fn (png, transform_to_argb32);

  png_read_update_info (png, info);

  rows = malloc (height * sizeof (png_byte *));
  image->buffer = ply_pixel_buffer_new (width, height);
  
  bytes = ply_pixel_buffer_get_argb32_data (image->buffer);

  for (row = 0; row < height; row++)
    rows[row] = (png_byte*) &bytes[row * width];

  png_read_image (png, rows);

  free (rows);
  png_read_end (png, info);
  fclose (fp);
  png_destroy_read_struct (&png, &info, NULL);

  return true;
}
示例#30
0
unsigned char* load_png_data(char *filename, int *w, int *h) {
    FILE *fp = fopen(filename, "rb");
    if(!fp) {
        return NULL;
    }
    png_byte header[8];
    fread(header, 1, 8, fp);
    if(png_sig_cmp(header, 0, 8)) {
        return NULL;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if(!png_ptr) {
        return NULL;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        fclose(fp);
        return NULL;
    }

    png_infop end_ptr = png_create_info_struct(png_ptr);
    if(!end_ptr) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(fp);
        return NULL;
    }

    if(setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);
        fclose(fp);
        return NULL;
    }

    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, 8);

    png_read_info(png_ptr, info_ptr);

    int bit_depth = png_get_bit_depth(png_ptr, info_ptr);

    switch(png_get_color_type(png_ptr, info_ptr)) {
    case PNG_COLOR_TYPE_PALETTE:
        png_set_palette_to_rgb(png_ptr);
        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
        break;
    case PNG_COLOR_TYPE_GRAY:
        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    case PNG_COLOR_TYPE_GRAY_ALPHA:
        if(bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
        if(bit_depth==16) png_set_strip_16(png_ptr);
        png_set_gray_to_rgb(png_ptr);
        break;
    case PNG_COLOR_TYPE_RGB:
        if(bit_depth <  8 ) png_set_packing(png_ptr);
        if(bit_depth == 16) png_set_strip_16(png_ptr);
        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
        break;
    default:
        break;
    }

    png_read_update_info(png_ptr, info_ptr);

    *w = png_get_image_width(png_ptr, info_ptr);
    *h = png_get_image_height(png_ptr, info_ptr);
    int rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);

    png_bytep data = malloc((*h)*rowbytes*sizeof(*data));

    png_bytep row_pointers[*h];

    int i;
    for(i=0; i<(*h); ++i) {
        row_pointers[i] = &data[i*rowbytes];
    }

    png_read_image(png_ptr, row_pointers);

    png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);

    fclose(fp);

    return data;
}